Threading(in thread main)

PainlessThreadingThisarticlediscussesthethreadingmodelusedbyAndroidapplicationsandhowapplicationscanensurebestUIperformancebyspawningworkerthreadstohandlelong-runningoperat

大家好,又见面了,我是你们的朋友全栈君。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.

本文讨论Android中的线程模型,以及应用如何通过产生worker threads来处理长时间操作以确保最佳的UI性能,而不是在主线程中处理这些任务。本文还介绍了与Android UI工具包组件中的主线程进行交互以及产生worker threads的APIs。

The UI thread

UI线程

When an application is launched, the system creates a thread called “main” for the application. The main thread, also called the UI 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.

当应用被启动时,系统创建一个主线程(main thread)。主线程也被称为UI线程(UI thread)管理事件的发布,如drawing events.它也是与Android UI工具包的运行组件交互的线程.

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.

除非你的应用是正确的,否则这种单线程模型有可能产生低效的性能。特别地,若所有事件都发生在在单一线程中,执行长操作,如在UI线程中访问网络或者数据库查询将阻塞整个用户界面。此时任何其它事件,如drawing events都不会被派发。从用户的角度,应用给人感觉被挂起了。更糟糕地是,若UI线程阻塞时间多达几秒,用户会以为”application not responding”(ANR).

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 or worker threads).

总之,保证主线程非阻塞非常重要。若你执行长时间操作,你需要在其它的线程(后台线程或工作线程)中执行。

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

以下给出单击监听下载一张图片并将其显示在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-threaded model for the UI: the Android UI toolkit is not thread-safe and must always be manipulated on the UI thread. In this piece of code above, the ImageView is manipulated on a worker thread, which can cause really weird problems. Tracking down and fixing such bugs can be difficult and time-consuming.

这段代码貌似没问题,因为它不会阻塞UI线程。然而,它违反了UI单线程模型:Android UI工具集并不是线程安全的,它而且必须在UI线程中执行。所以以上代码中,ImageView在一个工作线程中被执行,这可能导致非常奇怪的问题。调试这种bugs又困难又浪费时间。

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:

Android提供多种方式使其它线程访问UI线程。

以下给出一种很熟悉的步骤访问UI线程:

1).Activity.runOnUiThread(Runnable)

2).View.post(Runnable)

3).View.postDelayed(Runnable, long)

4).Handler

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.

不幸地是,这些类与方法只会使你的代码难以维护。特别是在你实现需要频繁的UI更新操作时这种方法使你的实现更加复杂。

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

为了解决这个问题,Android 1.5+提供了一个工具类AsyncTask来简化一个需要与用户界面交互的长时间运行的任务的创建。

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

Android 1.0和1.1中提供了一个AsyncTask类的等价类UserTask,它提供了几乎一模一样的API.

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

AsyncTask的目标是关注线程管理,之前那个例子可用AsyncTask重写为:

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 an AsyncTask instance 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:

正如你所看到的,AsyncTask需要被继承。注,AsyncTask实例必段在UI线程中创建并且只被执行一次。你可以阅读AsyncTask文档来了解更详细的使用。以下给出AsyncTask的简介:

1).You can specify the type of the parameters, the progress values and the final value of the task

你需要指明task的参数类型,进度值以及最终值

2).The method doInBackground() executes automatically on a worker thread

doInBackground()方法在一个工作线程中自动执行

3).onPreExecute(), onPostExecute() and onProgressUpdate() are all invoked on the UI thread

onPreExecute(), onPostExecute()和onProgressUpdate()都在UI线程中执行

4).The value returned by doInBackground() is sent to onPostExecute()

doInBackground()方法返回的值被发送给onPostExecute()

5).You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the UI thread

你可以在doInBackground()方法中的任何时候调用publishProgress()来执行UI线程中的进度更新任务onProgressUpdate()

6).You can cancel the task at any time, from any thread

你可以在任何时候从任何线程中取消任务

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

不论你是否使用AsyncTask,对于单线程模记住以下两条准则很重要:

1).Do not block the UI thread, and —— 不要阻塞UI线程

2).Make sure that you access the Android UI toolkit only on the UI thread. —— 确保只在UI线程中访问Android UI工具集

详情请见:http://developer.android.com/resources/articles/painless-threading.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/128924.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • idea2021.3激活吗 30 天破解方法

    idea2021.3激活吗 30 天破解方法,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月15日
    146
  • .NET API for RabbitMQ and ActiveMQ

    .NET API for RabbitMQ and ActiveMQ

    2022年1月15日
    44
  • 基于OIDC实现单点登录SSO、第三方登录[通俗易懂]

    基于OIDC实现单点登录SSO、第三方登录[通俗易懂]OIDC联合身份认证机制背景概念1OIDC身份认证协议2基于OIDC实现SSO2.1统一登录2.1.1流程2.1.2RP相关接口2.1.3OP相关接口2.2统一登出2.2.1流程2.2.2RP需要在向OP注册时提供2.2.3RP相关接口2.2.4OP相关接口2.3持续监视2.3.1流程2.3.2RP相关接口2.3.3OP相关接口3在OIDC的SSO中集成第三方登录(…

    2022年8月30日
    4
  • ANSI编码对照表「建议收藏」

    ANSI编码对照表「建议收藏」目前计算机中用得最广泛的字符集及其编码,是由美国国家标准局(ANSI)制定的ASCII码(AmericanStandardCodeforInformationInterchange,美国标准信息交换码),它已被国际标准化组织(ISO)定为国际标准,称为ISO646标准。适用于所有拉丁文字字母,ASCII码有7位码和8位码两种形式。因为1位二进制数可以表示(21=)2种状态:0、1;而2位二进制数可以表示(22)=4种状态:00、01、10、11;依次类推,7位二进制数可以表示(27=)128种

    2022年9月23日
    5
  • 2022年计算机考研过线就能上的学校[通俗易懂]

    2022年计算机考研过线就能上的学校[通俗易懂]部分考研同学本科是双非计算机类专业,基础能力一般,编程能力较弱,那么对于这类考生,主要还是以求稳为主,选择一个分数略低,复试较简单的学校,上岸几率就会加大。那么2022年计算机考研过线上岸率高的院校有哪些呢?

    2022年6月6日
    340
  • 虚拟机连接上网的步骤「建议收藏」

    虚拟机连接上网的步骤「建议收藏」1.首先查看本机的可上网的IP地址:我的本机IP地址是192.168.1.5,由此可以推出我的网关地址就是192.168.1.1这个网关就是可以用来访问的一个地址,一般子网掩码都是255.255.255.02.设置本机的Vmare8的IP为静态IP和并且一定要配到这个192.168.1.1这个网关下右键其属性配成对用的网关地址,一定要在一个网段内下面是虚拟机里面的配置,里面有个虚拟机网络编辑这个是可供虚拟机上网的网段,一定要在这个范围之内这个配置完之后

    2022年5月19日
    72

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号