在Android中,默认情况下,所有的操作都在主线程中进行,主线程负责与UI相关的事件,而用户创建的子线程,不能对UI组件进行操作。而子线程可以通过Handler来与主线程进行UI交互。
注意:在一个线程中,只能有一个Looper和一个MessageQueue,但可以有多个Handler,而且这些个Handler可以共享一个Looper和MessageQueue。
下面是例子:
public class MainActivity extends Activity {
private ImageView imageView;
private Handler handler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageview1);
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.what) {
case 1:
Bitmap bm = (Bitmap) msg.obj;
imageView.setImageBitmap(bm);// 更新UI界面的ImageView
break;
}
}
};
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
Bitmap bm = getImage("http://192.168.227.1:8080/Test/images/test.png");
Thread.sleep(2000);
Message msg = Message.obtain();
msg.what = 1;
msg.obj = bm;
handler.sendMessage(msg);// 发送消息
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
public Bitmap getImage(String path) {
Bitmap bm = null;
try {
URL url = new URL(path);// 创建URL对象
URLConnection con = url.openConnection();// 获取URL对象的连接
con.connect();// 打开连接
InputStream is = con.getInputStream();// 获取输入流
bm = BitmapFactory.decodeStream(is);// 根据输入流对象创建Bitmap对象
} catch (Exception e) {
e.printStackTrace();
}
return bm;
}
}
在上面的例子中使用子线程和主线程交互更新了UI主线程的界面。主要的原理是子线程使用主线程的Handler ,然后在子线程中向主线程发送消息。