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线程中运行,像访问网络就属于这类任务.因此我们必 ...
随机推荐
- thinkPHP入门 一
简介 ThinkPHP是一个快速.简单的基于MVC和面向对象的轻量级PHP开发框架,遵循Apache2开源协议发布,从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,尤其注重开 ...
- Spring MVC一个方法适用多种调用方式
web.xml spring-mvc.xml <mvc:annotation-driven /> <context:component-scan base-package=" ...
- SQLServer 2012 可视化窗口中,设置“时间”默认值为“当前时间"
最近,需要在SQLServer 2012中,设置datetime的默认值为当前时间. 通过可视化窗口进行设置,而不是将getdate()函数写在sql语句中,也不是将‘2022-2-2 22:22:2 ...
- DTS结构及其编译方法
一.主要问题1,需要了解dtsi与dts的关系2,dts的结构模型3,dts是如何被编译的,以及编译后会生成一个什么文件. 二.参考文字1,DTS(device tree source).dts文件是 ...
- 【CKEditor ASP.NET】解决360安全浏览器极速模式下不显示
博主问题只是出在误删了style.js文件 首先我用的是这种模式,在单个页面上导入: <%@ Register Assembly="CKEditor.NET" Namespa ...
- Callable,Runnable比较及用法
http://blog.csdn.net/xtwolf008/article/details/7713580 http://www.cnblogs.com/whgw/archive/2011/09/2 ...
- js的体会
关于观察者模式的核心是: 回调函数, 传递函数名作为参数,或者是传递变量,然后调用其函数名. 关于闭包的核心是 闭包的函数是全局变量之下的函数, 而非闭包的函数是局部变量. <script> ...
- 厂商自定义USB设备固件程序及特性
通过前面的学习,大家应该对USB固件程序结构有了比较深的认识,现在再来详细说说固件里决定设备识别成厂商自定义USB设备的地方有哪些,或者说厂商自定义USB设备的固件特性有哪些. 之前不止一次说过学习U ...
- lamp apache配置虚拟主机
You don't have permission to access /index.php on this server
- 【csdn】文章很好 - system函数遇到的问题
system函数遇到的问题http://blog.csdn.net/yangzhenzhen/article/details/51505176