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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • oracle 错误01017,ORA-01017:用户名密码出错 故障实例「建议收藏」

    oracle 错误01017,ORA-01017:用户名密码出错 故障实例「建议收藏」sysdba登录ORA-01017:用户名密码出错故障排查实例早上接到一个朋友的急call,说是数据库的sys登录不了系统叻。普通用户连接可以登录,只要是assysdba就提示ORA-01017:用户名密码出错。很显然这是一个典型的sysdba登录的问题。首先要他查看了sqlnet文件。SQLNET.AUTHENTICATION_SERVICES=(NONE)启动密码文件验证了,接着查看…

    2022年5月31日
    79
  • LSTM模型结构讲解[通俗易懂]

    LSTM模型结构讲解[通俗易懂]人类并不是每时每刻都从一片空白的大脑开始他们的思考。在你阅读这篇文章时候,你都是基于自己已经拥有的对先前所见词的理解来推断当前词的真实含义。我们不会将所有的东西都全部丢弃,然后用空白的大脑进行思考。我们的思想拥有持久性。传统的神经网络并不能做到这点,看起来也像是一种巨大的弊端。例如,假设你希望对电影中的每个时间点的时间类型进行分类。传统的神经网络应该很难来处理这个问题——使用电影中先前的事件推…

    2022年9月11日
    5
  • offset宏定义_vba offset 用法

    offset宏定义_vba offset 用法C语言面试的时候可能会考,这样的宏定义:#defineoffsetof(TYPE,MEMBER)((size_t)&((TYPE*)0)->MEMBER)函数作用:计算结构体成员的偏移,有些自有代码里也会手写这样的代码,实际上这个函数是标准实现的。实际上如果我们浏览ANSIC编译器的标头文件,将在stddef.h中遇到这样奇怪的宏。这个红具有可怕的声明。此…

    2022年8月22日
    5
  • Java Stringbuilder简单介绍

    Java Stringbuilder简单介绍程序开发过程中,我们常常碰到字符串连接的情况,方便和直接的方式是通过”+”符号来实现,但是这种方式达到目的的效率比较低,且每执行一次都会创建一个String对象,即耗时,又浪费空间。使用StringBuilder类就可以避免这种问题的发生,下面就Stringbuilder的使用做个简要的总结:一、创建Stringbuilder对象StringBuilderstrB=newStringBuilder();1、append(Stringstr)/append(Charc):字符串连接Syst

    2022年6月28日
    33
  • scrapy框架

    scrapy框架scrapy框架简介和基础应用什么是Scrapy?Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍。所谓的框架就是一个已经被集成了各种功能(高性能异步下载,队

    2022年7月3日
    19
  • 使用VIM搜索多个文件[通俗易懂]

    使用VIM搜索多个文件[通俗易懂]使用vim可以方便的搜索多个文件,这个时侯需要使用的命令是:vimgrep。vimgrep的命令格式是::vim[grep][!]/{pattern}/[g][j]{file}…命令:vimgrep,grep可以省略。!是在你要放弃当前文件的修改时使用。{pattern}是需要搜索的内容。{file}是需要搜索的文件。比如命令::vimgr

    2022年9月24日
    3

发表回复

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

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