ANDROID使用UI Thread/背景Thread的簡記


Android APP因為有ANR(Application No Respnse)問題要處理所以需要知道哪些操作是要在UI thread上執行, 而複雜操作要在背景thread上執行

寫過Java的人都會想到用Thread或是繼承Thread來執行複雜操作
// Java style thread
new Thread(new Runnable() {
    public void run() {
        // Running long time process, not included UIs
    }
}).start();

// Override the thread class
new Thread() {
    public void run() {
        // Running long time process, not included UIs
    }
}.start();

那Android上如何執行複雜操作? 你還是可以使用Java Thread或是選擇Android提供的Looper與Handler機制

/*
import android.os.HandlerThread;
import android.os.Handler;
HandlerThread mBackLooper = null;
Handler mBackHandler = null;
mBackLooper = new HandlerThread("BackgroundWorker");
mBackLooper.start();
mBackHandler = new Handler(mBackLooper.getLooper());
*/
void processComplexity(String name) {
    final String Name = name;
    mBackHandler.post(new Runnable(){
        public void run() {
            Log.i.(Name, "worker running");
            // Running long time process, not included UIs
        }
    });
}

那UI thread呢?

就要使用View的post來執行
// View mView = findViewById(R.id.{YourViewId});
// Notice: must call behind "setContentView()" in onCreate()
((View) mView).post(new Runnable(){
    public void run() {
        // Update UIs (e.g. Toast, TextView, SurfaceView, etc.)
    }
});

或是用Activity的runOnUiThread來執行
// In Application, Context mContext = getApplicationContext();
// In Activity, Context mContext = getContext();
// Notice: must call behind "setContentView()" in onCreate()
((Activity) mContext).runOnUiThread(new Runnable() {
    public void run() {
        // Update UIs (e.g. Toast, TextView, SurfaceView, etc.)
    }
});

如果想在複雜操作中間穿插UI操作呢?

我自己會將UI操作的功能逐項寫成功能函數, 再進行操作, 例如使用Toast顯示UI訊息
// import android.widget.Toast;
// private Toast mToast = null;
// setContentView(R.layout.activity_main);
// mContext = getApplicationContext();
void showMessage(String message) {
    final String msg = message;
    runOnUiThread(new Runnable(){ 
        public void run() {
            try {
                if (mToast!=null) {
                    mToast.cancel();
                    mToast = null;
                }
                mToast = Toast.makeText(mContext, msg, Toast.LENGTH_LONG);
                mToast.show();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }// end run
    });
}

或是使用AsyncTask來進行多個事件的非同步處理


留言