一篇讲解android线程非常好的文章
2015-02-12 02:32
162 查看
Painless threading
Whenever you first start an Android application, a thread called "main" is automatically created. The main thread, also called the UI thread, is very important because it is in charge of dispatching the events to the appropriate widgets and this includesthe drawing events. It is also the thread you interact with Android widgets on. 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 in Android applications that do not consider the implications. Since everything happens on a single thread performing long operations, like network access or database queries, on this 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 invokes
Thread.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 to perceive the application as slow.
Now that you know you must avoid lengthy operations on the UI thread, you will probably use extra threads (background or workerthreads) to perform these operations, and rightly so. Let's take the example of a click listener downloading
an image over the network and displaying it in an ImageView:
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 thread model: the Android UI toolkit is not thread-safe and must always be manipulated on the UI thread. In this piece
of code, the
ImageViewis 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
Any of these classes and methods could be used to correct our 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 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 offers a
new utility class, called AsyncTask, that simplifies the creation of long-running tasks that need to communicate
with the user interface.
AsyncTask is also available for Android 1.0 and 1.1 under the name UserTask.
It offers the exact same API and all you have to do is copy its source code in your application.
The goal of
AsyncTaskis to take care of thread management for you. Our previous example can easily be rewritten with
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 loadImageFromNetwork(urls[0]); } protected void onPostExecute(Bitmap result) { mImageView.setImageBitmap(result); } }
As you can see,
AsyncTaskmust be used by subclassing it. It is also very important to remember that an
AsyncTaskinstance has to be created on the UI thread and can be executed only once. You can read the AsyncTask
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 andViewPhotoActivity.java).
I highly recommend reading the source code of Shelves 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:
do not block the UI thread and make sure the Android UI toolkit is only accessed on the UI thread. AsyncTask just
makes it easier to do both of these things.
If you want to learn more cool techniques, come join us at Google I/O. Members of the Android team will be there to give a series
of in-depth technical sessions and answer all your questions.
原文:http://android-developers.blogspot.jp/2009/05/painless-threading.html
文章很好懂,大多是专业术语和日常用语~~~如果大家有看不懂的,可以参考http://blog.csdn.net/johnny901114/article/details/7536951这位博友的翻译
相关文章推荐
- 一篇非常好的讲解转场动画的文章链接
- 一篇非常好的服务器控件原理讲解文章(转载)
- 一篇非常好的服务器控件原理讲解文章(转载)
- COM的通信原理及ATL的通信操作 看过的一篇非常好的讲解通讯机制的文章
- 一篇非常好的服务器控件原理讲解文章
- 转载一篇讲解Hash表的文章
- 推荐一篇非常好的CakePHP入门文章
- Microsoft Sync Framework Runtime 简介(一篇非常好的MSF介绍文章)
- 一篇讲得非常好的build模式的解释文章
- 一篇讲解动态规划算法不错的文章
- 一篇不错的讲解Java异常的文章
- 一篇关于反射的非常好的文章
- 一篇很透彻讲解session的文章分享一下
- 一篇不错的讲解Java异常的文章(转载)----感觉很不错,读了以后很有启发
- 一篇不错的讲解Java异常的文章(转载)----感觉很不错,读了以后很有启发
- 一篇不错的讲解Java异常的文章(转载)----感觉很不错,读了以后很有启发
- 转载一篇总结的非常好的内存分析文章
- 转一篇文章,以便在后续文章中讲解——开源gis项目Mitab在C#中的使用方法
- 记录讲解Android Adapter的一篇文章
- 一篇不错的讲解Java异常的文章