1. 如何使用Handler?
创建Handler的方式:
1) new Handler()
创建目前正在执行此指令的线程的Handler对象,其Looper通过Looper.Looper.myLooper()获取
2) new Handler(Looper)
创建指定Looper线程的Handler对象, 如new Handler(Looper.getMainLooper())创建主线程的Handler对象
发送Message方案一:
static final int KEEP_SCREEN_ON_MSG = 1;
static final int GET_NEW_SURFACE_MSG = 2;
static final int UPDATE_WINDOW_MSG = 3;
final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case KEEP_SCREEN_ON_MSG: {
setKeepScreenOn(msg.arg1 != 0);
} break;
case GET_NEW_SURFACE_MSG: {
handleGetNewSurface();
} break;
case UPDATE_WINDOW_MSG: {
updateWindow(false, false);
} break;
}
}
};
//发送空消息
mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
//发送一个Message
Message msg = mHandler.obtainMessage(GET_NEW_SURFACE_MSG);
mHandler.sendMessage(msg);
发送Message方案二:
class AudioHandler extends Handler {
private void setDeviceVolume(VolumeStreamState streamState, int device) {
//do something
}
private void setAllVolumes(VolumeStreamState streamState) {
//do something
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SET_DEVICE_VOLUME:
setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1);
break;
case MSG_SET_ALL_VOLUMES:
setAllVolumes((VolumeStreamState) msg.obj);
break;
// ...
}
}
}
发送Runnable方案三:
public class MainActivity extends Activity {
private Handler h;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
h = new Handler(){
public void handleMessage(Message msg) {
//do nothing
}
};
h.post(new myRun());
}
class myRun implements Runnable{
public void run(){
setTitle(String.valueOf(1));
h.postDelayed(testRun, 2000);
}
}
Runnable testRun= new Runnable() {
public void run(){
setTitle(String.valueOf(2));
}
};
}
2. 如何使用Looper
Looper.prepare();
// 创建Handler
Looper.loop();
// 在此线程中创建的Handler将向Looper的MessageQueue发送消息
3. 创建、实现、启动线程
方案一:
new Thread(){
public void run(){
//do something you want to do
}
}.start();
方案二:
class Task implements Runnable {
public void run() {
// do something you want to do
}
}
Task ta = new Task();
Thread t1 = new Thread(ta, "MyTask");
t1.start();
方案三:
class MyThread extends Thread {
public MyThread() {
super("MyThread");
}
@Override
public void run() {
Looper.prepare();
mMyLooper = Looper.myLooper();
mAudioHandler = new AudioHandler();
//do something you want to do
Looper.loop();
}
}
AudioHandler mAudioHandler;
Looper mMyLooper;
MyThread mMyThread = new MyThread();
mMyThread.start(); //启动线程
// wait some event
mMyLooper.quit(); //使线程退出
4. 实现SurfaceHolder
在SurfaceView中实现的SurfaceHolder如下:
private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
private static final String LOG_TAG = "SurfaceHolder";
public boolean isCreating() {
return mIsCreating;
}
public void addCallback(Callback callback) {
synchronized (mCallbacks) {
// This is a linear search, but in practice we'll
// have only a couple callbacks, so it doesn't matter.
if (mCallbacks.contains(callback) == false) {
mCallbacks.add(callback);
}
}
}
public void removeCallback(Callback callback) {
synchronized (mCallbacks) {
mCallbacks.remove(callback);
}
}
public void setFixedSize(int width, int height) {
if (mRequestedWidth != width || mRequestedHeight != height) {
mRequestedWidth = width;
mRequestedHeight = height;
requestLayout();
}
}
public void setSizeFromLayout() {
if (mRequestedWidth != -1 || mRequestedHeight != -1) {
mRequestedWidth = mRequestedHeight = -1;
requestLayout();
}
}
public void setFormat(int format) {
// for backward compatibility reason, OPAQUE always
// means 565 for SurfaceView
if (format == PixelFormat.OPAQUE)
format = PixelFormat.RGB_565;
mRequestedFormat = format;
if (mWindow != null) {
updateWindow(false, false);
}
}
/**
* @deprecated setType is now ignored.
*/
@Deprecated
public void setType(int type) { }
public void setKeepScreenOn(boolean screenOn) {
Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG);
msg.arg1 = screenOn ? 1 : 0;
mHandler.sendMessage(msg);
}
public Canvas lockCanvas() {
return internalLockCanvas(null);
}
public Canvas lockCanvas(Rect dirty) {
return internalLockCanvas(dirty);
}
private final Canvas internalLockCanvas(Rect dirty) {
mSurfaceLock.lock();
if (DEBUG) Log.i(TAG, "Locking canvas... stopped="
+ mDrawingStopped + ", win=" + mWindow);
Canvas c = null;
if (!mDrawingStopped && mWindow != null) {
if (dirty == null) {
if (mTmpDirty == null) {
mTmpDirty = new Rect();
}
mTmpDirty.set(mSurfaceFrame);
dirty = mTmpDirty;
}
try {
c = mSurface.lockCanvas(dirty);
} catch (Exception e) {
Log.e(LOG_TAG, "Exception locking surface", e);
}
}
if (DEBUG) Log.i(TAG, "Returned canvas: " + c);
if (c != null) {
mLastLockTime = SystemClock.uptimeMillis();
return c;
}
// If the Surface is not ready to be drawn, then return null,
// but throttle calls to this function so it isn't called more
// than every 100ms.
long now = SystemClock.uptimeMillis();
long nextTime = mLastLockTime + 100;
if (nextTime > now) {
try {
Thread.sleep(nextTime-now);
} catch (InterruptedException e) {
}
now = SystemClock.uptimeMillis();
}
mLastLockTime = now;
mSurfaceLock.unlock();
return null;
}
public void unlockCanvasAndPost(Canvas canvas) {
mSurface.unlockCanvasAndPost(canvas);
mSurfaceLock.unlock();
}
public Surface getSurface() {
return mSurface;
}
public Rect getSurfaceFrame() {
return mSurfaceFrame;
}
}
5. 使用ProgressDialog
public class MainActivity extends Activity {
ProgressDialog mDialog;
MyThread mThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// create and display the progress in a new thread
mDialog = new ProgressDialog(MainActivity.this);
mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mDialog.setTitle("MyTitle");
//mDialog.setIcon(R.drawable.icon);
mDialog.setMessage("This is a progress example!");
mDialog.setMax(100);
mDialog.setProgress(0);
//mDialog.setSecondaryProgress(50);
mDialog.setIndeterminate(false);
mDialog.setCancelable(true);
mDialog.show();
mThread = new MyThread();
mThread.start();
}
public class MyThread extends Thread {
MyThread(){
super("MyThread");
}
@Override
public void run(){
int i=0;
while(i<100){
i++;
// set the progress value
mDialog.setProgress(i);
try{
Thread.sleep(100); // sleep 1s
}catch(InterruptedException e){
e.printStackTrace();
}
}
// destroy the progress
mDialog.dismiss();
}
}
}
6. 如何使用Timer and TimerTask?
package com.example.mytest;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
private Timer timer = new Timer();
private Handler h;
private int k = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
h = new Handler(){
public void handleMessage(Message msg) {
setTitle((String)msg.obj);
}
};
// init and start the timer
init();
}
public void init() {
//public abstract class TimerTask implements Runnable
TimerTask task = new TimerTask(){
@Override
public void run() {
h.removeMessages(0);
Message m = h.obtainMessage(1, 1, 1,Thread.currentThread().getName() + " : "+String.valueOf(k++));
h.sendMessage(m);
}
};
// after 500ms execute task firstly, then every 1000ms execute the task
timer.schedule(task, 500, 1000); //启动Timer线程
}
}