HandlerThread
1. Override Runnable
public class LauncherModel extends BroadcastReceiver {
......
private LoaderTask mLoaderTask;
private static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
static {
sWorkerThread.start();
}
private static final Handler sWorker = new Handler(sWorkerThread.getLooper());
......
public void startLoader(Context context, boolean isLaunching) {
......
synchronized (mLock) {
......
// Don't bother to start the thread if we know it's not going to do anything
if (mCallbacks != null && mCallbacks.get() != null) {
......
mLoaderTask = new LoaderTask(context, isLaunching);
sWorker.post(mLoaderTask);
}
}
}
......
private class LoaderTask implements Runnable {
......
public void run() {
......
keep_running: {
......
// second step
if (loadWorkspaceFirst) {
......
loadAndBindAllApps();
} else {
......
}
......
}
......
}
......
}
......
}
/**
* This service essentially plays the role of a "worker thread", allowing us to store
* incoming messages to the database, update notifications, etc. without blocking the
* main thread that SmsReceiver runs on.
*/
public class SmsReceiverService extends Service {
private static final String TAG = "SmsReceiverService";
private ServiceHandler mServiceHandler;
private Looper mServiceLooper;
private boolean mSending;
.....
public Handler mToastHandler = new Handler();
// This must match SEND_PROJECTION.
private static final int SEND_COLUMN_ID = 0;
private static final int SEND_COLUMN_THREAD_ID = 1;
private static final int SEND_COLUMN_ADDRESS = 2;
private static final int SEND_COLUMN_BODY = 3;
private static final int SEND_COLUMN_STATUS = 4;
private int mResultCode;
@Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block.
HandlerThread thread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Temporarily removed for this duplicate message track down.
mResultCode = intent != null ? intent.getIntExtra("result", 0) : 0;
if (mResultCode != 0) {
Log.v(TAG, "onStart: #" + startId + " mResultCode: " + mResultCode +
" = " + translateResultCode(mResultCode));
}
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
return Service.START_NOT_STICKY;
}
.....
@Override
public void onDestroy() {
// Temporarily removed for this duplicate message track down.
// if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) {
// Log.v(TAG, "onDestroy");
// }
mServiceLooper.quit();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
/**
* Handle incoming transaction requests.
* The incoming requests are initiated by the MMSC Server or by the MMS Client itself.
*/
@Override
public void handleMessage(Message msg) {
int serviceId = msg.arg1;
Intent intent = (Intent)msg.obj;
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
Log.v(TAG, "handleMessage serviceId: " + serviceId + " intent: " + intent);
}
if (intent != null) {
String action = intent.getAction();
int error = intent.getIntExtra("errorCode", 0);
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
Log.v(TAG, "handleMessage action: " + action + " error: " + error);
}
if (MESSAGE_SENT_ACTION.equals(intent.getAction())) {
handleSmsSent(intent, error);
} else if (SMS_RECEIVED_ACTION.equals(action)) {
handleSmsReceived(intent, error);
} else if (ACTION_BOOT_COMPLETED.equals(action)) {
handleBootCompleted();
} else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
handleServiceStateChanged(intent);
} else if (ACTION_SEND_MESSAGE.endsWith(action)) {
handleSendMessage();
}
}
// NOTE: We MUST not call stopSelf() directly, since we need to
// make sure the wake lock acquired by AlertReceiver is released.
SmsReceiver.finishStartingService(SmsReceiverService.this, serviceId);
}
}
.....
}