实现RunOnUiThread和RunOnUiThreadBlock
现在需要实现一个工具类,RunUtils,这个类中包含runOnUiThread(Context context, Runnable runnable)和runOnUiThreadBlock(Context context, Runnable runnable)两个方法。两个方法都使runnable在UI线程执行,runOnUiThread立即返回,runOnUiThreadBlock等待runnable执行完毕后才返回。
根据context创建一个Handler,这个Handler用于发送消息。runOnUiThread这个方法不需要同步,runOnUiThreadBlock需要同步。
RunUtils内容
package com.letv.handlertest; import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log; import java.lang.ref.WeakReference; public class RunUtils { private static final int WHAT_BLOCK = 0x1001; private static WeakReference<Context> weakContext;
private static WeakReference<Handler> weakHandler;
private static Object lock = new Object(); private static void init(Context context){
if(RunUtils.weakContext == null ||
(RunUtils.weakContext!=null && RunUtils.weakContext.get()!=context) ){
RunUtils.weakContext = new WeakReference<Context>(context); Handler handler = new Handler(context.getMainLooper()) {
@Override
public void dispatchMessage(Message msg) {
if(msg.what == WHAT_BLOCK){
Log.i(MainActivity.TAG, "what block");
synchronized (lock){
super.dispatchMessage(msg);
lock.notify();
Log.i(MainActivity.TAG, "notify");
}
}
else{
super.dispatchMessage(msg);
Log.i(MainActivity.TAG, "what not block");
}
}
};
weakHandler = new WeakReference<Handler>(handler);
handler = null;
}
} public static void runOnUiThread(Context context, Runnable runnable){
init(context);
weakHandler.get().post(runnable);
Log.i(MainActivity.TAG, "run ui over!");
} public static void runOnUiThreadBlock(Context context, Runnable runnable){
init(context); Message msg = Message.obtain(weakHandler.get(), runnable);
msg.what = WHAT_BLOCK;
msg.sendToTarget(); synchronized (lock){
Log.i(MainActivity.TAG, "begin wait!");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(MainActivity.TAG, "run ui block over!");
}
} }
主类MainActivity内容
package com.letv.handlertest; import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends Activity implements View.OnClickListener { public static final String TAG = "HandlerTest"; private Button btnRunOnUiThread, btnRunOnUiThreadBlock;
private TextView tvShow1, tvShow2;
// private RunUtilsB utils; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView(); // utils = new RunUtilsB(this);
} private void initView(){
btnRunOnUiThread = (Button)findViewById(R.id.btnRunOnUiThread);
btnRunOnUiThreadBlock = (Button)findViewById(R.id.btnRunOnUiThreadBlock);
tvShow1 = (TextView)findViewById(R.id.tvShow1);
tvShow2 = (TextView)findViewById(R.id.tvShow2); btnRunOnUiThread.setOnClickListener(this);
btnRunOnUiThreadBlock.setOnClickListener(this);
} private void runUi(){
new Thread(new Runnable() {
@Override
public void run() {
RunUtils.runOnUiThread(MainActivity.this, new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
tvShow1.setText("run ui");
}
});
}
}).start();
} private void runUiBlock(){
new Thread(new Runnable() {
@Override
public void run() {
RunUtils.runOnUiThreadBlock(MainActivity.this, new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
tvShow2.setText("run ui block");
}
});
}
}).start();
} @Override
public void onClick(View v) {
if(v == btnRunOnUiThread){
runUi();
}
else if(v == btnRunOnUiThreadBlock){
runUiBlock();
}
}
}
运行结果正常。点击RunOnUiThread实现2s后更新textView1的值,点击调用后立马返回,点击RunOnUiThreadBlock后实现2s后更新textView2的值,更新完后才返回。
实现RunOnUiThread和RunOnUiThreadBlock的更多相关文章
- android Activity runOnUiThread() 方法的使用
利用Activity.runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,然后在需要更新ui时,把这个Runnable对象传给Activity.runOnUiThr ...
- android Activity runOnUiThread() 方法使用
在android 中我们一般用 Handler 做主线程 和 子线程 之间的通信 . 现在有了一种更为简洁的写法,就是 Activity 里面的 runOnUiThread( Runnable )方法 ...
- 我的Android最佳实践之—— Android更新UI的两种方法:handler与runOnUiThread()
在Android开发过程中,常需要更新界面的UI.而更新UI是要主线程来更新的,即UI线程更新.如果在主线线程之外的线程中直接更新页面 显示常会报错.抛出异常:android.view.ViewRoo ...
- Android更新UI的两种方法——handler与runOnUiThread()
在Android开发过程中,常需要更新界面的UI.而更新UI是要主线程来更新的,即UI线程更新.如果在主线线程之外的线程中直接更新页面 显示常会报错.抛出异常:android.view.ViewRoo ...
- 使用runOnUiThread更新UI
android中更新UI的方式比较多,这里就不一一介绍了,比较常用的Thread+Handler,但是这种方式较繁琐,如在使用ProgressDialog创建进度对话框一文中就是使用的这种方式更新UI ...
- Android更新主线程UI的两种方式handler与runOnUiThread()
在android开发过程中,耗时操作我们会放在子线程中去执行,而更新UI是要主线程(也叫做:UI线程)来更新的,自然会遇到如何更新主线程UI的问题.如果在主线程之外的线程中直接更新页面显示常会报错.抛 ...
- 理解Activity.runOnUiThread()
这是一篇译文(中英对照),原文链接:Understanding Activity.runOnUiThread() When developing Android applications we alw ...
- 19 子线程刷新UI runOnUiThread
package com.example.com.fmyh; import java.io.BufferedReader; import java.io.File; import java.io.Fil ...
- runOnUiThread更新主线程
更新UI采用Handle+Thread,需要发送消息,接受处理消息(在回调方法中处理),比较繁琐.除此之外,还可以使用runOnUiThread方法. 利用Activity.runOnUiThre ...
随机推荐
- 关于相机拍照获取图片onActivityResult返回data 为null的问题
调用相机拍摄方法 /** * capture new image */ protected void selectPicFromCamera() { if (!EaseCommonUtils.isSd ...
- PostgreSQL date_trunc() 和timestamp
timestamp 01.SELECT now()::timestamp + '1 year'; 02.SELECT now()::timestamp + '1 month'; 03.SELECT n ...
- 堆栈的应用——用JavaScript描述数据结构
栈(stack)又名堆栈,它是一种运算受限的线性表.其限制是仅允许在表的一端进行插入和删除运算.这一端被称为栈顶,相对地,把另一端称为栈底. 一.实现一个栈类Stack 基于堆栈的特性,可以用数组做线 ...
- tkinter进阶版——ttk
很长的一段时间里,我都是用tkinter进行GUI设计的,还写过一篇<tkinter模块常用参数>. 但后来慢慢地觉得,这个tkinter真的是有点丑啊. 于是,找到了现在的ttk. tt ...
- Redis常用命令【字符串】
1.启动Redis客户端 进入src目录下,执行:redis-cli启动Redis客户端 2.help 帮助 帮助命令,用来查看redis命令的使用方式 3.set 设置 3.1设置 3.2不存在才设 ...
- sqlserver——cube:多维数据集
1.cube:生成多维数据集,包含各维度可能组合的交叉表格,使用with 关键字连接 with cube 根据需要使用union all 拼接 判断 某一列的null值来自源数据还是 cube 使用G ...
- MySQL open_tables和opened_tables
官网解释参见:https://dev.mysql.com/doc/refman/5.7/en/table-cache.html 其他可供参考的文章有: 关于表限制参数的使用:https://dba.s ...
- AngularJS学习之旅—AngularJS 简介(一)
一.AngularJS 简介 1.AngularJS 是一个 JavaScript 框架. AngularJS 是一个 JavaScript 框架.它是一个以 JavaScript 编写的库.Angu ...
- c/c++ 多维数组和指针
c/c++ 多维数组和指针 知识点 1,初始化多维数组,对应代码里的test1 2,遍历多维数组,除了最内层循环外,其他所有层都必须是引用类型,对应代码里的test2 3,指针和多维数组 ,对应代码里 ...
- Windows 快捷方式(*.link)打开方式关联错误
1.Win+r 组合键打开 “运行”,输入 “regedit” 打开 注册表 2.依次打开注册表,定位到以下位置: HKEY_CURRENT_USER\SOFTWARE\MICROSOFT\WINDO ...