Asynctask Android Example

AsyncTask Android example

Ok, you are trying to access the GUI via another thread. This, in the main, is not good practice.

The AsyncTask executes everything in doInBackground() inside of another thread, which does not have access to the GUI where your views are.

preExecute() and postExecute() offer you access to the GUI before and after the heavy lifting occurs in this new thread, and you can even pass the result of the long operation to postExecute() to then show any results of processing.

See these lines where you are later updating your TextView:

TextView txt = findViewById(R.id.output);
txt.setText("Executed");

Put them in onPostExecute().

You will then see your TextView text updated after the doInBackground completes.

I noticed that your onClick listener does not check to see which View has been selected. I find the easiest way to do this is via switch statements. I have a complete class edited below with all suggestions to save confusion.

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.System;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;

public class AsyncTaskActivity extends Activity implements OnClickListener {

Button btn;
AsyncTask<?, ?, ?> runningTask;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = findViewById(R.id.button1);

// Because we implement OnClickListener, we only
// have to pass "this" (much easier)
btn.setOnClickListener(this);
}

@Override
public void onClick(View view) {
// Detect the view that was "clicked"
switch (view.getId()) {
case R.id.button1:
if (runningTask != null)
runningTask.cancel(true);
runningTask = new LongOperation();
runningTask.execute();
break;
}
}

@Override
protected void onDestroy() {
super.onDestroy();
// Cancel running task(s) to avoid memory leaks
if (runningTask != null)
runningTask.cancel(true);
}

private final class LongOperation extends AsyncTask<Void, Void, String> {

@Override
protected String doInBackground(Void... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// We were cancelled; stop sleeping!
}
}
return "Executed";
}

@Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed"); // txt.setText(result);
// You might want to change "executed" for the returned string
// passed into onPostExecute(), but that is up to you
}
}
}

Android AsyncTask example and explanation

AsyncTask is one of the easiest ways to implement parallelism in Android without having to deal with more complex methods like Threads. Though it offers a basic level of parallelism with the UI thread, it should not be used for longer operations (of, say, not more than 2 seconds).

AsyncTask has four methods

  • onPreExecute()
  • doInBackground()
  • onProgressUpdate()
  • onPostExecute()

where doInBackground() is the most important as it is where background computations are performed.

Code:

Here is a skeletal code outline with explanations:

public class AsyncTaskTestActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// This starts the AsyncTask
// Doesn't need to be in onCreate()
new MyTask().execute("my string parameter");
}

// Here is the AsyncTask class:
//
// AsyncTask<Params, Progress, Result>.
// Params – the type (Object/primitive) you pass to the AsyncTask from .execute()
// Progress – the type that gets passed to onProgressUpdate()
// Result – the type returns from doInBackground()
// Any of them can be String, Integer, Void, etc.

private class MyTask extends AsyncTask<String, Integer, String> {

// Runs in UI before background thread is called
@Override
protected void onPreExecute() {
super.onPreExecute();

// Do something like display a progress bar
}

// This is run in a background thread
@Override
protected String doInBackground(String... params) {
// get the string from params, which is an array
String myString = params[0];

// Do something that takes a long time, for example:
for (int i = 0; i <= 100; i++) {

// Do things

// Call this to update your progress
publishProgress(i);
}

return "this string is passed to onPostExecute";
}

// This is called from background thread but runs in UI
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);

// Do things like update the progress bar
}

// This runs in UI when background thread finishes
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);

// Do things like hide the progress bar or change a TextView
}
}
}

Flow Diagram:

Here is a diagram to help explain where all the parameters and types are going:

Sample Image

Other helpful links:

  • What arguments are passed into AsyncTask<arg1, arg2, arg3>?
  • Slidenerd Android AsyncTask Tutorial: Android Tutorial For Beginners
  • Understanding AsyncTask – Once and Forever
  • Dealing with AsyncTask and Screen Orientation
  • How to pass multiple parameters to AsynkTask
  • how to pass in two different data types to AsyncTask, Android

AsyncTask in Android with Kotlin

AsyncTask is an Android API, not a language feature that is provided by Java nor Kotlin. You can just use them like this if you want:

class someTask() : AsyncTask<Void, Void, String>() {
override fun doInBackground(vararg params: Void?): String? {
// ...
}

override fun onPreExecute() {
super.onPreExecute()
// ...
}

override fun onPostExecute(result: String?) {
super.onPostExecute(result)
// ...
}
}

Anko's doAsync is not really 'provided' by Kotlin, since Anko is a library that uses language features from Kotlin to simplify long codes. Check here:

  • https://github.com/Kotlin/anko/blob/d5a526512b48c5cd2e3b8f6ff14b153c2337aa22/anko/library/static/commons/src/Async.kt

If you use Anko your code will be similar to this:

doAsync {
// ...
}

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

Android: AsyncTask to make an HTTP GET Request?

Yes you are right, Asynctask is used for short running task such as connection to the network. Also it is used for background task so that you wont block you UI thread or getting exception because you cant do network connection in your UI/Main thread.

example:

class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {


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

}

@Override
protected Boolean doInBackground(String... urls) {
try {

//------------------>>
HttpGet httppost = new HttpGet("YOU URLS TO JSON");
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httppost);

// StatusLine stat = response.getStatusLine();
int status = response.getStatusLine().getStatusCode();

if (status == 200) {
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);


JSONObject jsono = new JSONObject(data);

return true;
}


} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {

e.printStackTrace();
}
return false;
}

protected void onPostExecute(Boolean result) {

}

The AsyncTask API is deprecated in Android 11. What are the alternatives?

private WeakReference<MyActivity> activityReference;

Good riddance that it's deprecated, because the WeakReference<Context> was always a hack, and not a proper solution.

Now people will have the opportunity to sanitize their code.


AsyncTask<String, Void, MyPojo> 

Based on this code, Progress is actually not needed, and there is a String input + MyPojo output.

This is actually quite easy to accomplish without any use of AsyncTask.

public class TaskRunner {
private final Executor executor = Executors.newSingleThreadExecutor(); // change according to your requirements
private final Handler handler = new Handler(Looper.getMainLooper());

public interface Callback<R> {
void onComplete(R result);
}

public <R> void executeAsync(Callable<R> callable, Callback<R> callback) {
executor.execute(() -> {
final R result = callable.call();
handler.post(() -> {
callback.onComplete(result);
});
});
}
}

How to pass in the String? Like so:

class LongRunningTask implements Callable<MyPojo> {
private final String input;

public LongRunningTask(String input) {
this.input = input;
}

@Override
public MyPojo call() {
// Some long running task
return myPojo;
}
}

And

// in ViewModel
taskRunner.executeAsync(new LongRunningTask(input), (data) -> {
// MyActivity activity = activityReference.get();
// activity.progressBar.setVisibility(View.GONE);
// populateData(activity, data) ;

loadingLiveData.setValue(false);
dataLiveData.setValue(data);
});

// in Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main_activity);

viewModel = ViewModelProviders.of(this).get(MyViewModel.class);
viewModel.loadingLiveData.observe(this, (loading) -> {
if(loading) {
progressBar.setVisibility(View.VISIBLE);
} else {
progressBar.setVisibility(View.GONE);
}
});

viewModel.dataLiveData.observe(this, (data) -> {
populateData(data);
});
}

This example used a single-threaded pool which is good for DB writes (or serialized network requests), but if you want something for DB reads or multiple requests, you can consider the following Executor configuration:

private static final Executor THREAD_POOL_EXECUTOR =
new ThreadPoolExecutor(5, 128, 1,
TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

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();
}

}
}


Related Topics



Leave a reply



Submit