AsyncTask doInBackground(); executing multiple methods one by one - android

I'm having trouble with AsyncTask running multiple methods in doInBackground. this is my AsyncTask code:
public class FETCHDATA extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
pdialog = new ProgressDialog(getContext());
pdialog.setTitle("Please Wait");
pdialog.setMessage("Fetching data...");
pdialog.show();
}
#Override
protected Void doInBackground(Void... voids) {
try{
method1();
method2();
method3();
method4();
method5();
method6();
method7();
}catch (Throwable e){
e.printStackTrace();
}
}
#Override
protected void onPostExecute(Void aVoid) {
if (pdialog.isShowing()){
pdialog.dismiss();
}
}
Instead running and waiting the first method is done, the doInBackground proceeds to the next method. and the ProgressDialog dismiss by one second.
Note
Every Method will get data from our API and save it on my SQLiteDatabase .
QUESTION
How can i execute my methods when the first method has finished getting and saving data before moving to the second methods.

Maybe you have to create multiples AsyncTask and whenever the first method finish, communicate it with returning a boolean instead of void instance here ---> extends AsyncTask.

This is weird.
I assume that your methodX() are asynchronous call?
In that case, you can use Thread.join() or CountDownLatch.

You are violating usage of async task. Async task is designed for doing short async operations and update the UI easily before, during and after, It is not for doing 7 network & Sqlite operations at once.
You can read more here, : https://developer.android.com/reference/android/os/AsyncTask
So you need to implement some kind of job for yourself to execute these operations at once or use some popular libraries like Retrofit.
If you insist to use async task, since an async task need to be executed from UI thread, you need to create new async task an execute it from onPostExecute every time when it is done and you of course need to pass a param(a counter or something) to doInBackground to know which method should be called.

You can put a counter with a switch case statment in the doInBackground in wich you choose the methode to execute and then in the onPostExecute call new FETCHDATA().execute() recursively
EDIT : working code ( i forgot break; after case;)
int counter = 1; // global
class Fetchdata extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
}
#Override
protected Void doInBackground(Void... voids) {
try {
switch (counter) {
case 1:
method1();
break;
case 2:
method2();
break;
case 3:
method3();
break;
case 4:
method4();
break;
case 5:
method5();
break;
default:
cancel(true);
counter = 1;
break;
}
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
counter+=1;
Log.d(TAG, "onPostExecute: "+counter);
// cancel(true);
new Fetchdata().execute();
}
}
void method1(){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "methode1: coucou");
}
void method2(){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "methode2: ");
}
void method3(){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "methode3: ");
}
void method4(){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "methode4: ");
}
void method5(){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "methode5: ");
}

I think the problem is that your all methods or some methods already runs on a separate thread . So whenever you call a method which already runs on separate thread doInBackground() i.e current thread will not wait for it and continue the execution.
Apart from that The way you put try-catch is not a proper way to do it . Also if you want to call several threads one after another you should go with ThreadPoolExecuter.
If you are not using a Network library To make API calls you can use RetroFit.

Related

AsyncTask onPostExecute not reached

I'm trying to execute this AsyncTask to connect to the server but it is stuck and doesn't reach onPostExecute().
class UnoConnection extends AsyncTask<Void, Void, Boolean> {
#Override
protected void onPreExecute() {
IP = enterIP.getText().toString();
Response = "";
Log.i("Network", "Available");
}
#Override
protected Boolean doInBackground(Void... params) {
try {
InetAddress serverAddress = InetAddress.getByName(IP);
Log.i("Socket", "Trying to create...");
socket = new Socket();
socket.connect(new InetSocketAddress(serverAddress, 4444), 2000);
Log.i("Socket", "Created: " + socket.toString());
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
#Override
protected void onPostExecute(Boolean aBoolean) {
Log.i("Socket", "Post..." + aBoolean);
super.onPostExecute(aBoolean);
if (aBoolean) {
connect.setChecked(true);
showToast("Connected :)", "long");
enable(controls);
enterIP.setEnabled(false);
} else {
showToast("Unable to connect...!", "long");
connect.setChecked(false);
disable(controls);
enterIP.setEnabled(true);
}
Log.i("Socket", "Post..." + aBoolean);
}
}
The Method calling this AsyncTask is below:
switch (thisView.getId()) {
case R.id.connect:
UnoCon = new UnoConnection();
UnoCon.execute();
while (!(UnoCon.getStatus().equals(AsyncTask.Status.FINISHED))) {
Log.i("UnoCon",UnoCon.getStatus().toString());
}
if (socket == null) break;
cmdSend = new commandSender();
cmdSend.execute('2', 'R');
while (!(cmdSend.getStatus().equals(AsyncTask.Status.FINISHED))) {
Log.i("cmdSend", "Not Finished Yet");
}
if (commandSent) {
respRec = new responseReceiver();
respRec.execute();
while (!(respRec.getStatus().equals(AsyncTask.Status.FINISHED))) {
Log.i("respRec", "Not Finished Yet");
}
switch (Response) {
case "1":
Relay1.setChecked(true);
break;
case "0":
Relay1.setChecked(false);
break;
default:
break;
}
}
Log.i("Socket", socket.getInetAddress().toString());
break;
So when enabling the above //Log.i("UnoCon",UnoCon.getStatus().toString()); it always give running.
When I tried using some breakpoints I realized that it:
Enters doInBackground & does everything with no exception
return true then move to return false without even writing the stacktrace
jumps to AsyncTask class & then I don't know what happens
Maybe you called cancel() on your AsyncTask
See: http://developer.android.com/reference/android/os/AsyncTask.html#cancel(boolean)
the problem is this line:
while (!(UnoCon.getStatus().equals(AsyncTask.Status.FINISHED))) {
Log.i("UnoCon",UnoCon.getStatus().toString());
}
you start the stuff on the bakcgorund thread, but then you block the UI thread.
First that is completely wrong. Blocking the UI thread with a while loop waiting for something from the background thread is just as bad as doing the background work directly on the UI thread.
Then the reason onPostExecute doesn't execute is because this method is on the queue to be processed on the UI thread, but you're blocking the UI thread.
To fix it you have to remove this loop and find another way of processing whatever you're processing after the background thread finishes.

how to force the AsyncTask to wait

i want the AsyncTask to wait till it finishes. so i wrote the below code and i used .get() method as follows and as shown below in the code
mATDisableBT = new ATDisableBT();
but at run time the .get() doesnt force ATDisableBT to wait, becuase in the logcat i receive mixed order of messages issued from ATDisableBT and ATEnableBT
which means .get() on ATDisableBT did not force it to wait
how to force the AsyncTask to wait
code:
//preparatory step 1
if (this.mBTAdapter.isEnabled()) {
mATDisableBT = new ATDisableBT();
try {
mATDisableBT.execute().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
//enable BT.
this.mATEnableBT = new ATEnableBT();
this.mATEnableBT.execute();
You can do this way:
doInBackground of AsyncTask
#Override
protected Void doInBackground(String... params) {
Log.i("doInBackground", "1");
synchronized (this) {
try {
mAsyncTask.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.i("doInBackground", "2");
return null;
}
Outside this function from where you have to nstrong textotify AsyncTask to release from wait state:
new CountDownTimer(2000, 2000) {
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
synchronized (mAsyncTask) {
mAsyncTask.notify();
}
}
}.start();
Here I have notified AsyncTask by CountDownTimer after 2 seconds.
Hope this will help you.
You should execute AsyncTask on UI thread, so using get() - which will block it makes no sense - it might get you ANR error.
If you are on HONEYCOMB and up, then AsyncTasks are executed on single executor thread, serially - so your mATEnableBT should get executed after mATDisableBT. For more see here:
http://developer.android.com/reference/android/os/AsyncTask.html#execute(Params...)
You might also switch from AsyncTask to Executors. AsyncTask is implemented using executors. By creating single threaded executor you make sure tasks will get executed serially:
ExecutorService executor = Executors.newSingleThreadExecutor();
//...
executor.submit(new Runnable() {
#Override
public void run() {
// your mATDisableBT code
}
});
executor.submit(new Runnable() {
#Override
public void run() {
// your mATEnableBT code
}
});

Android: Async Task with Thread

I am developing an application in which what I done is:
In onCreate() I first called a Async Task and then write a thread as:
new LoadDataBase().execute();
// New Thread call.
new Thread() {
// Running Thread.
public void run() {
int count=0;
while (count<5){
try{
Thread.sleep(500);
count++;
}catch(Throwable e){
e.printStackTrace();
}
}
Intent intent = new Intent(ActivityOne.this,ActivityTwo.class);
startActivity(intent);
finish();
}
}.start();
My Async Task Code is as follows:
private class LoadDataBase extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... arg0) {
// Create data base from assets folder.
DataBaseHelper dataBaseHelper = new DataBaseHelper(getApplicationContext());
try {
dataBaseHelper.createDataBase();
} catch (IOException e) {
e.printStackTrace();
}
// Closing the Data base.
dataBaseHelper.close();
return "";
}
#Override
protected void onPostExecute(String result) {}
}
But the issue is that my thread is not working properly. Means I want that the Activity one should wait for some time then activity two invoke. But it is not happing.
As I run my app, activity one is visible for fraction on second and activity two is occurs. It happens so fast that the user is not able to find that activity one is there in the app or not. But the other functionality is working fine.
Now what should I do now to hold my activity one. I don't want to implement progress dialog in Async Task because I already implemented it in XML file.
Please guide me
In onPostExecute(String result) Method, Write waiting time code using Handler...

AsynTask cancel long running operation like HttpGet

I've seen several other post about canceling an AsynTask, but I don't think any of them resolves the issues. Imagine this scenario:
public class TestTask extends AsyncTask<Void, Void, Object> {
#Override
protected void onCancelled(Object result) {
running = false;
Log.i("Test", "onCancelled");
}
#Override
protected Object doInBackground(Void... params) {
try {
Log.i("Test", "cancelling");
cancel(true);
Thread.sleep(5000);
Log.i("Test", "Past sleep");
} catch (InterruptedException e) {
Log.i("Test", "InterruptedException", e);
}
return null;
}
}
Imagine I'd like to cancel this long 20 second request in the middle of a download, for example if the server is responding slow to a json request. So the Thread.sleep(5000) could be a HttpGet request that I'd like to cancel. However the cancel method is marked as final so I can't override it and call get.abort(). The onCancel hook happens after the doInBackground and back on the UI thread. Checking for isCancel won't do me any good once the HttpGet request has started.
The way I solve this is to make an abort() method on my AsynTask and just call that.
public void abort() {
get.abort();
cancel(true);
}
but this seems to go against the Android grain a bit. Is there a better way to cancel the request?
In the docs for HttpGet, there is no mention of thread safety, so calling abort() the way you described will probably lead to undesired results (at best). What you could do is pass an HttpGet object in the constructor for your AsyncTask, or via a setter (as long you do this before you call AsyncTask.execute()).
You would have to check periodically inside of doInBackground() if the task has been cancelled:
#Override
protected Object doInBackground(Void... params) {
// start GET request
try {
Log.i("Test", "cancelling");
cancel(true);
Thread.sleep(5000);
Log.i("Test", "Past sleep");
if ( this.isCancelled() ) {
// abort GET request and/or stop doing other work
return null;
}
else {
// do what ever work you need to
}
} catch (InterruptedException e) {
Log.i("Test", "InterruptedException", e);
}
return null;
}
Source.
You can always call AsyncTask.cancel(true) whenever you feel the task should be stopped (AsyncTask.cancel())
I am not sure if this is applicable or not, but you could create another thread using an executor service that executes the download-task and keep checking for isCancelled() inside doInBackground() or until the future object returns, whichever happens first:
#Override
protected Object doInBackground(Void... params)
{
Callable<Void> downlaodTask = new Callable<Void>()
{
#Override
public Void call() throws Exception
{
// download task here
return null;
}
};
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Void> future = executor.submit(downlaodTask);
while(true) // check every second
{
try
{
future.get(1, TimeUnit.SECONDS); // wait until the download task finishes with 1 second as a timeout
break;
}
catch(TimeoutException e)
{
if(isCancelled())
{
executor.shutdownNow(); // or abort() or both
break;
}
}
}
return null;
}

asyncTask and progressDialog : Freeze

please see my code .. and if you can, tell me why my progressDialog stopped when the function is halfway done in the background, the screen hangs (nothing is displayed, the logcat shows all logs i put in the background function).
Then, right before the end, the progressDialog starts animating again and closes after a couple seconds (the function is finished and the result is displayed normally)
public class changeWall extends AsyncTask<Integer, Integer, Integer> {
protected Integer doInBackground(Integer... urls) {
int totalSize=0;
try {
if(s.loadBoolean() == false)
{
log("IF = false");
log("tempLogin = "+tempLogin);
log("tempPassword = "+tempPassword);
getNewResponse(tempLogin,tempPassword);
if(needSave)
{
s.saveBoolean(true);
}
}
else
{
if(s.loadLogin()==null)
{
getNewResponse(tempLogin,tempPassword);
}else
{
getNewResponse(s.loadLogin(),s.loadPassowrd());
}
}
parser.setLol(0);
parser.startParse(RESULT_STRING);
log("end parse");
} catch (ClientProtocolException e) {
log("internet connection lost");
} catch (IOException e) {
// TODO Auto-generated catch block
log(" connection lost");
}
log("count = "+parser.getFacebookId(1));
publishProgress();
totalSize=1;
log("end of start");
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
log("wall click ON PROGRESS UPDATE");
wall.setBackgroundResource(R.drawable.tabbuttonon);
messages.setBackgroundResource(0);
activity.setBackgroundResource(0);
profile.setBackgroundResource(0);
l1_1.setBackgroundResource(R.drawable.tabbuttononleft);
l1_2.setBackgroundResource(R.drawable.tabbuttononright);
l2_1.setBackgroundResource(0);
l2_2.setBackgroundResource(0);
l3_1.setBackgroundResource(0);
l3_2.setBackgroundResource(0);
l4_2.setBackgroundResource(0);
l4_2.setBackgroundResource(0);
wall.setTextColor(Color.BLACK);
messages.setTextColor(Color.WHITE);
profile.setTextColor(Color.WHITE);
activity.setTextColor(Color.WHITE);
try {
loadWall();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
wallProgres.dismiss();
}
protected void onPostExecute(Long result) {
if(result==1)
{
log("end WallChange");
}
}
}
simple map as this showed :
----start progress(progress.show())
----start function
--- animation (progressDialog)
---animation(---)
---animation(---)
---FREEZ
---FREEZ(Function steel working normal, progressDialog in freeze mode)
---animation
---end function
---progress.dismis();//
similar problem i found here..(this problem = my problem but without download) Freezing UI Thread with AsyncTask
Regards,Peter.
It may not be correct but place
wallProgres.dismiss();
in onPostExecute rather than in onProgessUpdate method.
beacuse onProgressUpdate calls while running , but onPostExecute calls after execution.
Hope it helps..
place this line "wallProgres.dismiss()" in onPostExecute().
protected void onPostExecute(Long result) {
if(result==1)
{
log("end WallChange");
}
if(wallProgress.isShowing())
wallProgres.dismiss();
}
put this line
wallProgres.dismiss();
in onPostExecute() method
protected void onPostExecute(Long result) {
if(result==1)
{
log("end WallChange");
wallProgres.dismiss();
}
}

Categories

Resources