Android 关于操作UI线程
在非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 如何作用的快速的总览:
- 你可以具体设置参数的类型,进度值,任务的终值,使用的范型
doInBackground()方法自动在 worker 线程执行onPreExecute(),onPostExecute(), 和onProgressUpdate()方法都是在UI线程被调用doInBackground()的返回值会被送往onPostExecute()方法- 你可以随时在
doInBackground()方法里面调用publishProgress()方法来执行UI 线程里面的onProgressUpdate()方法 - 你可以从任何线程取消这个任务
注意: 你在使用worker线程的时候可能会碰到的另一个问题就是因为runtime configuration change (比如用户改变了屏幕的方向)导致你的activity不可预期的重启,这可能会kill掉你的worker线程。为了解决这个问题你可以参考 Shelves 这个项目。
线程安全的方法
在某些情况下,你实现的方法可能会被多个线程所调用,因此你必须把它写出线程安全的。
转自:http://greenrobot.me/devpost/android-thread-and-process/
Android 关于操作UI线程的更多相关文章
- Android 操作UI线程的一些方法
我们经常会在后台线程中去做一些耗时的操作,比如去网络取数据.但是当数据取回来,需要显示到页面上的时候,会遇到一些小麻烦,因为我们都知道,android的UI页面是不允许在其他线程直接操作的.下面总结4 ...
- android 在非UI线程更新UI仍然成功原因深入剖析
”只能在UI主线程中更新View“. 这句话很熟悉吧? 来来,哥们,看一下下面的例子 @Override protected void onCreate(Bundle savedInsta ...
- Android 高级UI设计笔记17:Android在非UI线程中显示Toast
1. 子线程的Toast怎么显示不出来? 因为Toast在创建的时候会依赖于一个Handler,并且一个Handler是需要有一个Looper才能够创建,而普通的线程是不会自动去创建一个Looper对 ...
- Android在非UI线程中更新UI的方法
1.使用Thread+Handler实现非UI线程更新UI界面 在UI Thread中创建Handler.用sendMessage(message)或者obtainMessage(result, ob ...
- Android中进程与线程及如何在子线程中操作UI线程
1. Android进程 一个应用程序被启动时,系统默认创建执行一个叫做"main"的线程.这个线程也是你的应用与界面工具包(android.widget和android.view ...
- Android 实战之UI线程和Worker线程交互
哈哈,博文取了个比较霸气的名字,大家不都喜欢这样忽悠人吗 呵呵! 好了,现在就是很简单的点击查询,然后这个查询有点花时间,不想见面出现假死现象,所以在另外的线程进行查询. 好了,代码在此: packa ...
- Android允许在UI线程中使用网络访问
StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode ...
- Android UI线程和非UI线程
Android UI线程和非UI线程 UI线程及Android的单线程模型原则 当应用启动,系统会创建一个主线程(main thread). 这个主线程负责向UI组件分发事件(包括绘制事件),也是在这 ...
- Android中UI线程与后台线程交互设计的5种方法
我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一 些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必 ...
随机推荐
- POJ 2594 - Treasure Exploration
一个星球上有很多点,点与点之间有很多单向路 问可重点的最小路径覆盖 利用floyd缩点后求二分图最大匹配 #include <iostream> #include <cstdio&g ...
- PO VO DAO DTO BO TO概念与区别
O/R Mapping 是 Object Relational Mapping(对象关系映射)的缩写.通俗点讲,就是将对象与关系数据库绑定,用对象来表示关系数据.在O/R Mapping的世界里,有两 ...
- js 去掉字符串最后一个字符
var str = str.substring(0,str.length-1); alert(str); 注:length 需小写.
- Fragment与Activity
一个Fragment的实例总是和包含它的Activity直接相关. fragment可以通过getActivity() 方法来获得Activity的实例,然后就可以调用一些例如findViewById ...
- windows下安装配置Xampp
XAMPP是一款开源.免费的网络服务器软件,经过简单安装后,就可以在个人电脑上搭建服务器环境.本文为大家介绍Windows中安装XAMPP(Apache+Mysql+PHP)及使用方法及其相关问题的总 ...
- 在WPF中自定义你的绘制(五)
原文:在WPF中自定义你的绘制(五) 在WPF中自定义你的绘制(五) ...
- 简单方便又实用的在线作图工具:ProcessOn
说到Visio大家都不陌生,虽然没有Word那么火,但很多业内朋友都在用,一用就是好多年,Visio是相对比较传统和专业的工具,新手在没人指导的情况下一般很难上手,下载和安装以及“授权”都是个问题,很 ...
- 必学100个常用linux命令大全
1,echo “aa” > test.txt 和 echo “bb” >> test.txt //>将原文件清空,并且内容写入到文件中,>>将内容放到文件的尾部 2 ...
- __declspec(dllimport)的作用
是时候总结一下__declspec(dllimport)的作用了.可能有人会问:__declspec(dllimport)和__declspec(dllexport)是一对的,在动态链接库中__dec ...
- python图片小爬虫
import re import urllib import os def rename(name): name = name + '.jpg' return name def getHtml(url ...