Android UI線程更新並不是線程安全的,並且必須在UI線程中進程UI更新操作,以下面一個錯誤為例:
- public class MainActivity extends Activity {
-
- private String title;
- private Button btn;
- private final Handler handler = new Handler(){
- @Override
- public void handleMessage(Message msg) {
- setTitle(title);
- }
- };
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- btn = (Button) findViewById(R.id.time);
- btn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- Timer timer = new Timer();
- timer.schedule(new MyTask(), 1000);
- }
- });
- }
-
-
- class MyTask extends TimerTask{
-
- Message msg;
- Bundle bundle;
- SimpleDateFormat sdf;
-
- public MyTask(){
- Message msg = new Message();
- Bundle bundle = new Bundle();
- sdf = new SimpleDateFormat();
- }
-
- @Override
- public void run() {
- String date = sdf.format(new Date());
- //在子線程中更新UI
- setTitle("當前時間 :"+date);
- }
- }
- }
上面的例子會報“Only the original thread that created a view hierarchy can touch its views. ”
正確的寫法應該是在子線程中組裝數據,然後通過handler發送消息給UI線程,最後在UI線程中更新UI:
- public class MainActivity extends Activity {
-
- private Button btn;
- private final Handler handler = new Handler(){
-
- @Override
- public void handleMessage(Message msg) {
- //接收消息
- switch (msg.what) {
- case 110:
- Bundle bundle = msg.getData();
- String date = bundle.getString("date");
- //更新UI
- setTitle(date);
- break;
- }
- }
- };
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- btn = (Button) findViewById(R.id.time);
- btn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- Timer timer = new Timer();
- //設置每秒執行一次
- timer.schedule(new MyTask(),0,1000);
- }
- });
- }
-
-
- class MyTask extends TimerTask{
-
- Message msg;
- Bundle bundle;
- SimpleDateFormat sdf;
-
- public MyTask(){
- msg = new Message();
- bundle = new Bundle();
- sdf = new SimpleDateFormat("yyyy年MM月dd : HH時mm分ss");
- }
-
- @Override
- public void run() {
- //組裝數據
- String date = sdf.format(new Date());
- msg.what = 110;
- bundle.putString("date", date);
- msg.setData(bundle);
- //發送消息
- handler.sendMessage(msg);
- }
- }
- }