现在需要实现一个工具类,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. git 入门教程之冲突合并

    如果足够幸运的话,团队成员互不影响,彼此相安无事,大家各自基于 master 分支的某个 commit 创建自己的分支,平时在分支上独立工作,等到一段时间后再合并 merge 到 master 分支, ...

  2. js 时间转字符串,转成yyyy-MM-dd HH:mm:SS格式

    // 时间转字符串,转成yyyy-MM-dd HH:mm:SS格式 function dateToStr(datetime){ var dateTime = new Date(datetime); v ...

  3. Spark之UDAF

    import org.apache.spark.sql.{Row, SparkSession} import org.apache.spark.sql.expressions.{MutableAggr ...

  4. MySQL【Delete误操作】数据恢复【转】

    前言:      操作数据库时候难免会因为“大意”而误操作,需要快速恢复的话通过备份来恢复是不太可能的,因为需要还原和binlog差来恢复,等不了,很费时.这里先说明下因为Delete 操作的恢复方法 ...

  5. Sql查询今天、本周和本月的记录(时间字段为时间戳)

    工作中遇到的问题,小结一下 查询今日添加的记录: select * from [表名] where datediff(day,CONVERT(VARCHAR(20),DATEADD(SECOND,[时 ...

  6. Android长时间定时任务实现

    在服务的onStartCommand方法里面使用AlarmManager 定时唤醒发送广播,在广播里面启动服务 每次执行startService方法启动服务都会执行onStartCommand 1.服 ...

  7. C# -- 使用XmlDocument或XDocument创建xml文件

    使用XmlDocument或XDocument创建xml文件 需引用:System.Xml; System.Xml.Linq; 1.使用XmlDocument创建xml(入门案例) static vo ...

  8. java操作elasticsearch实现组合桶聚合

    1.terms分组查询 //分组聚合 @Test public void test40() throws UnknownHostException{ //1.指定es集群 cluster.name 是 ...

  9. 18年10月份最新免费申请微软OneDrive5TB云盘超详细教程!(已亲测!)

    本人已于今天10月23日亲测,成功获取微软OneDrive5T云盘! 第一步:.打开申请链接学生版:https://signup.microsoft.com/signup?sku=student教师版 ...

  10. Spring的IOC注解开发入门2

    注解方式设置属性的值 在我们IOC基于xml属性注入的方式中有(一般推荐set方法) 构造方法注入普通值:<constructor-arg>的使用 set方法注入普通值:<prope ...