Android中工作线程与主线程同步方式

在Android中,常用的主线程同步方式有以下几种:

  1. Activity.runOnUiThread(Runnable)
  2. View.post(Runnable)、View.postDelay(Runnable, long)
  3. AsyncTask
  4. Handler

这几种方式其原理都是一样的,都是基于Handler。

1、Activity.runOnUiThread(Runnable)

runOnUiThread是Activity中的一个final方法,不可以被重写,接受一个Runnable对象,其内部实现首先是判断当前线程是不是UI线程,如果是UI线程则直接调用Runnable的run()方法,如果不是,则通过Handler将Runnablepost到主线程,此Handler为主线程的Handler。

public final void runOnUiThread(Runnable action) {
    if (Thread.currentThread() != mUiThread) {
        mHandler.post(action);
    } else {
        action.run();
    }
}

这里的mUiThread在Activity的attach()方法中得到初始化。

final void attach(...) {
    ...
    mUiThread = Thread.currentThread();
    ...
}

这里的mUiThread 为什么会是主线程呢?

我们知道,当Zygote孵化出一个进程之后,便会执行ActivityThread中的main()方法,main()方法中初始化了mainLooper,随后new了一个ActivityThread对象,初始化了一个名为mH的Handler,然后进行Looper.loop()操作。

public static void main(String[] args) {
    ...
    Looper.prepareMainLooper();
    ...
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
    ...
    Looper.loop();
}

在mH中是这样实现的,然后调用handleLaunchActivity,最后执行Activity的attach方法,便初始化了mUiThread。

class H extends Handler {
    ...
    public void handleMessage(Message msg) {
        ....
        case LAUNCH_ACTIVITY:
            handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
            break;
        ....
    }
}

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    ...
    Activity a = performLaunchActivity(r, customIntent);
    ...
}

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ...
    Activity activity = null;
    activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
    activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);
    ...
}

2、View.post(Runnable)、View.postDelay(Runnable, long)

public boolean post(Runnable action) {
    final AttachInfo attachInfo = mAttachInfo;
    if (attachInfo != null) {
        return attachInfo.mHandler.post(action);
    }
    getRunQueue().post(action);
    return true;
}

public boolean postDelayed(Runnable action, long delayMillis) {
    final AttachInfo attachInfo = mAttachInfo;
    if (attachInfo != null) {
        return attachInfo.mHandler.postDelayed(action, delayMillis);
    }
    getRunQueue().postDelayed(action, delayMillis);
    return true;
}

两个方法都会先判断attachInfo是否为空,如果不为空则执行Handler.post(),那么attachInfo的赋值情况如何呢?

void dispatchAttachedToWindow(AttachInfo info, int visibility) {
    mAttachInfo = info;
}

void dispatchDetachedFromWindow() {
    mAttachInfo = null;
}

dispatchAttachedToWindow和dispatchDetachedFromWindow何时被调用这里不做展开,当attachInfo为空时,也就是执行了dispatchDetachedFromWindow之后,post的Runnable便会被加入到mRunQueue中,这里可以暂且将其理解为一个Runnable数组,当下次调用dispatchAttachedToWindow后,便会从mRunQueue中拿出Runnable依次执行handler.postDelayed。

void dispatchAttachedToWindow(AttachInfo info, int visibility) {
    ...
    if (mRunQueue != null) {
        mRunQueue.executeActions(info.mHandler);
        mRunQueue = null;
    }
    ...
}

public void executeActions(Handler handler) {
    synchronized (this) {
        final HandlerAction[] actions = mActions;
        for (int i = 0, count = mCount; i < count; i++) {
            final HandlerAction handlerAction = actions[i];
            handler.postDelayed(handlerAction.action, handlerAction.delay);
        }

        mActions = null;
        mCount = 0;
    }
}

3、AsyncTask

在AsyncTask中有一个名为mHandler的Handler,可以通过getHandler拿到,通常我们使用AsyncTask都是调用AsyncTask的无参构造方法,而无参构造方法会初始化主线程的Handler。在AsyncTask中,onPreExecute、onCancelled、onPostExecute、onProgressUpdate都会在主线程被调用,除onPreExecute是在一开始就被调用外,其余方法皆是通过Handler让其在主线程执行。

    protected final void publishProgress(Progress... values) {
        if (!isCancelled()) {
            getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
                        new AsyncTaskResult(this, values)).sendToTarget();
        }
    }

    private Result postResult(Result result) {
        @SuppressWarnings("unchecked")
        Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult(this, result));
        message.sendToTarget();
        return result;
    }

mHandler就是AsyncTask内部的InternalHandler

    private static class InternalHandler extends Handler {
        public InternalHandler(Looper looper) {
            super(looper);
        }

        @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
        @Override
        public void handleMessage(Message msg) {
            AsyncTaskResult result = (AsyncTaskResult) msg.obj;
            switch (msg.what) {
                case MESSAGE_POST_RESULT:
                    // There is only one result
                    result.mTask.finish(result.mData[0]);
                    break;
                case MESSAGE_POST_PROGRESS:
                    result.mTask.onProgressUpdate(result.mData);
                    break;
            }
        }
    }

    private void finish(Result result) {
        if (isCancelled()) {
            onCancelled(result);
        } else {
            onPostExecute(result);
        }
        mStatus = Status.FINISHED;
    }

    protected void onProgressUpdate(Progress... values) {

    }

 

你可能感兴趣的:(Android,Handler,多线程)