Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AsyncTask Android example

I was reading about AsyncTask, and I tried the simple program below. But it does not seem to work. How can I make it work?

public class AsyncTaskActivity extends Activity {      Button btn;      /** Called when the activity is first created. */     @Override     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.main);          btn = (Button) findViewById(R.id.button1);         btn.setOnClickListener((OnClickListener) this);     }      public void onClick(View view){         new LongOperation().execute("");     }      private class LongOperation extends AsyncTask<String, Void, String> {         @Override         protected String doInBackground(String... params) {             for(int i=0;i<5;i++) {                 try {                     Thread.sleep(1000);                 } catch (InterruptedException e) {                     // TODO Auto-generated catch block                     e.printStackTrace();                 }             }             TextView txt = (TextView) findViewById(R.id.output);             txt.setText("Executed");             return null;         }          @Override         protected void onPostExecute(String result) {         }          @Override         protected void onPreExecute() {         }          @Override         protected void onProgressUpdate(Void... values) {         }     } } 

I am just trying to change the label after 5 seconds in the background process.

This is my main.xml:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"               android:layout_width="fill_parent"               android:layout_height="fill_parent"               android:orientation="vertical" >     <ProgressBar         android:id="@+id/progressBar"         style="?android:attr/progressBarStyleHorizontal"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:indeterminate="false"         android:max="10"         android:padding="10dip">     </ProgressBar>     <Button         android:id="@+id/button1"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="Start Progress" >     </Button>     <TextView android:id="@+id/output"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:text="Replace"/> </LinearLayout> 
like image 606
Fox Avatar asked Mar 12 '12 17:03

Fox


People also ask

What is AsyncTask in Android with example?

An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params , Progress and Result , and 4 steps, called onPreExecute , doInBackground , onProgressUpdate and onPostExecute .

What is AsyncTask class in Android?

Android AsyncTask is an abstract class provided by Android which gives us the liberty to perform heavy tasks in the background and keep the UI thread light thus making the application more responsive. Android application runs on a single thread when launched.

How do I use AsyncTask?

Android AsyncTask going to do background operation on background thread and update on main thread. In android we cant directly touch background thread to main thread in android development. asynctask help us to make communication between background thread to main thread.

What are the functionalities in AsyncTask in Android?

Options 1) onPreExecution() 2) doInBackground() 3) onProgressUpdate() 4) onPostExecution()


2 Answers

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         }     } } 
like image 22
Graham Smith Avatar answered Sep 28 '22 05:09

Graham Smith


My full answer is here, but here is an explanatory image to supplement the other answers on this page. For me, understanding where all the variables were going was the most confusing part in the beginning.

enter image description here

like image 189
Suragch Avatar answered Sep 28 '22 03:09

Suragch