在非UI线程里访问 Android UI toolkit—这个在一个worker线程修改了 View 。这会导致不可预期的结果,而且还难以调试。

为了修复这个问题,Android提供了几个方法从非UI线程访问Android UI toolkit 。详见下面的这个列表:

可以使用 View.post(Runnable) 方法来修改之前的代码:

public void onClick(View v){
    new Thread(new Runnable(){
        public void run(){
            final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
            mImageView.post(new Runnable(){
                public void run(){
                    mImageView.setImageBitmap(bitmap);
                }
            });
        }
    }).start();}

  

现在这个方案的线程安全的:这个网络操作在独立线程中完成后,UI线程便会对ImageView 进行操作。

使用 AsyncTask

AsyncTask 能让你在UI上进行异步操作。它在一个worker线程里进行一些阻塞操作然后把结果交给UI主线程,在这个过程中不需要你对线程或者handler进行处理。

使用它,你必须继承 AsyncTask 并实现 doInBackground() 回调方法,这个方法运行在一个后台线程池里面。如果你需要更新UI,那么你应该实现onPostExecute()这个方法从 doInBackground() 取出结果,然后在 UI 线程里面运行,所以你可以安全的更新你的UI。你可以通过在UI线程调用 execute()方法来运行这个任务。

比如,你可以通过使用 AsyncTask来实现之前的例子:

public void onClick(View v){
    new DownloadImageTask().execute("http://example.com/image.png");
}
private class DownloadImageTask extends AsyncTask<String,Void,Bitmap>{
    /** The system calls this to perform work in a worker thread and
      * delivers it the parameters given to AsyncTask.execute() */
    protected Bitmap doInBackground(String... urls){
        return loadImageFromNetwork(urls[0]);
    }
   
    /** The system calls this to perform work in the UI thread and delivers
      * the result from doInBackground() */
    protected void onPostExecute(Bitmap result){
        mImageView.setImageBitmap(result);
    }}

  

现在UI是安全的了,代码也更加简单了,因为AsyncTask把worker线程里做的事和UI线程里要做的事分开了。

你应该阅读一下 AsyncTask 的参考文档以便更好的使用它。下面就是一个对 AsyncTask 如何作用的快速的总览:

注意: 你在使用worker线程的时候可能会碰到的另一个问题就是因为runtime configuration change (比如用户改变了屏幕的方向)导致你的activity不可预期的重启,这可能会kill掉你的worker线程。为了解决这个问题你可以参考 Shelves 这个项目。

线程安全的方法

在某些情况下,你实现的方法可能会被多个线程所调用,因此你必须把它写出线程安全的。

转自:http://greenrobot.me/devpost/android-thread-and-process/

Android 关于操作UI线程的更多相关文章

  1. Android 操作UI线程的一些方法

    我们经常会在后台线程中去做一些耗时的操作,比如去网络取数据.但是当数据取回来,需要显示到页面上的时候,会遇到一些小麻烦,因为我们都知道,android的UI页面是不允许在其他线程直接操作的.下面总结4 ...

  2. android 在非UI线程更新UI仍然成功原因深入剖析

    ”只能在UI主线程中更新View“. 这句话很熟悉吧? 来来,哥们,看一下下面的例子 @Override       protected void onCreate(Bundle savedInsta ...

  3. Android 高级UI设计笔记17:Android在非UI线程中显示Toast

    1. 子线程的Toast怎么显示不出来? 因为Toast在创建的时候会依赖于一个Handler,并且一个Handler是需要有一个Looper才能够创建,而普通的线程是不会自动去创建一个Looper对 ...

  4. Android在非UI线程中更新UI的方法

    1.使用Thread+Handler实现非UI线程更新UI界面 在UI Thread中创建Handler.用sendMessage(message)或者obtainMessage(result, ob ...

  5. Android中进程与线程及如何在子线程中操作UI线程

    1. Android进程 一个应用程序被启动时,系统默认创建执行一个叫做"main"的线程.这个线程也是你的应用与界面工具包(android.widget和android.view ...

  6. Android 实战之UI线程和Worker线程交互

    哈哈,博文取了个比较霸气的名字,大家不都喜欢这样忽悠人吗 呵呵! 好了,现在就是很简单的点击查询,然后这个查询有点花时间,不想见面出现假死现象,所以在另外的线程进行查询. 好了,代码在此: packa ...

  7. Android允许在UI线程中使用网络访问

    StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode ...

  8. Android UI线程和非UI线程

    Android UI线程和非UI线程 UI线程及Android的单线程模型原则 当应用启动,系统会创建一个主线程(main thread). 这个主线程负责向UI组件分发事件(包括绘制事件),也是在这 ...

  9. Android中UI线程与后台线程交互设计的5种方法

    我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一 些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必 ...

随机推荐

  1. CAShapeLayer + UIBezierPath

    UIBezierPath: UIBezierPath是在 UIKit 中的一个类,继承于NSObject,可以创建基于矢量的路径.使用此类可以定义常见的圆形.多边形等形状 .我们使用直线.弧(arc) ...

  2. MVC中的错误过滤器无法拦截URL路径错误的解决办法

    “/”应用程序中的服务器错误. 无法找到资源. 说明: HTTP 404.您正在查找的资源(或者它的一个依赖项)可能已被移除,或其名称已更改,或暂时不可用.请检查以下 URL 并确保其拼写正确. 请求 ...

  3. WindowsForm 增 删 查 改

    首先是连接数据库  在数据库里写代码 建立一个数据库下面是代码 create database JinXiaoCun go use JinXiaoCun go create table users ( ...

  4. 用记事本编写C#程序并运行C#代码

    net framework自带有C#编译器 csc.exe,用它就好了 它在.NET框架目录下的<\Microsoft.NET\Framework\v**** (*号内容与版本有关) 不行你直接 ...

  5. 从汇编看c++成员函数指针(三)

    前面的从汇编看c++中成员函数指针(一)和从汇编看c++成员函数指针(二)讨论的要么是单一类,要么是普通的多重继承,没有讨论虚拟继承,下面就来看一看,当引入虚拟继承之后,成员函数指针会有什么变化. 下 ...

  6. 变形课--hdu1181

    变形课 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submis ...

  7. Cube(hd1220)

    Cube 点我 Problem Description Cowl is good at solving math problems. One day a friend asked him such a ...

  8. Redis存储Session

    net Core 使用Redis存储Session   前言 Asp.net Core 改变了之前的封闭,现在开源且开放,下面我们来用Redis存储Session来做一个简单的测试,或者叫做中间件(m ...

  9. SQL Server 错误18456

    第一步. 错误发生的场景 第二步. 找到引起错误的原因 第1步. 查看windows日志文件. 运行中输入 eventvwr (event viewer)打开日志文件查看器, 第三步. 解决方案,由第 ...

  10. 2014.8.15模拟赛【公主的工作】&&bzoj1046[HAOI2007]上升序列

    bzoj题目是这样的 Description 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm ...