子线程更新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? ...
随机推荐
- 作为程序员你不知道中国互联网300强你就OUT了!
很多程序员们工作一段时间之后,都想跳槽到综合实力更强的公司以获取高薪资或者接触到前沿的技术,但是哪些行业值得我们投入大量的时间,哪些公司属于我们行业中的佼佼者呢, 那么小编给您分析下2018年中国互联 ...
- phoneshop cs6破解
一.以“试用”方式安装photoshop: 二.下载amtlib.dll破解文件,密码:ubx2: 三.备份photoshop目录下的amtlib.dll文件,将下载的amtlib.dll文件拷贝到p ...
- Failed to load ApplicationContext ,Error creating bean with name 'adminUserService': Injection of autowired dependencies failed;
Druid配置的时候出现这个问题: "C:\Program Files\Java\jdk1.8.0_191\bin\java" -ea -Didea.test.cyclic.buf ...
- Spring Security框架下Restful Token的验证方案
项目使用Restful的规范,权限内容的访问,考虑使用Token验证的权限解决方案. 验证方案(简要概括): 首先,用户需要登陆,成功登陆后返回一个Token串: 然后用户访问有权限的内容时需要上传T ...
- Good Time 冲刺四
---恢复内容开始--- 一.今日完成任务情况及遇到的问题 第四天 日期:2018.6.17 王怡镔:在学习工程中,逐步完善个人中心界面的设计和编写. 于鑫宇:对小程序内容进行一些修改,复习了昨天学过 ...
- web过滤器
Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 ht ...
- Android DrawerLayout侧滑菜单
本教程已经录制视频,欢迎大家观看我在CSDN学院录制的课程:http://edu.csdn.net/lecturer/944
- mininet的学习之二-----miniedit可视化
安装ryu git clone git://github.com/osrg/ryu.git cd ./ryu sudo python setup.py install mininet可视化 git ...
- Mysql主外键
主键 primary key 创建表时直接加上主键: create table student1(id int primary key, name varchar(20), age int, g ...
- 网络操作基础(one)
P12 一.什么是网络操作系统?网络操作系统具有哪些基本功能? 二.网络操作系统具有哪些特征? 三.常用的网络操作系统有哪些?它们各具有什么特点? 四.在网络操作系统中主要可提供哪些? ———— —— ...