子线程更新UI界面的2种方法
一、一般我们都会在子线程完成一些耗时的操作。
1、Android中消息机制:

2、知识点:
Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。
Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。
MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。
Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。
Thread:线程,负责调度整个消息循环,即消息循环的执行场所。
子线程更新uI界面方法一:用Handler
1、我们将在上张AsyncTask的案例中进行操作,我们将之前点击调用事件中的调用方法注释。
public class MainActivity extends Activity {
private SimpleAdapter sa;
private Button btn;
private TextView tv;
private List<Userinfos> list=new ArrayList<Userinfos>();
private BaseAdapter adapter;
private ListView lv;
private Runnable doInBackground1;
private Runnable doInBackground2;
private Runnable doInBackground3;
private Handler handler;
private Thread th;
private Thread th2;
@Override
protected void onCreate(Bundle savedInstanceState) {
//这里是UI主线程
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (int i = 0; i < 5; i++) {
Userinfos u = new Userinfos();
u.setName("小明"+i);
u.setSex("男"+i);
list.add(u);
}
lv=(ListView)this.findViewById(R.id.listView1);
tv=(TextView)findViewById(R.id.textView1);
btn=(Button)findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener(){
//模拟数据访问产生数据
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
/*Take tk=new Take(MainActivity.this);//同步任务
tk.execute(list,adapter);//参数是传给doInBackground*/
Thread t1=new Thread(doInBackground1);
t1.start();
Thread t2=new Thread(doInBackground2);
t2.start();
Thread t3=new Thread( doInBackground3);
t3.start();
}});
handler=new Handler()
{
public void handleMessage(android.os.Message msg)
{
int what=msg.what;
Log.i("handler","已经收到消息,消息what:"+what+",id:"+Thread.currentThread().getId()); if(what==1)
{
Log.i("handler已接受到消息",""+what);
tv.setText("子线程一");
}
if(what==2)
{
Log.i("handler已接受到消息",""+what);
adapter.notifyDataSetChanged(); }
if(what==3)
{
Log.i("handler已接受到消息",""+what);
adapter.notifyDataSetChanged();
btn.setText("子线程三");
}
};
};
//子线程一
doInBackground1=new Runnable(){ @Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//1.访问数据库或者互联网,不在UI进程,所以不卡
Message msg=new Message();
//对消息一个识别号,便于handler能够识别
msg.what=1;
handler.sendMessage(msg);
Log.i("dd","子线程一已发送消息给handler");
}};
//子线程二
doInBackground2=new Runnable(){ @Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Message mge=new Message();
mge.what=2;
handler.sendMessageDelayed(mge,200);
for(Userinfos us:list)
{
us.setName("李丽");
}
Log.i("dd","子线程二已发送消息给handler"); }};
//子线程三
doInBackground3=new Runnable()
{ @Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(9000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Message mge=new Message();
mge.what=3;
handler.sendMessageDelayed(mge,200);
for(Userinfos us:list)
{
us.setSex("女");
}
Log.i("dd","子线程三已发送消息给handler"); }};
1、子线程发消息,通知Handler完成UI更新:
2、Handler的handleMessage方法进行消息处理,接收到消息进行UI界面更新。
注:方法一的Handler对象必须定义在主线程中,如果是多个类直接互相调用,就不是很方便,需要传递content对象或通过接口调用。
效果图:

子线程更新uI界面方法二:用用Activity对象的runOnUiThread方法更新
通过runOnUiThread方法进行UI界面更新
public void onClick(View v) {
// TODO Auto-generated method stub
/*Take tk=new Take(MainActivity.this);//同步任务
tk.execute(list,adapter);//参数是传给doInBackground*/
/*Thread t1=new Thread(doInBackground1);
t1.start();
Thread t2=new Thread(doInBackground2);
t2.start();
Thread t3=new Thread( doInBackground3);
t3.start();*/
th.start();
th2.start();
}});
th= new Thread()
{
@Override
public void run() {
//这儿是耗时操作,完成之后更新UI;
runOnUiThread(new Runnable()
{
//更新UI
@Override
public void run() {
// TODO Auto-generated method stub
btn.setText("runOnUiThread子线程一");
} });
super.run();
}
};
th2=new Thread()
{
public void run()
{
runOnUiThread(new Runnable()
{
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub
tv.setText("runOnUiThread子线程二");
} }); }; };
1、通过runOnUiThread方法New 一个Runnable实现run方法进行UI界面更新。
如果在非上下文类中(Activity),可以通过传递上下文实现调用;
效果图片:

子线程更新UI界面的2种方法的更多相关文章
- Android中使用异步线程更新UI视图的几种方法
在Android中子线程是不能更新ui的. 所以我们要通过其他方式来动态改变ui视图, 1.runOnUiThreadactivity提供的一个轻量级更新ui的方法,在Fragment需要使用的时候要 ...
- Android通过子线程更新UI的几种方式
一般情况下,UI的更新都少不了Handler,首先我们先了解一下Handler机制: Handler消息机制 定义 Message 线程间通信的数据单元,可通过message携带需要的数据创建对象:M ...
- OkHttp3几个简单的例子和在子线程更新UI线程的方法
okHttp用于android的http请求.据说很厉害,我们来一起尝尝鲜.但是使用okHttp也会有一些小坑,后面会讲到如何掉进坑里并爬出来. 首先需要了解一点,这里说的UI线程和主线程是一回事儿. ...
- Android开发——实现子线程更新UI
Android中线程按功能分的话,可以分为两个,一个是主线程(UI线程),其他的都是子线程 主线程不能执行那些耗时过长的代码或任务(执行耗时过长的代码会出现应用未响应的提示),所以都是使用子线程来执行 ...
- Python+PyQT5的子线程更新UI界面的实例《新手必学》
今天小编就为大家分享一篇Python+PyQT5的子线程更新UI界面的实例,具有很好的参考价值,希望对大家有所帮助.一起跟随小编过来看看吧子线程里是不能更新UI界面的,在移动端方面.Android的U ...
- Android子线程更新UI的方法总结
版权声明:本文为博主原创文章,转载请注明出处:https://i.cnblogs.com/EditPosts.aspx?postid=6121280 消息机制,对于Android开发者来说,应该是非常 ...
- Android可以子线程更新UI?
初了解Android的时候,就知道Android是不能在子线程更新UI的,不然程序会直接抛出异常,告诉你,别给我在自线程搞事情! 但是,这个是针对普通的view做的限制,而TextureView,Su ...
- android子线程更新UI
参考:https://www.cnblogs.com/joy99/p/6121280.html 子线程是不能直接更新UI的.Android实现View更新有两组方法,分别是invalidate和pos ...
- [Android学习笔记]子线程更新UI线程方法之Handler
关于此笔记 不讨论: 1.不讨论Handler实现细节 2.不讨论android线程派发细节 讨论: 子线程如何简单的使用Handler更新UI 问题: android开发时,如何在子线程更新UI? ...
随机推荐
- ng2 配置端口号
ng2 默认端口号4200 若要配置,用两种方法 (1)可以使用以下命令 ng server --port 4201 (2)找到node_modules/angular-cli/lib/confi ...
- iOS利用xcodebuild命令自动打包方法
1,xcode项目先打包试一下可以打包成功 2,创建一plist导出文件 3,xcodebuild命令直接运行 导出文件内容: <?xml version="1.0" enc ...
- python 列表、元组
列表 List(列表) 是 Python 中使用最频繁的数据类型. 列表可以完成大多数集合类的数据结构实现.它支持字符,数字,字符串甚至可以包含列表(即嵌套). 列表用 [ ] 标识,是 python ...
- 【oracle】ORA-02289: sequence does not exist
select * from user_sequences where sequence_name = 'NLDP_LGIR_BASE_SEQUENCE'; 通过该指令查看SEQUENCE是否存在
- Mesh内存分配器的mmap小技巧
最近看了一篇内存分配器的论文,原理很简单,但是里面的数学论证还没看懂,这次先简单写一下原理和用到的API. 内存分配器是用于封装操作系统提供的底层API,给应用程序提供动态内存的.内存不断申请释放后, ...
- python类的语法和底层实现
语法: class 类名: name = “egon” # 类属性 def __init__(self): self.age = 18 # 对象属性 self.__sex = "fe ...
- 部署springboot工程到linux上及遇到的坑
一.步骤 1.将工程打成jar包 IDEA中点击file-project structure,如下图: 选择Artifacts-JAR-From modules,选择入口类Main Class,如下图 ...
- jquery 禁止回车事件响应
$(this).keydown( function(e) { var key = window.event?e.keyCode:e.which; if(key.toString() == " ...
- springCloud、springBoot学习
http://projects.spring.io/spring-cloud/ 官网https://springcloud.cc/spring-cloud-netflix.htmlhttp://cl ...
- Spock - Document -04- Interaction Based Testing
Interaction Based Testing Peter Niederwieser, The Spock Framework TeamVersion 1.1 Interaction-based ...