一、介绍
1、Android为了用户体验更好,是不可以在主线程(UI线程)执行耗时任务的,那么就要在分线程执行耗时任务,但是不可以在分线程更新UI。
2、Handle 异步消息处理
Message就是在不同线程之间传递的消息,可以带上一些小的数据,用于不同线程之间交换数据,可以理解Message就是装在数据的,然后发送之后就把它放到消息队列,Looper会不停的取出消息,然后就是在handleMessage()方法内处理消息了。
注意:MessageQueue对象和Looper对象在每个线程中只会各自有一个。
3、AsyncTask
直接看代码有注释的
二、创建线程常用的方式
(1)继承Thread
class MyThread extends Thread{
@Override
public void run() {
super.run();
}
}
MyThread thread=new MyThread();
thread.start();
(2)实现Runnable接口
class MyThread implements Runnable{
@Override
public void run() {
}
}
MyThread thread=new MyThread();
new Thread(thread).start();
三、使用Handle
public class MainActivity extends Activity {
static final String TAG="MainActivity";
private Button but;
private ImageView imageView;
public static final int HANDLE_STATE=1;
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case HANDLE_STATE:
//更新UI
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
but=findViewById(R.id.but_ok);
imageView=findViewById(R.id.pothoImg);
MyThread thread=new MyThread();
new Thread(thread).start();
}
class MyThread implements Runnable{
@Override
public void run() {
//耗时任务,例如网络请求
//发送消息,其实就是发送到了消息队列,这是发送空消息。
handler.sendEmptyMessage(HANDLE_STATE);
//还可以发送带内容的消息
Message message=new Message();
message.what=HANDLE_STATE;
//使用arg1,arg2可以带上额外的整型数据
message.arg1=666;
message.arg2=777;
//还可以带上额外的对象,
message.obj=new Object();
handler.sendMessage(message);
}
}
}
四、使用runOnUiThread更新UI
原理和handle是一摸一样的,就是使用方式不同,但是我觉得没有handle容易维护。
class MyThread implements Runnable{
@Override
public void run() {
//耗时任务,例如网络请求
//跟新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
//
}
});
}
}
五、AsyncTask 异步处理,是Google给封装好的handle
/**
* 泛型第一个参数表示使用的时候传进来的参数,例如可以传URL什么的,Void表示不需要传,
* 第二个参数表示 进度的单位,例如进度条可以用整型
* 第三个参数表示doInBackground执行后可以返回的结果。
*/
class MyAsyncTask extends AsyncTask<String,Integer,Boolean>{
@Override
protected void onPreExecute() {
super.onPreExecute();
//开始做的事情
}
@Override
protected Boolean doInBackground(String... str) {
//执行耗时任务
//只是为了演示,实际会根据数据的长度循环的。
int i=0;
while(i<100){
i++;
publishProgress(i);
}
return true;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
//这里更新UI
}
@Override
protected void onPostExecute(Boolean b) {
super.onPostExecute(b);
//integer就是doInBackground中的返回值,根据状态做一些事情
}
}
使用
new MyAsyncTask().execute("www.xxxxx.sss");