来自androidDeveloper 的好文章。

http://developer.android.com/guide/practices/design/responsiveness.html

简单总结下:

0: eclipse DEBUG 模式,能看见如下的 UI 。(暂时没截图,后面补上)

1: android 主线程 也叫UI 线程。它是非UI安全的。(也就是 非UI线程去修改UI线程 会有问题。)

2: android 动态的修改 UI线程中的UI,常用的方法有 5 种。

Android offers several ways to access the UI thread from other threads. You may already be familiar with some of them but here is a comprehensive list:

  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runnable, long)
  • Handler
  • AsyncTask

The goal of AsyncTask is to take care of thread management for you. Our previous example can easily be rewritten withAsyncTask:

//=============================原文引用============================================

Painless Threading

This article discusses the threading model used by Android applications and how applications can ensure best UI performance by spawning worker threads to handle long-running operations, rather than handling them in the main thread. The article also explains the API that your application can use to interact with Android UI toolkit components running on the main thread and spawn managed worker threads.

The UI thread

When an application is launched, the system creates a thread called "main" for the application. The main thread, also called theUI thread, is very important because it is in charge of dispatching the events to the appropriate widgets, including drawing events. It is also the thread where your application interacts with running components of the Android UI toolkit.

For instance, if you touch the a button on screen, the UI thread dispatches the touch event to the widget, which in turn sets its pressed state and posts an invalidate request to the event queue. The UI thread dequeues the request and notifies the widget to redraw itself.

This single-thread model can yield poor performance unless your application is implemented properly. Specifically, if everything is happening in a single thread, performing long operations such as network access or database queries on the UI thread will block the whole user interface. No event can be dispatched, including drawing events, while the long operation is underway. From the user's perspective, the application appears hung. Even worse, if the UI thread is blocked for more than a few seconds (about 5 seconds currently) the user is presented with the infamous "application not responding" (ANR) dialog.

If you want to see how bad this can look, write a simple application with a button that invokesThread.sleep(2000) in itsOnClickListener. The button will remain in its pressed state for about 2 seconds before going back to its normal state. When this happens, it is very easy for the user toperceive the application as slow.

To summarize, it's vital to the responsiveness of your application's UI to keep the UI thread unblocked. If you have long operations to perform, you should make sure to do them in extra threads (background orworker threads).

Here's an example of a click listener downloading an image over the network and displaying it in anImageView:

public void onClick(View v) {   new Thread(new Runnable() {     public void run() {       Bitmap b = loadImageFromNetwork();       mImageView.setImageBitmap(b);     }   }).start(); }


At first, this code seems to be a good solution to your problem, as it does not block the UI thread. Unfortunately, it violates the single-threaded model for the UI: the Android UI toolkit isnot thread-safe and must always be manipulated on the UI thread. In this piece of code above, theImageView is manipulated on a worker thread, which can cause really weird problems. Tracking down and fixing such bugs can be difficult and time-consuming.

Android offers several ways to access the UI thread from other threads. You may already be familiar with some of them but here is a comprehensive list:

  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runnable, long)
  • Handler

You can use any of these classes and methods to correct the previous code example:

public void onClick(View v) {   new Thread(new Runnable() {     public void run() {       final Bitmap b = loadImageFromNetwork();       mImageView.post(new Runnable() {         public void run() {           mImageView.setImageBitmap(b);         }       });     }   }).start(); }

Unfortunately, these classes and methods could also tend to make your code more complicated and more difficult to read. It becomes even worse when your implement complex operations that require frequent UI updates.

To remedy this problem, Android 1.5 and later platforms offer a utility class calledAsyncTask, that simplifies the creation of long-running tasks that need to communicate with the user interface.

An AsyncTask equivalent is also available for applications that will run on Android 1.0 and 1.1. The name of the class isUserTask. It offers the exact same API and all you have to do is copy its source code in your application.

The goal of AsyncTask is to take care of thread management for you. Our previous example can easily be rewritten withAsyncTask:

public void onClick(View v) {   new DownloadImageTask().execute("http://example.com/image.png"); }  private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {      protected Bitmap doInBackground(String... urls) {          return loadImageFromNetwork(urls[0]);      }       protected void onPostExecute(Bitmap result) {          mImageView.setImageBitmap(result);      }  }


As you can see, AsyncTask must be used by subclassing it. It is also very important to remember that anAsyncTask instance has to be created on the UI thread and can be executed only once. You can read theAsyncTask documentation for a full understanding on how to use this class, but here is a quick overview of how it works:

  • You can specify the type, using generics, of the parameters, the progress values and the final value of the task
  • The method doInBackground() executes automatically on a worker thread
  • onPreExecute(),onPostExecute() and onProgressUpdate() are all invoked on the UI thread
  • The value returned by doInBackground() is sent to onPostExecute()
  • You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the UI thread
  • You can cancel the task at any time, from any thread

In addition to the official documentation, you can read several complex examples in the source code of Shelves (ShelvesActivity.java and AddBookActivity.java) and Photostream (LoginActivity.java,PhotostreamActivity.java and ViewPhotoActivity.java). We highly recommend reading the source code ofShelves to see how to persist tasks across configuration changes and how to cancel them properly when the activity is destroyed.

Regardless of whether or not you use AsyncTask, always remember these two rules about the single thread model:

  1. Do not block the UI thread, and
  2. Make sure that you access the Android UI toolkit only on the UI thread.

AsyncTask just makes it easier to do both of these things.

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. Android(安卓)JNI 之 JNIEnv 解析
  3. Android(安卓)当修改一些代码时,使用什么编译命令可以最有效率
  4. android service 广播 更新 activity
  5. 关于上传的app的标识号和版本号
  6. Android的handler和callback机制
  7. ProgressBar
  8. android 应用的网络请求工具
  9. ClassNotFoundException解决方案总结

随机推荐

  1. android 新手学习笔记 点击事件
  2. Android(安卓)NDK R8 发布
  3. android kindleFire develop
  4. Android(安卓)富文本编辑器 - ListItemSp
  5. android 在线视频播放器实现方法
  6. Android(安卓)流媒体系列(二)
  7. Android(安卓)Tab点击监听 自定义事件
  8. Android(安卓)Interface Definition Lang
  9. Android(安卓)| class | tree
  10. Android(安卓)4种补间动画基础使用。