Android Handler Message 通信机制


Android UI线程更新并不是线程安全的,并且必须在UI线程中进程UI更新操作,以下面一个错误为例:

 
  1. public class MainActivity extends Activity {  
  2.   
  3.     private String title;  
  4.     private Button btn;  
  5.     private final Handler handler = new Handler(){  
  6.         @Override  
  7.         public void handleMessage(Message msg) {  
  8.             setTitle(title);  
  9.         }  
  10.     };  
  11.       
  12.     @Override  
  13.     public void onCreate(Bundle savedInstanceState) {  
  14.         super.onCreate(savedInstanceState);  
  15.         setContentView(R.layout.main);  
  16.         btn = (Button) findViewById(R.id.time);  
  17.         btn.setOnClickListener(new OnClickListener() {  
  18.             @Override  
  19.             public void onClick(View arg0) {  
  20.                  Timer timer = new Timer();  
  21.                      timer.schedule(new MyTask(), 1000);  
  22.             }  
  23.         });  
  24.     }  
  25.       
  26.       
  27.     class MyTask extends TimerTask{  
  28.           
  29.         Message msg;  
  30.         Bundle bundle;  
  31.         SimpleDateFormat sdf;  
  32.           
  33.         public MyTask(){  
  34.             Message msg = new Message();  
  35.             Bundle bundle = new Bundle();  
  36.             sdf = new SimpleDateFormat();  
  37.         }  
  38.           
  39.         @Override  
  40.         public void run() {  
  41.             String date = sdf.format(new Date());  
  42.             //在子线程中更新UI   
  43.                         setTitle("当前时间 :"+date);  
  44.         }  
  45.     }  
  46. }  

上面的例子会报“Only the original thread that created a view hierarchy can touch its views.

正确的写法应该是在子线程中组装数据,然后通过handler发送消息给UI线程,最后在UI线程中更新UI:

 
  1. public class MainActivity extends Activity {  
  2.   
  3.     private Button btn;  
  4.     private final Handler handler = new Handler(){  
  5.           
  6.         @Override  
  7.         public void handleMessage(Message msg) {  
  8.             //接收消息   
  9.             switch (msg.what) {  
  10.             case 110:  
  11.                 Bundle bundle = msg.getData();  
  12.                 String date = bundle.getString("date");  
  13.                 //更新UI   
  14.                 setTitle(date);  
  15.                 break;  
  16.             }  
  17.         }  
  18.     };  
  19.       
  20.     @Override  
  21.     public void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         setContentView(R.layout.main);  
  24.         btn = (Button) findViewById(R.id.time);  
  25.         btn.setOnClickListener(new OnClickListener() {  
  26.             @Override  
  27.             public void onClick(View arg0) {  
  28.                  Timer timer = new Timer();  
  29.                  //设置每秒执行一次   
  30.                  timer.schedule(new MyTask(),0,1000);  
  31.             }  
  32.         });  
  33.     }  
  34.       
  35.       
  36.     class MyTask extends TimerTask{  
  37.           
  38.         Message msg;  
  39.         Bundle bundle;  
  40.         SimpleDateFormat sdf;  
  41.           
  42.         public MyTask(){  
  43.             msg = new Message();  
  44.             bundle = new Bundle();  
  45.             sdf = new SimpleDateFormat("yyyy年MM月dd : HH时mm分ss");  
  46.         }  
  47.           
  48.         @Override  
  49.         public void run() {  
  50.             //组装数据   
  51.             String date = sdf.format(new Date());  
  52.             msg.what = 110;  
  53.             bundle.putString("date", date);  
  54.             msg.setData(bundle);  
  55.             //发送消息   
  56.             handler.sendMessage(msg);  
  57.         }  
  58.     }  
  59. }  

相关内容