现在需要实现一个工具类,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的更多相关文章

  1. android Activity runOnUiThread() 方法的使用

    利用Activity.runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,然后在需要更新ui时,把这个Runnable对象传给Activity.runOnUiThr ...

  2. android Activity runOnUiThread() 方法使用

    在android 中我们一般用 Handler 做主线程 和 子线程 之间的通信 . 现在有了一种更为简洁的写法,就是 Activity 里面的 runOnUiThread( Runnable )方法 ...

  3. 我的Android最佳实践之—— Android更新UI的两种方法:handler与runOnUiThread()

    在Android开发过程中,常需要更新界面的UI.而更新UI是要主线程来更新的,即UI线程更新.如果在主线线程之外的线程中直接更新页面 显示常会报错.抛出异常:android.view.ViewRoo ...

  4. Android更新UI的两种方法——handler与runOnUiThread()

    在Android开发过程中,常需要更新界面的UI.而更新UI是要主线程来更新的,即UI线程更新.如果在主线线程之外的线程中直接更新页面 显示常会报错.抛出异常:android.view.ViewRoo ...

  5. 使用runOnUiThread更新UI

    android中更新UI的方式比较多,这里就不一一介绍了,比较常用的Thread+Handler,但是这种方式较繁琐,如在使用ProgressDialog创建进度对话框一文中就是使用的这种方式更新UI ...

  6. Android更新主线程UI的两种方式handler与runOnUiThread()

    在android开发过程中,耗时操作我们会放在子线程中去执行,而更新UI是要主线程(也叫做:UI线程)来更新的,自然会遇到如何更新主线程UI的问题.如果在主线程之外的线程中直接更新页面显示常会报错.抛 ...

  7. 理解Activity.runOnUiThread()

    这是一篇译文(中英对照),原文链接:Understanding Activity.runOnUiThread() When developing Android applications we alw ...

  8. 19 子线程刷新UI runOnUiThread

    package com.example.com.fmyh; import java.io.BufferedReader; import java.io.File; import java.io.Fil ...

  9. runOnUiThread更新主线程

    更新UI采用Handle+Thread,需要发送消息,接受处理消息(在回调方法中处理),比较繁琐.除此之外,还可以使用runOnUiThread方法.   利用Activity.runOnUiThre ...

随机推荐

  1. Django 配置文件settings注解(含静态文件和上传文件配置)

    基于Django1.11配置文件settings.py import os import sys # Build paths inside the project like this: os.path ...

  2. 使用VSTS的Git进行版本控制(三)——评审历史记录

    使用VSTS的Git进行版本控制(三)--评审历史记录 Git使用存储在每个提交中的父引用信息来管理开发的完整历史记录.评审该提交历史记录,能够找出文件更改的时间,并确定代码版本之间的差异. Git使 ...

  3. ERP口碑订单无法落桌的解决方法

    第一步,退出ERP 第二步,打开控制面板卸载erp 第三步,删除erp安装路径的所有文件 第四步,卸载sql服务,操作方法如下(win+R—输入cmd—输入sc delete mysql_sl 回车键 ...

  4. 【mongoDB高级篇③】综合实战(1): 分析国家地震数据

    数据准备 下载国家地震数据 http://data.earthquake.cn/data/ 通过navicat导入到数据库,方便和mysql语句做对比 shard分片集群配置 # step 1 mkd ...

  5. SQL中常用日期函数

    --1 GETDATE() 返回当前系统日期SELECT GETDATE() --2 DATEADD(日期部分,常数,日期) 返回将日期的指定日期部分加常数后的结果返回 日期部分可以是: --常数为正 ...

  6. Python赋值运算符

    赋值运算符 运 算 符  说 明 举 例   展 开 形 式  =   简单的赋值运算  x=y x=y  +=  加赋值 x+=y  x=x+y -=  减赋值 x-=y  x=x-y   *= 乘 ...

  7. c/c++ 用普利姆(prim)算法构造最小生成树

    c/c++ 用普利姆(prim)算法构造最小生成树 最小生成树(Minimum Cost Spanning Tree)的概念: ​ 假设要在n个城市之间建立公路,则连通n个城市只需要n-1条线路.这时 ...

  8. Linux学习历程——Centos 7 man命令

    一.man命令介绍 man,为单词manual的缩写,是linux下的帮助指令. 二.实例 以man命令为例,输入 man  man  获取man命令的帮助文档 可以看出,使用man命令查询到的帮助信 ...

  9. Stopwatch + C#打印日志方法

    打印一个接口.方法的运行时间在程序中是很容易遇到的一件事情:现在,我就分享一个我在工作中使用的临时打印日志的方法和结合 Stopwatch 打印测量某个时间间隔的运行时间的方法. Stopwatch ...

  10. C语言 矩阵的转置及矩阵的乘法

    C语言 矩阵的转置及矩阵的乘法 //凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1.矩阵的转置 #include<stdio.h> #defi ...