如果我們想要在另一個 Thread 中操控 UI (Activity),在Android中直接使用是不行的。
如果直接使用的話,會丟出一個 android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views 錯誤。
我們必須透過Message的傳遞來達到目的。
import XXX.XXX.XXX.MyHandler;
public class main extends Activity {
public ProgressDialog myDialog = null ;
private static final int UPDATE_SETTING_SUCCESS = 0x0001;
/** Called when the activity is first created **/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.XXX);
final MyHandler handler = new MyHandler();
Submit = (Button) findViewById(R.id.Button01);
Submit.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
myDialog = ProgressDialog.show(
ToCloud.this,
"請稍後片刻...",
"正在執行雲端運算中...",
true
);
new Thread()
{
public void run()
{
String result = null ;
try{
// 透過Message來傳遞值做對應操作UI(Activity)的部分即可執行。
Message m = new Message();
m.what = UPDATE_SETTING_SUCCESS;
handler.sendMessage(m);
// 在這邊寫要操作UI(Activity)的部分,不會動作,還有可能程式會當掉。
}catch (Exception e)
{
e.printStackTrace();
// 在這邊寫要操作UI(Activity)的部分,不會動作,還有可能程式會當掉。
}finally
{
myDialog.dismiss();
// 在這邊寫要操作UI(Activity)的部分,不會動作,還有可能程式會當掉。
}
}
}.start();
}
});
}
class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_SETTING_SUCCESS:
// 在這邊寫要操作UI(Activity)的部分,就會動作了。
}
super.handleMessage(msg);
}
}
}
要寫Android,難懂的多執行緒一定要給他搞懂
在Android當中,如果做超過5秒被系統強制關閉(收到Application not Responsed簡稱ANR);onCreate()如果做超過10秒就會跳ANR。
所以繁重的事情不能在onCreate()裡頭做,解決辦法之一就是Thread(執行緒)。
Thread & Runnable
啟動Thread,指定Runable給它執行。執行完後就不再動作。
HandlerThread & Handler
有一種Thread,他的性質比較不一樣,不管有沒有事情做也要待機在那裡。
會有一個 HandlerThread 負責管理他要執行的事。
回到程式,一般來說,Activity 執行的時候,會有個 UI Thread( Main Thread ) 就是你程式本身原有的執行緒,管著畫面呈現 ... 等等事物,就是你的程式進入點。
而 Main Thread,他也是個 HandlerThread 可以給他一個Handler,做接收訊息之用。
package com.J_Test.HandlerAndThread;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
public class main extends Activity {
/* Called when the activity is first created. */
private Handler mUI_Handler = new Handler();
private Handler mThreadHandler;
private HandlerThread mThread;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mThread = new HandlerThread("name");
mThread.start();
mThreadHandler = new Handler(mThread.getLooper());
mThreadHandler.post(r1);
}
private Runnable r1 = new Runnable () {
public void run() {
// 做了很多事
mUI_Handler.post(r2);
}
};
private Runnable r2 = new Runnable () {
public void run() {
// 顯示畫面的動作
}
};
@Override
protected void onDestroy() {
super.onDestroy();
if (mThreadHandler != null) {
mThreadHandler.removeCallbacks(r1);
}
if (mThread != null) {
mThread.quit();
}
}
}