在非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. Windows环境搭建Red5流媒体服务器指南(转)

    Windows环境搭建Red5流媒体服务器指南 Windows环境搭建Red5流媒体服务器指南 测试环境:Windows 7 一.   下载安装程序 red5-server 下载地址 https:// ...

  2. 【Android类型SDK测试(一)】认识Android类型的 SDK

    (一)SDK是个什么东东 接触软件相关行业的同学都应该知道,SDK(即 Software Development Kit),软件开发包.其作用就是为开发某些软件提供一些便利的东西,包括工具 集合,文档 ...

  3. ORACLE DUAL表详解 .

    今天在戴明明同学的QQ空间里看到篇不错的关于DUAL表的文章,自己平时也时而会用到,可是没有系统的学习过,借这个机会学习学习~ ==================================== ...

  4. java压缩/解压缩zip格式文件

    因为项目要用到压缩.解压缩zip格式压缩包,只好自己封装一个,对于网上流行的中文乱码的问题,本文的解决方法是用apache的包代替jdk里的.基本上还是比较好用的. 废话少说,直接上代码. }     ...

  5. Sublime Text 3 个人配置文件

    { "dpi_scale": 1.0, "draw_white_space": "selection", "fallback_en ...

  6. Python中yield深入理解

    众所周知,python中的yield有这样的用法: def test(alist): for i in alist: yield i 这样,这个test函数就变成了一个生成器,当每次调用的时候,就会自 ...

  7. Oracle EBS-SQL (QA-1):检查超出检验周期的检验数据.sql

    select msi.segment1                                    物料编码,          msi.DESCRIPTION                ...

  8. 浅谈 qmake 之 shadow build(就是将源码路径和构建路径分开)

    shadow build shadow build 是什么东西?就是将源码路径和构建路径分开(也就是生成的makefile文件和其他产物都不放到源码路径),以此来保证源码路径的清洁. 这不是qmake ...

  9. Handler机制原理图、源码、使用!!!!!

    android的消息处理机制——Looper,Handler,Message  (原理图.源码) 转自:http://my.oschina.net/u/1391648/blog/282892 在开始讨 ...

  10. 如何优化pom依赖项?

    Maven工程通过pom.xml里的<dependency>来定义依赖项.当然,我们不会少定义依赖项,否则编译不通过.不过,如果我们多定义了依赖项虽然不会造成灾难,但可能会造成一些问题,比 ...