实现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 ...
随机推荐
- Android星球效果实现
在项目中看着这个旋转效果挺炫的,就抽取出来做个记录.主要是使用CarrouselLayout 稍微修改 CarrouselLayout代码Demo下载z地址:GitHub https://github ...
- 使用vuejs2.0和element-ui 搭建的一个后台管理界面
说明: 这是一个用vuejs2.0和element-ui搭建的后台管理界面. 相关技术: vuejs2.0:一套构建用户界面的渐进式JavaScript框架,易用.灵活.高效. element-ui: ...
- github提交代码失败
向github上面提交代码,提示代码里面有大文件,建议使用git-lfs. 1,安装git-lfs yum install git-lfs 2,配置需要追踪的打文件(由于我这里提交的是jar包) gi ...
- CSS杂谈(2)
opacity 属性设置元素的不透明级别. 语法 opacity: value|inherit; 值 描述 value 规定不透明度.从 0.0 (完全透明)到 1.0(完全不透明). i ...
- create table 使用select查询语句创建表的方法分享
转自:http://www.maomao365.com/?p=6642 摘要:下文讲述使用select查询语句建立新的数据表的方法分享 ---1 mysql create table `新数据表名` ...
- memory 监控 mysql vs percona vs maria
oracle mysql 5.7 在performance_schema 通过以下表展现内存信息.这些表实际engine为performance_schema.这些表数据实际是以数组的形式存储在内存中 ...
- HOW TO ANSWER: Tell Me About Yourself
https://biginterview.com/blog/2011/09/tell-me-about-yourself.html There are some job interview quest ...
- Hibernate 5 入门指南-基于JPA
首先创建\META-INF\persistence.xml配置文件并做简单的配置 <persistence xmlns="http://java.sun.com/xml/ns/pers ...
- C语言 统计一串字符中空格键、Tab键、回车键、字母、数字及其他字符的个数(Ctrl+Z终止输入)
//凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ #include<stdio.h> void main(){ , num=, blank=, ...
- Java同步(Synchronization)
前言 线程间的通信主要通过共享对字段的访问和对象引用字段的引用,可能会产生两种错误,线程干扰和内存一致性错误.Java的同步就是防止这些错误,但当多个线程访问同一资源会导致线程执行缓慢,甚至暂停执行. ...