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线程中运行,像访问网络就属于这类任务.因此我们必 ...
随机推荐
- Windows环境搭建Red5流媒体服务器指南(转)
Windows环境搭建Red5流媒体服务器指南 Windows环境搭建Red5流媒体服务器指南 测试环境:Windows 7 一. 下载安装程序 red5-server 下载地址 https:// ...
- 【Android类型SDK测试(一)】认识Android类型的 SDK
(一)SDK是个什么东东 接触软件相关行业的同学都应该知道,SDK(即 Software Development Kit),软件开发包.其作用就是为开发某些软件提供一些便利的东西,包括工具 集合,文档 ...
- ORACLE DUAL表详解 .
今天在戴明明同学的QQ空间里看到篇不错的关于DUAL表的文章,自己平时也时而会用到,可是没有系统的学习过,借这个机会学习学习~ ==================================== ...
- java压缩/解压缩zip格式文件
因为项目要用到压缩.解压缩zip格式压缩包,只好自己封装一个,对于网上流行的中文乱码的问题,本文的解决方法是用apache的包代替jdk里的.基本上还是比较好用的. 废话少说,直接上代码. } ...
- Sublime Text 3 个人配置文件
{ "dpi_scale": 1.0, "draw_white_space": "selection", "fallback_en ...
- Python中yield深入理解
众所周知,python中的yield有这样的用法: def test(alist): for i in alist: yield i 这样,这个test函数就变成了一个生成器,当每次调用的时候,就会自 ...
- Oracle EBS-SQL (QA-1):检查超出检验周期的检验数据.sql
select msi.segment1 物料编码, msi.DESCRIPTION ...
- 浅谈 qmake 之 shadow build(就是将源码路径和构建路径分开)
shadow build shadow build 是什么东西?就是将源码路径和构建路径分开(也就是生成的makefile文件和其他产物都不放到源码路径),以此来保证源码路径的清洁. 这不是qmake ...
- Handler机制原理图、源码、使用!!!!!
android的消息处理机制——Looper,Handler,Message (原理图.源码) 转自:http://my.oschina.net/u/1391648/blog/282892 在开始讨 ...
- 如何优化pom依赖项?
Maven工程通过pom.xml里的<dependency>来定义依赖项.当然,我们不会少定义依赖项,否则编译不通过.不过,如果我们多定义了依赖项虽然不会造成灾难,但可能会造成一些问题,比 ...