Android 提供以下的method, 可在其它的thread 下調用 UI thread.
或是使用Handler or AsyncTasks class 達到同樣的效果.
處理message 需要override handleMessage(), 透過sendMessage() or sendEmptyMessage() method.
執行Runnanble則是使用post() method.
一個Activity 只需有一個Handler instance.
呼叫execute() 開始執行, 之後onPerExecute()接著自動被呼叫, 通常用來 initial status of task.
接著doInBackground() 被調用, 一般為long time computation時使用.
call publishProgress()後會調用onProgressUpdate(), onProgressUpdate()調用於UI thread, 一般用來update progress bar, UI animate.
package com.samchen.samdemos.threads;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
public class DemoThreads extends Activity {
final boolean isThread = true;
final String TAG = "DemoThreads";
private ProgressBar mProgress;
private int mProgressStatus = 0;
boolean isRunning = false;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demothreads);
Button btnRun = (Button) findViewById(R.id.button1);
mProgress = (ProgressBar) findViewById(R.id.progressBar1);
btnRun.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View arg0) {
if(isRunning){
Log.d(TAG,"thread is
runing");
Toast.makeText(getApplicationContext(),
getString(R.string.running),
Toast.LENGTH_SHORT).show();
return;
}else
isRunning = true;
if (isThread) {
// thread example
new Thread(new Runnable() {
public void run() {
while (mProgressStatus < 100) {
// update the bar
status
mProgress.post(new Runnable() {
public void run() {
mProgress.setProgress(mProgressStatus);
Log.d(TAG, "update
mProgressStatus : "
+ mProgressStatus);
}
});
// do something long
SystemClock.sleep(500);
mProgressStatus++;
}
}
}).start();
} else {
// non-thread example
while (mProgressStatus < 100) {
// update the bar status
mProgress.post(new Runnable() {
public void run() {
mProgress.setProgress(mProgressStatus);
}
});
// do something long
//SystemClock.sleep(500);
//if use SystemClock.sleep, system
will be crash.
try{
Thread.sleep(500);
}catch (InterruptedException
e){
Log.d(TAG,"InterruptedException!!!!!!!");
e.printStackTrace();
}
mProgressStatus++;
}
}
}
});
}
}
Handler example:
package com.samchen.samdemos.threads;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
public class DemoHandler extends Activity {
final String TAG = "DemoHandler";
private ProgressBar mProgress;
private int mProgressStatus = 0;
private Handler mHandler;
boolean isRunning = false;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demothreads);
Button btnRun = (Button) findViewById(R.id.button1);
mProgress = (ProgressBar) findViewById(R.id.progressBar1);
mHandler = new Handler();
btnRun.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View arg0) {
if (!isRunning) {
startProgress(mProgress);
isRunning = true;
} else{
Log.d(TAG, "thread is
runing");
Toast.makeText(getApplicationContext(),
getString(R.string.running),
Toast.LENGTH_SHORT).show();
}
}
});
}
public void startProgress(View view) {
// Do something long
Runnable runnable = new Runnable() {
@Override
public void run() {
for (mProgressStatus = 0; mProgressStatus <= 100; mProgressStatus++) {
//final int value = i;
SystemClock.sleep(500);
mHandler.post(new Runnable() {
@Override
public void run() {
Log.d(TAG, "update
mProgressStatus : "
+ mProgressStatus);
mProgress.setProgress(mProgressStatus);
}
});
}
}
};
new Thread(runnable).start();
}
}
AsyncTask example:
package com.samchen.samdemos.threads;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
public class DemoAsyncTask extends Activity {
final String TAG = "DemoAsyncTask";
private ProgressBar mProgress;
private int mProgressStatus = 0;
boolean isRunning = false;
private updateTask mTask;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demothreads);
mProgress = (ProgressBar) findViewById(R.id.progressBar1);
Button btnRun = (Button) findViewById(R.id.button1);
btnRun.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View arg0) {
if (!isRunning) {
mTask = new updateTask();
mTask.execute();
isRunning = true;
} else {
Log.d(TAG, "thread is
runing");
Toast.makeText(getApplicationContext(),
getString(R.string.running), Toast.LENGTH_SHORT)
.show();
}
}
});
}
private class updateTask extends AsyncTask<Void, Integer, Void> {
protected void onPostExecute(Void result) {
}
protected void onProgressUpdate(Integer... value) {
Log.d(TAG, "onProgressUpdate : " + value);
mProgress.setProgress(value[0]);
}
protected void onPreExecute() {
// TODO Auto-generated method stub
mProgressStatus = 0;
}
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
while (mProgressStatus < 100) {
Log.d(TAG, "doInBackground mProgressStatus
: "
+ mProgressStatus);
// do something long
publishProgress(mProgressStatus);
SystemClock.sleep(500);
mProgressStatus++;
}
return null;
}
}
}