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)
上一篇 2022年4月15日 下午3:20
下一篇 2022年4月15日 下午3:20


相关推荐

  • Nginx使用

    Nginx使用

    2021年7月10日
    74
  • flask中jsonify和json区别[通俗易懂]

    flask中jsonify和json区别[通俗易懂]JSON数据结构要把json与字典区分开来dumps(字典转换成Json)loads(Json转换成字典)参考:Python的字典是一种数据结构,JSON是一种数据格式。json就是一个根据某种约定格式编写的纯字符串,不具备任何数据结构的特征。而python的字典的字符串表现形式的规则看上去和json类似,但是字典本身是一个完整的数据结构,实现了一切自身该有的算法。Python的字典key可以是任意可hash对象,json只能是字符串。形式上有些相像,但JSO

    2022年5月23日
    53
  • AES加密算法的详细介绍与实现

    AES加密算法的详细介绍与实现AES简介高级加密标准(AES,AdvancedEncryptionStandard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用相同的密钥,具体的加密流程如下图:下面简单介绍下各个部分的作用与意义:明文P没有经过加密的数据。密钥K用来加密明文的密码,在对称加密算法中,加密与解密的密钥是相同的。密钥为接收方与发送方协商产生

    2022年6月26日
    20
  • 关于CPLD与FPGA的对比分析

    关于CPLD与FPGA的对比分析1.PLD/FPGA/CPLDPLD(ProgrammableLogicDevice):可编程逻辑器件,数字集成电路半成品,芯片上按照一定的排列方式集成了大量的门和触发器等基本逻辑元件,使用者按照设计要求运用开发工具将这些片内的元件连接起来,此过程称为编程;FPGA:基于查找表技术,要外挂配置用的EEPROM的PLD产品;由逻辑功能块排列为阵列,并由可编程的内部连线连接…

    2022年6月3日
    39
  • .net基础笔记4

    .net基础笔记4

    2021年8月16日
    53
  • java sdk 下载_Java SDK下载方法

    java sdk 下载_Java SDK下载方法1 下载 JDK 下载链接 点击打开链接 http www oracle com technetwork java javase downloads index html 下载成功后是这个文件 双击打开 进入安装安装在 C 盘或者其他盘 关系不大 记得自己装在哪个位置就行 因为等会儿要添加环境变量 一路安装 2 配置环境变量桌面 我的电脑 右键属性 高级设置 环境变量有的电脑是这样打开的 开始

    2026年3月26日
    2

发表回复

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

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