How to Use Asynctask Correctly in Android

How to use AsyncTask correctly in Android

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;

public class AsyncExample extends Activity{


private String url="http://www.google.co.in";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}


@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();

new AsyncCaller().execute();

}

private class AsyncCaller extends AsyncTask<Void, Void, Void>
{
ProgressDialog pdLoading = new ProgressDialog(AsyncExample.this);

@Override
protected void onPreExecute() {
super.onPreExecute();

//this method will be running on UI thread
pdLoading.setMessage("\tLoading...");
pdLoading.show();
}
@Override
protected Void doInBackground(Void... params) {

//this method will be running on background thread so don't update UI frome here
//do your long running http tasks here,you dont want to pass argument and u can access the parent class' variable url over here


return null;
}

@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);

//this method will be running on UI thread

pdLoading.dismiss();
}

}
}

How to properly use AsyncTask on Android?

to check if the internet connection is available, you can do this:

private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting();
//return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

You can't call

Boolean internetConnection;
internetConnection = new CheckConnectionTask().execute();

the return value of excute() is not what you want. If you want use asyntask you can set a boolean variable in onPostExecute(...) :

private boolean isConnect = false;
private class CheckConnectionTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void... params) {
try {
InetAddress ipAddr = InetAddress.getByName("https://www.google.com");

if (!ipAddr.isReachable(10000)) {
return false;
} else {
return true;
}

} catch (Exception e) {
Log.e("exception", e.toString());
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(aVoid);
isConnect = result;
}
}

But, I never use this approach to get status of internet connection, beacause I must run this asyntask before everything to get exact status.

Android: How to implement Asynctask correctly for this below class?

Based on you edit, you're trying to extend two classes? Well, (I think) that's not possible in Java ...

Back to your question about AsyncTask. AsynTask are made to make task outside de Main Thread/UI Thread, for some scenarios (Ex.: the basic, not lock the UI while doing some work), for that reason you can't interact with the UI in a AsyncTask or even mix both things (is possible in some cases, but not recommended).

So you need to extends AsyncTask in other class than your view/activity (another Class.java or nested/internal class), example below:

public class MyAsyncTask extends AsyncTask<ParameterType, ProgressType, ReturnType> {

//Example to demonstrate UI interation
private IView view;

public MyAsyncTask(IView view) {
this.view = view;
}

@Override
protected ReturnType doInBackground(ParameterType... params) {
// do and update the work
return new ReturnType(); // work is done, return the result
}

// Override this method if you need to do something after the AsyncTask has finished (based on the return). Here you can interact with the UI too.
@Override
protected void onPostExecute(ReturnType o) {
// Example of UI interaction
view.updateUI(o);
}
}

If you don't need Parameters, Returns or update the progress of your AsyncTask, you can use the 'Void' type in place ParameterType, ProgressType or ReturnType.

Then you can create a intance of MyAsyncTask in other classes (Ex.: your activity) an call ‘execute()’ method to start the AsyncTask.

public class Foobar extends AppCompatActivity implements IView {
... code ...
MyAsyncTask fooTask = new MyAsyncTask(this); // Foobar class needs to implement IView interface
fooTask.execute(parameters); // execute AsyncTask with 'parameters'
... code ...
}

Based on your code you're trying to make a Network call. So you need need migrate your network call to inside 'doInBackground' method, and call the next activity (or show the error) in the 'onPostExecute'.

I not very familiar with your implementation (RestClient, ResponseResolver), but I think you can use Retrofit/Jackson libraries for a more solid solution. They are not very difficult to understand and makes Network calls easier.

In the references below there are other alternatives that you can use instead of a AsyncTask.

Here is some references:

https://developer.android.com/reference/android/os/AsyncTask.html
https://developer.android.com/guide/components/processes-and-threads.html

Good coding.

How to use AsyncTask correctly?

If you need todo a simple work in background do not use deprecated AsyncTask use Executors.

        Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Runnable() {
@Override
public void run() {
// run your background code here
}
});

Using AsyncTask

It would be something like this

   public class TalkToServer extends AsyncTask<Void, Void, Void> {

@Override
protected void onPreExecute() {
/*
* do things before doInBackground() code runs
* such as preparing and showing a Dialog or ProgressBar
*/
}

@Override
protected void onProgressUpdate(Void... values) {
/*
* updating data
* such a Dialog or ProgressBar
*/

}

@Override
protected Void doInBackground(Void... params) {
//do your work here
return null;
}

@Override
protected void onPostExecute(Void result) {
/*
* do something with data here
* display it or send to mainactivity
* close any dialogs/ProgressBars/etc...
*/
}
}

Then you can execute it with

TalkToServer myTask = new MyTask(); // can add params for a constructor if needed
myTask.execute(); // here is where you would pass data to doInBackground()

You may not need onProgressUpdate() or onPreExecute() if you aren't using them to show a Dialog, progress, or other tasks before or during doInBackground().

onPreExecute() can be used to initialize and show a ProgressDialog. Then it could be dismissed in onPostExecute()

After a task finishes

onPostExecute() will be called. If the class is an inner-class of your Activity then you can update UI elements there or call a function to run code once the task finishes. If it is a separate file than the Activity then you can use an interface and create a callBack to the Activity and run code there once the task finishes.

This answer talks about using an interface for a callback if you need

Make sure any UI updating is done in any method besides doInBackground() or sent back to the Activity in any function besides doInBackground(). Heavy-lifting such as network operations should be done in doInBackground().

Also, be sure to read through the AsyncTask Docs completely. Especially the Threading Rules

Can somebody explain how to use ASyncTask with Android?

AsyncTask uses parameterized types (java generics) so that you can specify the types it uses when you define your own AsyncTask. Perhaps it's easier to explain in this form:

public abstract class AsyncTask<Params, Progress, Result> {
...
protected abstract Result doInBackground(Params... params);

protected abstract void onProgressUpdate(Progress... progress);

protected abstract void onPostExecute(Result result);
...
}

There are no classes named Params, Progress, or Result. These are instead generic types. They are just placeholders for types you wish to use when you define your own AsyncTask subclass. The above could equally be written as such:

public abstract class AsyncTask<A, B, C> {
...
protected abstract C doInBackground(A... params);

protected abstract void onProgressUpdate(B... progress);

protected abstract void onPostExecute(C result);
...
}

Suppose I were defining an AsyncTask that takes a list of Strings representing URLs, and it will ping each one to see if it's reachable, then return the number that were reachable. Meanwhile, with each test, it will update a ProgressBar as each test completes. It might look something like this:

public class MyAsyncTask extends AsyncTask<String, Integer, Integer> {

@Override
protected Integer doInBackground(String... params) {
int total = params.length;
int successfulPings = 0;
for (int i = 0; i < total; i++) {
if (isReachable(params[i])) {
successfulPings++;
}
publishProgress(i, total);
}
return successfulPings;
}

@Override
protected void onProgressUpdate(Integer... progress) {
int testsSoFar = progress[0];
int totalTests = progress[1];
progressBar.setMax(totalTests);
progressBar.setProgress(testSoFar);
}

@Override
protected void onPostExecute(Integer result) {
Toast.makeTest(context, "Reached " + result + " sites.", Toast.LENGTH_SHORT).show();
}
}

I would initiate this as follows:

String[] urls = ...
MyAsyncTask task = new MyAsyncTask();
task.execute(urls);

The argument passed into execute will be passed into doInBackground. Whatever you do in doInBackground, you need to return something that gets passed in as the argument to onPostExecute. While in doInBackground, you can call publishProgress, where you can do something like I did (but you don't have to).



Related Topics



Leave a reply



Submit