Threading in Android
A Thread is a sequence of instructions executed in order. Although each CPU can proc- ess only one instruction at a time, most operating systems are capable of handling multiple threads on multiple CPUs, or interleaving them on a single CPU. Different threads need different priorities, so the operating system determines how much time to give each one if they have to share a CPU.
The Android operating system is based on Linux and as such is fully capable of running multiple threads at the same time. However, you need to be aware of how applications use threads in order to design your application properly.
Single Thread
By default, an Android application runs on a single thread. Single-threaded applications run all commands serially, meaning the next command is not completed until the pre- vious one is done. Another way of saying this is that each call is blocking.
This single thread is also known as the UI thread because it's the thread that processes all the user interface commands as well. The UI thread is responsible for drawing all the elements on the screen as well as processing all the user events, such as touches on the screen, clicks of the button, and so on.
Single-threaded execution |
A much better solution is to have the potentially long operations run on a separate thread. When multiple tasks run on multiple threads at the same time, the operating system slices the available CPU so that no one task dominates the execution. As a result, it appears that multiple tasks are running in parallel at the same time.
In our example, we could put the actual network call for updating our status in the cloud in a separate thread. That way our main UI thread will not block while we're waiting for the network, and the application will appear much more responsive. We tend to talk of the main thread as running in the foreground and the additional threads as running in the background. They're really all equal in status, alternating their execution on the device's CPU, but from the point of view of the user, the main thread is in the foreground because it deals with the UI.
Multithreaded execution |
There are multiple ways of accomplishing multithreading. Java has a Thread class that allows for many of these operations. We could certainly use any of the regular Java features to put the network call in the background.
However, using the standard Java Thread class is problematic because another thread is not allowed to update the elements in the main UI thread. This makes sense because to update the UI thread, we would need to synchronize with the current state of its objects, and that would be a job on its own.
AsyncTask
AsyncTask is an Android mechanism created to help handle long operations that need to report to the UI thread.
To take advantage of this class, we need to create a new subclass of AsyncTask and implement the doInBackground(), onProgressUpdate(), and onPostExecute() methods.
In other words, we are going to fill in the blanks for what to do in the background, what to do when there's some progress, and what to do when the task completes.
Example :StatusActivity.java package com.kanakdroid.example; import winterwell.jtwitter.Twitter; import winterwell.jtwitter.TwitterException; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class StatusActivity extends Activity implements OnClickListener { private static final String TAG = "StatusActivity"; EditText editText; Button updateButton; Twitter twitter; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.status); // Find views
editText = (EditText) findViewById(R.id.editText);
updateButton = (Button) findViewById(R.id.buttonUpdate);
updateButton.setOnClickListener(this);
twitter = new Twitter("student", "password");
twitter.setAPIRootUrl("http://yamba.marakana.com/api");
}
// Asynchronously posts to twitter
class PostToTwitter extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... statuses) {
try {
Twitter.Status status = twitter.updateStatus(statuses[0]);
return status.text;
} catch (TwitterException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
return "Failed to post";
}
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
// Not used in this case
}
@Override
protected void onPostExecute(String result) {
Toast.makeText(StatusActivity2.this, result, Toast.LENGTH_LONG).show();
}
}
// Called when button is clicked
public void onClick(View v) {
String status = editText.getText().toString();
new PostToTwitter().execute(status);
Log.d(TAG, "onClicked");
}
}
onProgressUpdate() is called whenever there's progress in the task execution. The progress should be reported from the doInBackground() call.
onPostExecute() is called when our task completes. This is our callback method to update the user interface and tell the user that the task is done.
Once we have our AsyncTask set up, we can use it. To use it, we simply instantiate it and call execute() on it.
Comments
Post a Comment