handler 主要用于主线程和子线程的通信,因为系统默认只有主线程才能执行更改UI组件的任务,假如在子线程里更改UI组件,就会报错。
假如要在子线程里更新UI组件,就要用到 Handler 进行通信,在线程里将数据放在Message对象里,然后发送Message到Handler上,然后在主线程获取消息对象,然后进行UI组件的更新。下面贴代码。
1.子线程往主线程发消息:
在主线程里生成Handler类,并重写handleMessage方法。在子线程里通过handler的obtainMessage方法获得消息对象,将数据放在Message对象里。然后在主线程的handleMessage方法里 处理消息,执行UI组件更新。
package com.example.tset_handler;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
private Button myButton = null;
private myHandler myhandler = null;
private TextView myText = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myButton = (Button)findViewById(R.id.myButton);
myText = (TextView)findViewById(R.id.mytext);
myhandler = new myHandler();
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
myThread t = new myThread();
t.start();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
class myHandler extends Handler{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
System.out.println(msg.arg1);
}
}
class myThread extends Thread{
public void run(){
Message msg = myhandler.obtainMessage();
msg.arg1=2;
myhandler.sendMessage(msg);
}
}
}
2.主线程往子线程发消息:
与1不同,这种情况,是在子线程里生成handler类,并在子线程里调用handleMessage方法。在主线程里 放入数据,然后在子线程里处理数据。
还有要注意的是,在子线程,必须先调用Looper.prapre()方法,生成looper对象,然后才能循环读取消息。最后调用Loop.loop()方法形成循环。
代码如下。
package com.example.test_handler2;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends ActionBarActivity {
private Button myButton = null;
private Handler handler = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myButton=(Button)findViewById(R.id.myButton);
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Message msg = handler.obtainMessage();
msg.arg1=1;
handler.sendMessage(msg);
}
});
System.out.println("2222222222222222");
myThread t = new myThread();
t.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
class myThread extends Thread{
public void run(){
Looper.prepare();
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
System.out.println(msg.arg1);
}
};
Looper.loop();
}
}
}