Android只会存在两种线程:UI主线程(UI thread)和工作线程(work thread).
我们知道Android的UI主线程主要负责处理用户的按键事件、用户的触屏事件以及屏幕绘图事件等,在子线程中处理耗时的任务,任务完成后通过Handler通知UI主线程更新UI界面
注意:
不能阻塞UI主线程,也就是不能在UI主线程中做耗时的操作,如网络连接,文件的IO;
只能在UI主线程中做更新UI的操作;
ANR:
anr:application not reponse:应用程序无响应
主线程:UI线程
anr产生的原因:主线程需要做很多重要的事情,响应点击事件,更新ui,如果在主线程里面阻塞时间过久,应用程序就会无响应,为了避免应用程序出现anr,所有的耗时的操作,都应该放在子线程中执行。
1、使用线程处理 耗时比较长的“业务”
有以下几种方式:
1)Activity.runOnUiThread(Runnable)
2)View.post(Runnable) ;View.postDelay(Runnable , long)
3)Handler
4)AsyncTask
2、使用方法举例
1)Activity.runOnUiThread(Runnable)
采用runOnUiThread(new Runnable()),这要实现Runnable借口,我们可以直接在这个线程中进行UI的更新。是api提供的方法,较为便捷。
new Thread(){
@Override
public void run() {
final String result = LoginServices.loginByGet(username, password);
if(result != null){
//成功
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, result, 0).show();
}
});
}else{
//请求失败
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "请求失败", 0).show();
}
});
}
};
}.start();
handler.post(r)其实这样并不会新起线程,只是执行的runnable里的run()方法,却没有执行start()方法,所以runnable走的还是UI线程。
如果像这样,是可以操作ui,但是run还是走在主线程,见打印出来的Log线程名字是main,说明是主线程。
这就是为什么可以直接在run方法里操作ui,因为它本质还是ui线程
handler.post(new Runnable(){
public void run(){
Log.e("当前线程:",Thread.currrentThread.getName());//这里打印de结果会是main
setTitle("哈哈");
}
});
3)Handler
Thread与Handler组合,比较常见
这里在加载100张图片,然后没加载完成一个用handler 返回给UI线程一张图片并显示,最后加载完成返回一个List给UI线程 ,Handler就是一个后台线程与UI线程中间的桥梁
package com.android.wei.thread;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class Activity01 extends Activity {
/** Called when the activity is first created. */
/**读取进度**/
public final static int LOAD_PROGRESS =0;
/**标志读取进度结束**/
public final static int LOAD_COMPLETE = 1;
/**开始加载100张图片按钮**/
Button mButton = null;
/**显示内容**/
TextView mTextView = null;
/**加载图片前的时间**/
Long mLoadStart = 0L;
/**加载图片完成的时间**/
Long mLoadEndt = 0L;
Context mContext = null;
/**图片列表**/
private List<Bitmap> list;
/**图片容器**/
private ImageView mImageView;
//接受传过来得消息
Handler handler = new Handler(){
public void handleMessage(Message msg){
switch(msg.what){
case LOAD_PROGRESS:
Bitmap bitmap = (Bitmap)msg.obj;
mTextView.setText("当前读取到第"+msg.arg1+"张图片");
mImageView.setImageBitmap(bitmap);
break;
case LOAD_COMPLETE:
list = (List<Bitmap>) msg.obj;
mTextView.setText("读取结束一共加载"+list.size()+"图片");
break;
}
super.handleMessage(msg);
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.main);
mButton =(Button) findViewById(R.id.button1);
mTextView=(TextView) findViewById(R.id.textView1);
mImageView =(ImageView) this.findViewById(R.id.imageview);
mTextView.setText("点击按钮加载图片");
mButton.setOnClickListener(new OnClickListener(){
public void onClick(View v){
//调用方法
LoadImage();
}
});
}
public void LoadImage(){
new Thread(){
public void run(){
mLoadStart = System.currentTimeMillis();
List<Bitmap> list = new ArrayList<Bitmap>();
for(int i =0;i<100;i++){
Bitmap bitmap=ReadBitmap(mContext,R.drawable.icon);
Message msg = new Message();
msg.what = LOAD_PROGRESS;
msg.arg1 = i+1;
list.add(bitmap);
msg.obj = bitmap;
handler.sendMessage(msg);
}
mLoadEndt = System.currentTimeMillis();
Message msg =