大家好我是Miko,今天给大家总结一下Android 中UI界面刷新以及多线程技术实现的几个方法。
我们都知道,Android所采用的是UI单线程模式,UI操作只能在主线程中进行;而为了提高用户体验Google规定耗时的操作不允许在主线程中进行,因此在程序中更新数据等耗时操作必须在子线程中进行,这样就要求两个线程之间进行数据通信。
程序中的耗时操作是在网上下载一个图片并显示在ImageView中,我将采用三种不同的方法实现UI的刷新,如有错误还请大神们指正。
首先上Github网址 https://github.com/MikoGodZd/HttpTest.git
- Handler + Thread
- AsynacTask异步操作
- runOnUIThread
一、Handler+Thread
这是最经典的线程间通讯的方法,不熟悉Handler消息机制的朋友可以参考一下这篇文档:
Android知识梳理:消息机制之Handler:http://gqdy365.iteye.com/blog/2148925
Android知识梳理:消息机制之Looper :http://gqdy365.iteye.com/blog/2137494
- 优点:功能定义明确,多个异步操作时简单。
- 缺点:单个异步操作时臃肿
首先我们在主线程中new一个Handler
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//这里是进行的更新UI操作
iv.setImageBitmap(bm);
}
};
然后我们实现一个Runnable接口
Runnable Get = new Runnable() {
@Override
public void run() {
//这里是耗时操作
GetPicture("http://www.pp3.cn/uploads/allimg/111111/10142UL5-3.jpg");
Message msg = new Message();
MainActivity.this.handler.sendMessage(msg);
}
};
最后在onCreate中开辟新的线程并运行
btHandler.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(Get).start();
}
});
二、AsynacTask异步操作
AsyncTask,是android提供的轻量级的异步类,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.
新手朋友请参考http://www.cnblogs.com/devinzhang/archive/2012/02/13/2350070.html
- 优点:简单快捷,过程可控
缺点:多个异步操作时,易发生不可控错误
在AsynacTask中我们至少重写两个方法
doInBackground(Params…) 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。
- onPostExecute(Result) 相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回
ok我们创建一个新的class类
class AsynacGet extends AsyncTask {
String url;
AsynacGet(String url){
this.url=url;
}
@Override
protected Object doInBackground(Object[] params) {
//这里进行耗时操作
GetPicture(url);
return null;
}
@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
//这里更新操作
iv.setImageBitmap(bm);
}
}
然后在onCreate中执行
btAsy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AsynacGet asy = new AsynacGet("http://img02.tooopen.com/images/20160216/tooopen_sy_156324542564.jpg");
asy.execute();
}
});
三、runOnUiThread
名字很直白的一个方法=_=+/// 这个方法开启一个新的线程
与第一种方法类似,先实现Runnable接口
Runnable RunOn =new Runnable() {
@Override
public void run() {
GetPicture("http://img5.imgtn.bdimg.com/it/u=876917683,706781518&fm=11&gp=0.jpg");
runOnUiThread(new Runnable() {
@Override
public void run() {
//这里是ui操作
iv.setImageBitmap(bm);
}
});
}
};
同样最后在onCreate中开启线程
btRunOn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(RunOn).start();
}
});
ok以上就是三种方法,大牛们勿喷
博主大二狗,未开Java自学Android 有志同道合兄弟加q 136057505 =-=