We will introduce the Android single-threaded model in detail in this article. I hope that beginners can have a full understanding of this concept through the content introduced in this article and have a deep understanding of this system.
- Android unit test source code
- Android Jni sample code
- How to install and uninstall a program on Android
- Android Shell commands
- Android data transmission Overview
When an Android program is started for the first time, Android automatically creates a thread called "main" main thread. This main thread is also called the UI thread), because it is responsible for dispatching events to the corresponding controls, including Screen Drawing events. It is also the thread of user interaction with the Andriod control. For example, when you press a button on the screen, the UI thread will distribute the event to the button you just pressed, then the button sets itself as pressed and sends an invalid invalidate request to the event queue. The UI thread will remove this request from the event queue and notify the button to redraw itself on the screen.
The Android single-threaded model will cause low performance of Android applications without considering its impact, because all tasks are executed in the same thread. If you execute some time-consuming operations, if you access the network or query the database, the entire user interface is blocked. When some time-consuming operations are performed, events cannot be distributed in a timely manner, including user interface re-painting events. From the user's perspective, the application seems to have crashed. Worse, if the application is blocked for too long, it may take about five seconds.) Android will prompt the user with some information, that is, open an "application does not have the corresponding application not responding) "dialog box.
If you want to know how bad this is, write a simple program containing a button, register a click event for the button, and call such code Thread in the event processor. sleep (2000 ). After you press this button, the restore button remains in normal state for about 2 seconds. If this happens in your application, your first response is that your program runs slowly.
Now you know that you should avoid executing time-consuming operations in the UI thread. You are likely to execute these time-consuming tasks in the background thread or worker thread. Is this correct? Let's take a look at an example. In this example, the Click Event downloads an image from the network and uses ImageView to display the image. The Code is as follows:
- public void onClick( View v ) {
- new Thread( new Runnable() {
- public void run() {
- Bitmap b = loadImageFromNetwork();
- mImageView.setImageBitmap( b );
- }
- }).start();
- }
- public void onClick( View v ) {
- new Thread( new Runnable() {
- public void run() {
- Bitmap b = loadImageFromNetwork();
- mImageView.setImageBitmap( b );
- }
- }).start();
- }
This Code seems to solve your problem well because it does not block the UI thread. Unfortunately, it violates the Android single-thread model: Android UI operations are not thread-safe and must be executed in the UI thread. In this code snippet, The ImageView method is used in a worker thread, which causes some strange problems. It is very difficult and time-consuming to investigate and fix the problem.
Andriod provides several methods to access the UI thread in other threads. You may already be familiar with some of these methods, but below is a more comprehensive list:
- Activity.runOnUiThread( Runnable )
- View.post( Runnable )
- View.postDelayed( Runnable, long )
- Hanlder
Any of the above classes or methods can fix problems in our previous code.
- public void onClick( View v ) {
- new Thread( new Runnable() {
- public void run() {
- final Bitmap b = loadImageFromNetwork();
- mImageView.post( new Runnable() {
- mImageView.setImageBitmap( b );
- });
- }
- }).start();
- }
- public void onClick( View v ) {
- new Thread( new Runnable() {
- public void run() {
- final Bitmap b = loadImageFromNetwork();
- mImageView.post( new Runnable() {
- mImageView.setImageBitmap( b );
- });
- }
- }).start();
- }
Unfortunately, these classes or methods also make your code complex and hard to understand. However, when you need to implement complex operations and frequently update the UI, this will become worse. To solve this problem, Android 1.5 provides a tool class: AsyncTask, which makes it easier to create long-running tasks that need to interact with the user interface.
In Android 1.0 and 1.1, UserTask has the same functions as AsyncTask. It provides the same API. All you need to do is copy its code to your program.
The goal of AsyncTask is to manage your threads for you. The previous code can be easily rewritten using AsyncTask.
- public void onClick( View v ) {
- new DownloadImageTask().execute
( "http://example.com/image.png" );
- }
- private class DownloadImageTask extends AsyncTask {
- protected Bitmap doInBackground( String... urls ) {
- return loadImageFormNetwork( urls[0] );
- }
- protected void onPostExecute( Bitmap result ) {
- mImageView.setImageBitmap( result );
- }
- }
- public void onClick( View v ) {
- new DownloadImageTask().execute
( "http://example.com/image.png" );
- }
- private class DownloadImageTask extends AsyncTask {
- protected Bitmap doInBackground( String... urls ) {
- return loadImageFormNetwork( urls[0] );
- }
- protected void onPostExecute( Bitmap result ) {
- mImageView.setImageBitmap( result );
- }
- }
As you can see, using AsyncTask must inherit it. It is very important to use AsyncTask: The AsyncTask instance must be created in the UI thread and can only be used once. You can use the pre-read AsyncTask document to learn how to use this class. The following describes how it works:
You can use generic parameters to specify task parameters, intermediate values progress values), and any final execution results.
The doInBackground () method is automatically executed in the worker thread.
The onPreExecute (), onPostExecute (), and onProgressUpdate () methods are called in the UI thread.
The Return Value of the doInBackground () method is passed to the onPostExecute () method.
In the doInBackground () method, you can call the publishProgress () method. Each call causes the UI thread to execute the onProgressUpdate () method.
You can cancel this task in any thread at any time.
In addition to official documents, you can read several complex examples in the source code of Shelves and Photostream. I strongly recommend you read the source code of Shelves, which will show you how to persist tasks between configuration changes and cancel tasks correctly when the activity is destroyed.
Whether or not AsyncTask is used, always remember the following two guidelines for the Android single-threaded model: Do not block the UI thread and all Android UI operations are executed in the UI thread. AsyncTask only makes it easier for you to follow these two principles.