android使用多線程更新ui示例分享
Android線程涉及的技術有:Handler;Message;MessageQueue;Looper;HandlerThread。
下面看一段在線程中更新UI的代碼:
public class MainActivity extends Activity {
private TextView timeLable;
private Button stopBtn;
private Thread mThread;
private boolean isRunning = true;
private int timeCount = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timeLable = (TextView) findViewById(R.id.timelable);
stopBtn = (Button) findViewById(R.id.stop);
stopBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
isRunning = false;
}
});
mThread = new Thread(new Runnable() {
@Override
public void run() {
while (isRunning) {
try {
Thread.sleep(1000);
timeCount++;
timeLable.setText("timeCount=" + timeCount + " 秒");
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
mThread.start();
}
}
這段代碼只是在線程中更新TextView的顯示內容,但是執(zhí)行后看不到效果,并且報了一個錯:android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
在Android中更新UI處理必須由創(chuàng)建它的線程更新,而不能在其他線程中更新。上面的錯誤原因就在于此。
由于timeLable是一個UI控件,它是在主線程中創(chuàng)建的,但是它卻在子線程中被更新了,更新操作在mThread線程的run()方法中實現。這樣的處理違背了Android多線程編程規(guī)則,系統(tǒng)會拋出異常。
要解決這個問題,就要明確主線程和子線程的職責。主線程的職責是創(chuàng)建、顯示和更新UI控件、處理UI事件、啟動子線程、停止子線程等;子線程的職責是計算時間和向主線程發(fā)出更新UI消息,而不是直接更新UI。子線程向主線程發(fā)送消息可以用Handler實現。代碼如下:
public class MainActivity extends Activity {
private TextView timeLable;
private Button stopBtn;
private Thread mThread;
private boolean isRunning = true;
private int timeCount = 0;
final private Handler mHandler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case 0 :
timeLable.setText("timeCount=" + timeCount + " 秒");
break;
default :
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timeLable = (TextView) findViewById(R.id.timelable);
stopBtn = (Button) findViewById(R.id.stop);
stopBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
isRunning = false;
}
});
mThread = new Thread(new Runnable() {
@Override
public void run() {
while (isRunning) {
try {
Thread.sleep(1000);
timeCount++;
mHandler.sendEmptyMessage(0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
mThread.start();
}
}
運行后不會報之前的錯,TextView也能正常更新內容了。
- 淺談Android 的線程和線程池的使用
- Android自帶的四種線程池使用總結
- 在Android線程池里運行代碼任務實例
- Android 線程之自定義帶消息循環(huán)Looper的實例
- Android開發(fā)之多線程中實現利用自定義控件繪制小球并完成小球自動下落功能實例
- Android開發(fā)筆記之:如何安全中止一個自定義線程Thread的方法
- Android Handler主線程和一般線程通信的應用分析
- Android 在其他線程中更新UI線程的解決方法
- android開發(fā)教程之子線程中更新界面
- Android多線程及異步處理問題詳細探討
- Handler與Android多線程詳解
- Android編程自定義線程池與用法示例
相關文章
Android 使用 ViewPager循環(huán)廣告位的實現
本文給大家分享android使用 ViewPager循環(huán)廣告位的實現,感興趣的朋友一起學習吧2015-11-11

