基于Android 10.0的源码剖析
当手指触摸到屏幕时, 屏幕硬件一行行不断地扫描每个像素点, 获取到触摸事件后, 从底层产生中断上报.
Native底层细节可参考http://gityuan.com/2016/12/31/input-ipc/, 本文暂不讨论, 直接从Java层分析起.
[ -> frameworks/base/core/java/android/view/ViewRootImpl.java ]
public abstract class InputEventReceiver {
...
// Called from native code.
private void dispatchInputEvent(int seq, InputEvent event) {
mSeqMap.put(event.getSequenceNumber(), seq);
onInputEvent(event);
}
...
}
final class WindowInputEventReceiver extends InputEventReceiver {
public WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {
super(inputChannel, looper);
}
@Override
public void onInputEvent(InputEvent event) {
List<InputEvent> processedEvents = mInputCompatProcessor.processInputEventForCompatibility(event);
if (processedEvents != null) {
if (processedEvents.isEmpty()) {
// InputEvent consumed by mInputCompatProcessor
finishInputEvent(event, true);
} else {
for (int i = 0; i < processedEvents.size(); i++) {
enqueueInputEvent(
processedEvents.get(i), this,
QueuedInputEvent.FLAG_MODIFIED_FOR_COMPATIBILITY, true);
}
}
} else {
enqueueInputEvent(event, this, 0, true);
}
}
...
}
void enqueueInputEvent(InputEvent event, InputEventReceiver receiver, int flags, boolean processImmediately) {
QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags);
// Always enqueue the input event in order, regardless of its time stamp.
// We do this because the application or the IME may inject key events
// in response to touch events and we want to ensure that the injected keys
// are processed in the order they were received and we cannot trust that
// the time stamp of injected events are monotonic.
QueuedInputEvent last = mPendingInputEventTail;
if (last == null) {
mPendingInputEventHead = q;
mPendingInputEventTail = q;
} else {
last.mNext = q;
mPendingInputEventTail = q;
}
mPendingInputEventCount += 1;
if (processImmediately) {
doProcessInputEvents();
} else {
scheduleProcessInputEvents();
}
}
void doProcessInputEvents() {
// Deliver all pending input events in the queue.
while (mPendingInputEventHead != null) {
QueuedInputEvent q = mPendingInputEventHead;
mPendingInputEventHead = q.mNext;
if (mPendingInputEventHead == null) {
mPendingInputEventTail = null;
}
q.mNext = null;
mPendingInputEventCount -= 1;
long eventTime = q.mEvent.getEventTimeNano();
long oldestEventTime = eventTime;
if (q.mEvent instanceof MotionEvent) {
MotionEvent me = (MotionEvent)q.mEvent;
if (me.getHistorySize() > 0) {
oldestEventTime = me.getHistoricalEventTimeNano(0);
}
}
mChoreographer.mFrameInfo.updateInputEventTime(eventTime, oldestEventTime);
deliverInputEvent(q);
}
// We are done processing all input events that we can process right now
// so we can clear the pending flag immediately.
if (mProcessInputEventsScheduled) {
mProcessInputEventsScheduled = false;
mHandler.removeMessages(MSG_PROCESS_INPUT_EVENTS);
}
}
private void deliverInputEvent(QueuedInputEvent q) {
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onInputEvent(q.mEvent, 0);
}
InputStage stage;
if (q.shouldSendToSynthesizer()) {
stage = mSyntheticInputStage;
} else {
stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;
}
if (q.mEvent instanceof KeyEvent) {
mUnhandledKeyManager.preDispatch((KeyEvent) q.mEvent);
}
if (stage != null) {
handleWindowFocusChanged();
stage.deliver(q);
} else {
finishInputEvent(q);
}
}
abstract class InputStage {
private final InputStage mNext;
protected static final int FORWARD = 0;
protected static final int FINISH_HANDLED = 1;
protected static final int FINISH_NOT_HANDLED = 2;
/**
* Creates an input stage.
* @param next The next stage to which events should be forwarded.
*/
public InputStage(InputStage next) {
mNext = next;
}
/**
* Delivers an event to be processed.
*/
public final void deliver(QueuedInputEvent q) {
if ((q.mFlags & QueuedInputEvent.FLAG_FINISHED) != 0) {
forward(q);
} else if (shouldDropInputEvent(q)) {
finish(q, false);
} else {
apply(q, onProcess(q));
}
}
...
}
/**
* Delivers post-ime input events to the view hierarchy.
*/
final class ViewPostImeInputStage extends InputStage {
public ViewPostImeInputStage(InputStage next) {
super(next);
}
@Override
protected int onProcess(QueuedInputEvent q) {
if (q.mEvent instanceof KeyEvent) {
return processKeyEvent(q);
} else {
final int source = q.mEvent.getSource();
if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
return processPointerEvent(q);
} else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
return processTrackballEvent(q);
} else {
return processGenericMotionEvent(q);
}
}
}
@Override
protected void onDeliverToNext(QueuedInputEvent q) {
if (mUnbufferedInputDispatch
&& q.mEvent instanceof MotionEvent
&& ((MotionEvent)q.mEvent).isTouchEvent()
&& isTerminalInputEvent(q.mEvent)) {
mUnbufferedInputDispatch = false;
scheduleConsumeBatchedInput();
}
super.onDeliverToNext(q);
}
...
}
final class ViewPostImeInputStage extends InputStage {
...
private int processPointerEvent(QueuedInputEvent q) {
final MotionEvent event = (MotionEvent)q.mEvent;
mAttachInfo.mUnbufferedDispatchRequested = false;
mAttachInfo.mHandlingPointerEvent = true;
boolean handled = mView.dispatchPointerEvent(event);
maybeUpdatePointerIcon(event);
maybeUpdateTooltip(event);
mAttachInfo.mHandlingPointerEvent = false;
if (mAttachInfo.mUnbufferedDispatchRequested && !mUnbufferedInputDispatch) {
mUnbufferedInputDispatch = true;
if (mConsumeBatchedInputScheduled) {
scheduleConsumeBatchedInputImmediately();
}
}
return handled ? FINISH_HANDLED : FORWARD;
}
...
}
[ -> frameworks/base/core/java/com/android/internal/policy/DecorView.java ]
DecorView继承ViewGroup, DecorView#dispatchPointerEvent 也就是 ViewGroup#dispatchPointerEvent
public final boolean dispatchPointerEvent(MotionEvent event) {
if (event.isTouchEvent()) {
return dispatchTouchEvent(event);
} else {
return dispatchGenericMotionEvent(event);
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final Window.Callback cb = mWindow.getCallback();
return cb != null && !mWindow.isDestroyed() && mFeatureId < 0
? cb.dispatchTouchEvent(ev) : super.dispatchTouchEvent(ev);
}
溯源PhoneWindow#setCallback
可知, mCallback为Activity.
[ -> frameworks/base/core/java/android/app/Activity.java ]
/**
* Called to process touch screen events. You can override this to
* intercept all touch screen events before they are dispatched to the
* window. Be sure to call this implementation for touch screen events
* that should be handled normally.
*
* @param ev The touch screen event.
*
* @return boolean Return true if this event was consumed.
*/
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
}
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
/**
* Called when a touch screen event was not handled by any of the views
* under it. This is most useful to process touch events that happen
* outside of your window bounds, where there is no view to receive it.
*
* @param event The touch screen event being processed.
*
* @return Return true if you have consumed the event, false if you haven't.
* The default implementation always returns false.
*/
public boolean onTouchEvent(MotionEvent event) {
if (mWindow.shouldCloseOnTouch(this, event)) {
finish();
return true;
}
return false;
}
[ -> frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java ]
@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
return mDecor.superDispatchTouchEvent(event);
}
public boolean superDispatchTouchEvent(MotionEvent event) {
return super.dispatchTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(ev, 1);
}
// If the event targets the accessibility focused view and this is it, start
// normal event dispatch. Maybe a descendant is what will handle the click.
if (ev.isTargetAccessibilityFocus() && isAccessibilityFocusedViewOrHost()) {
ev.setTargetAccessibilityFocus(false);
}
boolean handled = false;
if (onFilterTouchEventForSecurity(ev)) {
final int action = ev.getAction();
final int actionMasked = action & MotionEvent.ACTION_MASK;
// Handle an initial down.
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Throw away all previous state when starting a new touch gesture.
// The framework may have dropped the up or cancel event for the previous gesture
// due to an app switch, ANR, or some other state change.
cancelAndClearTouchTargets(ev);
resetTouchState();
}
// Check for interception.
final boolean intercepted;
if (actionMasked == MotionEvent.ACTION_DOWN
|| mFirstTouchTarget != null) {
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action); // restore action in case it was changed
} else {
intercepted = false;
}
} else {
// There are no touch targets and this action is not an initial down
// so this view group continues to intercept touches.
intercepted = true;
}
// If intercepted, start normal event dispatch. Also if there is already
// a view that is handling the gesture, do normal event dispatch.
if (intercepted || mFirstTouchTarget != null) {
ev.setTargetAccessibilityFocus(false);
}
// Check for cancelation.
final boolean canceled = resetCancelNextUpFlag(this)
|| actionMasked == MotionEvent.ACTION_CANCEL;
// Update list of touch targets for pointer down, if needed.
final boolean split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) != 0;
TouchTarget newTouchTarget = null;
boolean alreadyDispatchedToNewTouchTarget = false;
if (!canceled && !intercepted) {
// If the event is targeting accessibility focus we give it to the
// view that has accessibility focus and if it does not handle it
// we clear the flag and dispatch the event to all children as usual.
// We are looking up the accessibility focused host to avoid keeping
// state since these events are very rare.
View childWithAccessibilityFocus = ev.isTargetAccessibilityFocus()
? findChildWithAccessibilityFocus() : null;
if (actionMasked == MotionEvent.ACTION_DOWN
|| (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)
|| actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
final int actionIndex = ev.getActionIndex(); // always 0 for down
final int idBitsToAssign = split ? 1 << ev.getPointerId(actionIndex)
: TouchTarget.ALL_POINTER_IDS;
// Clean up earlier touch targets for this pointer id in case they
// have become out of sync.
removePointersFromTouchTargets(idBitsToAssign);
final int childrenCount = mChildrenCount;
if (newTouchTarget == null && childrenCount != 0) {
final float x = ev.getX(actionIndex);
final float y = ev.getY(actionIndex);
// Find a child that can receive the event.
// Scan children from front to back.
final ArrayList<View> preorderedList = buildTouchDispatchChildList();
final boolean customOrder = preorderedList == null
&& isChildrenDrawingOrderEnabled();
final View[] children = mChildren;
for (int i = childrenCount - 1; i >= 0; i--) {
final int childIndex = getAndVerifyPreorderedIndex(
childrenCount, i, customOrder);
final View child = getAndVerifyPreorderedView(
preorderedList, children, childIndex);
// If there is a view that has accessibility focus we want it
// to get the event first and if not handled we will perform a
// normal dispatch. We may do a double iteration but this is
// safer given the timeframe.
if (childWithAccessibilityFocus != null) {
if (childWithAccessibilityFocus != child) {
continue;
}
childWithAccessibilityFocus = null;
i = childrenCount - 1;
}
if (!child.canReceivePointerEvents()
|| !isTransformedTouchPointInView(x, y, child, null)) {
ev.setTargetAccessibilityFocus(false);
continue;
}
newTouchTarget = getTouchTarget(child);
if (newTouchTarget != null) {
// Child is already receiving touch within its bounds.
// Give it the new pointer in addition to the ones it is handling.
newTouchTarget.pointerIdBits |= idBitsToAssign;
break;
}
resetCancelNextUpFlag(child);
if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
// Child wants to receive touch within its bounds.
mLastTouchDownTime = ev.getDownTime();
if (preorderedList != null) {
// childIndex points into presorted list, find original index
for (int j = 0; j < childrenCount; j++) {
if (children[childIndex] == mChildren[j]) {
mLastTouchDownIndex = j;
break;
}
}
} else {
mLastTouchDownIndex = childIndex;
}
mLastTouchDownX = ev.getX();
mLastTouchDownY = ev.getY();
newTouchTarget = addTouchTarget(child, idBitsToAssign);
alreadyDispatchedToNewTouchTarget = true;
break;
}
// The accessibility focus didn't handle the event, so clear
// the flag and do a normal dispatch to all children.
ev.setTargetAccessibilityFocus(false);
}
if (preorderedList != null) preorderedList.clear();
}
if (newTouchTarget == null && mFirstTouchTarget != null) {
// Did not find a child to receive the event.
// Assign the pointer to the least recently added target.
newTouchTarget = mFirstTouchTarget;
while (newTouchTarget.next != null) {
newTouchTarget = newTouchTarget.next;
}
newTouchTarget.pointerIdBits |= idBitsToAssign;
}
}
}
// Dispatch to touch targets.
if (mFirstTouchTarget == null) {
// No touch targets so treat this as an ordinary view.
handled = dispatchTransformedTouchEvent(ev, canceled, null,
TouchTarget.ALL_POINTER_IDS);
} else {
// Dispatch to touch targets, excluding the new touch target if we already
// dispatched to it. Cancel touch targets if necessary.
TouchTarget predecessor = null;
TouchTarget target = mFirstTouchTarget;
while (target != null) {
final TouchTarget next = target.next;
if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) {
handled = true;
} else {
final boolean cancelChild = resetCancelNextUpFlag(target.child)
|| intercepted;
if (dispatchTransformedTouchEvent(ev, cancelChild,
target.child, target.pointerIdBits)) {
handled = true;
}
if (cancelChild) {
if (predecessor == null) {
mFirstTouchTarget = next;
} else {
predecessor.next = next;
}
target.recycle();
target = next;
continue;
}
}
predecessor = target;
target = next;
}
}
// Update list of touch targets for pointer up or cancel, if needed.
if (canceled
|| actionMasked == MotionEvent.ACTION_UP
|| actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
resetTouchState();
} else if (split && actionMasked == MotionEvent.ACTION_POINTER_UP) {
final int actionIndex = ev.getActionIndex();
final int idBitsToRemove = 1 << ev.getPointerId(actionIndex);
removePointersFromTouchTargets(idBitsToRemove);
}
}
if (!handled && mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onUnhandledEvent(ev, 1);
}
return handled;
}
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.isFromSource(InputDevice.SOURCE_MOUSE)
&& ev.getAction() == MotionEvent.ACTION_DOWN
&& ev.isButtonPressed(MotionEvent.BUTTON_PRIMARY)
&& isOnScrollbarThumb(ev.getX(), ev.getY())) {
return true;
}
return false;
}
public boolean dispatchTouchEvent(MotionEvent event) {
// If the event should be handled by accessibility focus first.
if (event.isTargetAccessibilityFocus()) {
// We don't have focus or no virtual descendant has it, do not handle the event.
if (!isAccessibilityFocusedViewOrHost()) {
return false;
}
// We have focus and got the event, then use normal event dispatch.
event.setTargetAccessibilityFocus(false);
}
boolean result = false;
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(event, 0);
}
final int actionMasked = event.getActionMasked();
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Defensive cleanup for new gesture
stopNestedScroll();
}
if (onFilterTouchEventForSecurity(event)) {
if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {
result = true;
}
// noinspection SimplifiableIfStatement
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}
if (!result && onTouchEvent(event)) {
result = true;
}
}
if (!result && mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
}
// Clean up after nested scrolls if this is the end of a gesture;
// also cancel it if we tried an ACTION_DOWN but we didn't want the rest
// of the gesture.
if (actionMasked == MotionEvent.ACTION_UP ||
actionMasked == MotionEvent.ACTION_CANCEL ||
(actionMasked == MotionEvent.ACTION_DOWN && !result)) {
stopNestedScroll();
}
return result;
}
public boolean onTouchEvent(MotionEvent event) {
final float x = event.getX();
final float y = event.getY();
final int viewFlags = mViewFlags;
final int action = event.getAction();
final boolean clickable = ((viewFlags & CLICKABLE) == CLICKABLE
|| (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
|| (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE;
if ((viewFlags & ENABLED_MASK) == DISABLED) {
if (action == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
setPressed(false);
}
mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
// A disabled view that is clickable still consumes the touch
// events, it just doesn't respond to them.
return clickable;
}
if (mTouchDelegate != null) {
if (mTouchDelegate.onTouchEvent(event)) {
return true;
}
}
if (clickable || (viewFlags & TOOLTIP) == TOOLTIP) {
switch (action) {
case MotionEvent.ACTION_UP:
mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
if ((viewFlags & TOOLTIP) == TOOLTIP) {
handleTooltipUp();
}
if (!clickable) {
removeTapCallback();
removeLongPressCallback();
mInContextButtonPress = false;
mHasPerformedLongPress = false;
mIgnoreNextUpEvent = false;
break;
}
boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0;
if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) {
// take focus if we don't have it already and we should in
// touch mode.
boolean focusTaken = false;
if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
focusTaken = requestFocus();
}
if (prepressed) {
// The button is being released before we actually
// showed it as pressed. Make it show the pressed
// state now (before scheduling the click) to ensure
// the user sees it.
setPressed(true, x, y);
}
if (!mHasPerformedLongPress && !mIgnoreNextUpEvent) {
// This is a tap, so remove the longpress check
removeLongPressCallback();
// Only perform take click actions if we were in the pressed state
if (!focusTaken) {
// Use a Runnable and post this rather than calling
// performClick directly. This lets other visual state
// of the view update before click actions start.
if (mPerformClick == null) {
mPerformClick = new PerformClick();
}
if (!post(mPerformClick)) {
performClickInternal();
}
}
}
if (mUnsetPressedState == null) {
mUnsetPressedState = new UnsetPressedState();
}
if (prepressed) {
postDelayed(mUnsetPressedState,
ViewConfiguration.getPressedStateDuration());
} else if (!post(mUnsetPressedState)) {
// If the post failed, unpress right now
mUnsetPressedState.run();
}
removeTapCallback();
}
mIgnoreNextUpEvent = false;
break;
case MotionEvent.ACTION_DOWN:
if (event.getSource() == InputDevice.SOURCE_TOUCHSCREEN) {
mPrivateFlags3 |= PFLAG3_FINGER_DOWN;
}
mHasPerformedLongPress = false;
if (!clickable) {
checkForLongClick(
ViewConfiguration.getLongPressTimeout(),
x,
y,
TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS);
break;
}
if (performButtonActionOnTouchDown(event)) {
break;
}
// Walk up the hierarchy to determine if we're inside a scrolling container.
boolean isInScrollingContainer = isInScrollingContainer();
// For views inside a scrolling container, delay the pressed feedback for
// a short period in case this is a scroll.
if (isInScrollingContainer) {
mPrivateFlags |= PFLAG_PREPRESSED;
if (mPendingCheckForTap == null) {
mPendingCheckForTap = new CheckForTap();
}
mPendingCheckForTap.x = event.getX();
mPendingCheckForTap.y = event.getY();
postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
} else {
// Not inside a scrolling container, so show the feedback right away
setPressed(true, x, y);
checkForLongClick(
ViewConfiguration.getLongPressTimeout(),
x,
y,
TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS);
}
break;
case MotionEvent.ACTION_CANCEL:
if (clickable) {
setPressed(false);
}
removeTapCallback();
removeLongPressCallback();
mInContextButtonPress = false;
mHasPerformedLongPress = false;
mIgnoreNextUpEvent = false;
mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
break;
case MotionEvent.ACTION_MOVE:
if (clickable) {
drawableHotspotChanged(x, y);
}
final int motionClassification = event.getClassification();
final boolean ambiguousGesture =
motionClassification == MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE;
int touchSlop = mTouchSlop;
if (ambiguousGesture && hasPendingLongPressCallback()) {
final float ambiguousMultiplier =
ViewConfiguration.getAmbiguousGestureMultiplier();
if (!pointInView(x, y, touchSlop)) {
// The default action here is to cancel long press. But instead, we
// just extend the timeout here, in case the classification
// stays ambiguous.
removeLongPressCallback();
long delay = (long) (ViewConfiguration.getLongPressTimeout() * ambiguousMultiplier);
// Subtract the time already spent
delay -= event.getEventTime() - event.getDownTime();
checkForLongClick(
delay,
x,
y,
TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS);
}
touchSlop *= ambiguousMultiplier;
}
// Be lenient about moving outside of buttons
if (!pointInView(x, y, touchSlop)) {
// Outside button
// Remove any future long press/tap checks
removeTapCallback();
removeLongPressCallback();
if ((mPrivateFlags & PFLAG_PRESSED) != 0) {
setPressed(false);
}
mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
}
final boolean deepPress =
motionClassification == MotionEvent.CLASSIFICATION_DEEP_PRESS;
if (deepPress && hasPendingLongPressCallback()) {
// process the long click action immediately
removeLongPressCallback();
checkForLongClick(
0 /* send immediately */,
x,
y,
TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS);
}
break;
}
return true;
}
return false;
}
基于Android 10.0的源码剖析
本文以TextView#setText为切入口, 分析Choreographer的实现机制.
调用链:
TextView#setText -> checkForRelayout -> requestLayout -> invalidate -> invalidateInternal -> ViewGroup#invalidateChild -> ViewGroup#onDescendantInvalidated(硬件加速) -> ... -> DecorView#onDescendantInvalidated -> ViewRootImpl#onDescendantInvalidated -> ViewRootImpl#invalidate -> ViewRootImpl#scheduleTraversals
我们再来看ViewRootImpl#scheduleTraversals
的实现:
[ -> frameworks/base/core/java/android/view/ViewRootImpl.java ]
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
if (!mUnbufferedInputDispatch) {
scheduleConsumeBatchedInput();
}
notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}
根据上面代码, 引出Choreographer:
ViewRootImpl#scheduleTraversals -> Choreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, …)
[ -> frameworks/base/core/java/android/view/Choreographer.java ]
中文翻译是编舞者. 用于协调animations, input和drawing的时间.
Choreographer通过接收显示系统的时间脉冲(如垂直同步信号), 来完成下一帧的渲染工作.
通常App层通过高层抽象的API调用和Choreographer交互, 如ValueAnimator#start / View#postOnAnimation / View#postInvalidateOnAnimation / View#invalidate等.
// 每一帧的时间间隔(通常是16ms), 帧率为60fps
private long mFrameIntervalNanos;
// 帧率系数因子(通常是1)
private int mFPSDivisor = 1;
// Callback队列, 是一个元素为CallbackRecord的单向链表.
private final CallbackQueue[] mCallbackQueues;
// CALLBACK_INPUT(如Touch事件)
public static final int CALLBACK_INPUT = 0;
// CALLBACK_ANIMATION&CALLBACK_INSETS_ANIMATION(如各种动画)
public static final int CALLBACK_ANIMATION = 1;
public static final int CALLBACK_INSETS_ANIMATION = 2;
// CALLBACK_TRAVERSAL(如layout/draw等绘制操作)
public static final int CALLBACK_TRAVERSAL = 3;
// CALLBACK_COMMIT(当前帧时间延迟的上报和时间戳调整)
public static final int CALLBACK_COMMIT = 4;
接下来分析Choreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, …)过程.
public void postCallback(int callbackType, Runnable action, Object token) {
postCallbackDelayed(callbackType, action, token, 0);
}
public void postCallbackDelayed(int callbackType, Runnable action, Object token, long delayMillis) {
postCallbackDelayedInternal(callbackType, action, token, delayMillis);
}
private void postCallbackDelayedInternal(int callbackType, Object action, Object token, long delayMillis) {
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
// 根据dueTime时间序, 将callback添加到CallbackQueue队列
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
// 根据dueTime决定是否立即执行callback
if (dueTime <= now) {
scheduleFrameLocked(now);
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
msg.arg1 = callbackType;
// 异步消息, 不受同步栅栏SyncBarrier影响
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, dueTime);
}
}
}
Choreographer#postCallback逻辑:
(1) 封装CallbackRecord对象. mCallbackPool为用于循环复用的对象池.
private CallbackRecord obtainCallbackLocked(long dueTime, Object action, Object token) {
CallbackRecord callback = mCallbackPool;
if (callback == null) {
callback = new CallbackRecord();
} else {
mCallbackPool = callback.next;
callback.next = null;
}
callback.dueTime = dueTime;
callback.action = action;
callback.token = token;
return callback;
}
CallbackRecord数据结构为:
next
: 下一个CallbackRecord元素callbackType
: callback类型dueTime
: 到期时间action
: 下一帧要做的事情token
: callback令牌(2) 执行callback操作.
如果dueTime时间到了, 则调用scheduleFrameLocked立即执行
如果dueTime时间没到, 则封装并向FrameHandler发送异步消息MSG_DO_SCHEDULE_CALLBACK
.
FrameHandler是一个Handler, 用于执行Choreographer中的操作:
private final class FrameHandler extends Handler {
public FrameHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_DO_FRAME: // 执行帧操作
doFrame(System.nanoTime(), 0);
break;
case MSG_DO_SCHEDULE_VSYNC: // 执行vsync
doScheduleVsync();
break;
case MSG_DO_SCHEDULE_CALLBACK: // 执行callback
doScheduleCallback(msg.arg1);
break;
}
}
}
执行callback操作:
void doScheduleCallback(int callbackType) {
synchronized (mLock) {
if (!mFrameScheduled) {
final long now = SystemClock.uptimeMillis();
// 检查dueTime到期时间
if (mCallbackQueues[callbackType].hasDueCallbacksLocked(now)) {
scheduleFrameLocked(now);
}
}
}
}
不管同步还是异步, 最终都执行到scheduleFrameLocked.
private void scheduleFrameLocked(long now) {
if (!mFrameScheduled) {
mFrameScheduled = true;
if (USE_VSYNC) {
// 判断当前运行的Looper是否为FrameHandler对应的Looper
if (isRunningOnLooperThreadLocked()) {
scheduleVsyncLocked();
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
msg.setAsynchronous(true);
mHandler.sendMessageAtFrontOfQueue(msg);
}
} else {
// sFrameDelay为10ms
final long nextFrameTime = Math.max(mLastFrameTimeNanos / TimeUtils.NANOS_PER_MS + sFrameDelay, now);
Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, nextFrameTime);
}
}
}
scheduleFrameLocked逻辑:
USE_VSYNC
: 是否使用Vsync机制, 默认是true.
1.Vsync机制
首先确保执行的Looper是在FrameHandler对应的Looper.
如果是则可以直接执行; 如果不是需要向FrameHandler发送类型为MSG_DO_SCHEDULE_VSYNC
的异步消息
void doScheduleVsync() {
synchronized (mLock) {
if (mFrameScheduled) {
scheduleVsyncLocked();
}
}
}
最终都会执行到scheduleVsyncLocked
2.非Vsync机制
通过消息循环机制, 定时向FrameHandler发送类型为MSG_DO_FRAME
的异步消息. 执行doFrame从而刷新一帧数据.
下面的过程都是分析Vsync机制.
private void scheduleVsyncLocked() {
mDisplayEventReceiver.scheduleVsync();
}
Choreographer通过FrameDisplayEventReceiver接收来自Native层显示系统的Vsync垂直同步脉冲信号.
class FrameDisplayEventReceiver extends DisplayEventReceiver
首先看一下超类DisplayEventReceiver
:
public abstract class DisplayEventReceiver {
private long mReceiverPtr;
@FastNative
private static native void nativeScheduleVsync(long receiverPtr);
// 接收Vsync垂直同步信号, 在该方法中需要渲染一帧数据, 然后调用scheduleVsync启动下一个Vsync过程
// timestampNanos为接收到Vsync信号的时间戳, frame表示帧序号
public void onVsync(long timestampNanos, long physicalDisplayId, int frame) {
}
public void scheduleVsync() {
if (mReceiverPtr == 0) {
Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event "
+ "receiver has already been disposed.");
} else {
nativeScheduleVsync(mReceiverPtr);
}
}
// Called from native code.
private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) {
onVsync(timestampNanos, physicalDisplayId, frame);
}
...
}
调用链: DisplayEventReceiver#scheduleVsync -> nativeScheduleVsync
由此可知Vsync机制是Native实现的.
1.Vsync机制Native层实现:
[ -> frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp ]
static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
sp<NativeDisplayEventReceiver> receiver =
reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
status_t status = receiver->scheduleVsync();
if (status) {
String8 message;
message.appendFormat("Failed to schedule next vertical sync pulse. status=%d", status);
jniThrowRuntimeException(env, message.string());
}
}
[ -> frameworks/base/libs/androidfw/DisplayEventDispatcher.cpp ]
status_t DisplayEventDispatcher::scheduleVsync() {
if (!mWaitingForVsync) {
ALOGV("dispatcher %p ~ Scheduling vsync.", this);
// Drain all pending events.
nsecs_t vsyncTimestamp;
PhysicalDisplayId vsyncDisplayId;
uint32_t vsyncCount;
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "",
this, ns2ms(static_cast<nsecs_t>(vsyncTimestamp)));
}
status_t status = mReceiver.requestNextVsync();
if (status) {
ALOGW("Failed to request next vsync, status=%d", status);
return status;
}
mWaitingForVsync = true;
}
return OK;
}
[ -> frameworks/native/libs/gui/DisplayEventReceiver.cpp ]
status_t DisplayEventReceiver::requestNextVsync() {
if (mEventConnection != nullptr) {
mEventConnection->requestNextVsync();
return NO_ERROR;
}
return NO_INIT;
}
2.启动Vsync过程:
DisplayEventReceiver#scheduleVsync -> nativeScheduleVsync -> JNI -> android_view_DisplayEventReceiver#nativeScheduleVsync -> DisplayEventDispatcher#scheduleVsync -> DisplayEventReceiver#requestNextVsync
更底层的实现细节暂时就不追究了.
3.接收Vsync垂直脉冲信号
调用链: Native层 -> DisplayEventReceiver#dispatchVsync -> onVsync
再看一下实现类FrameDisplayEventReceiver
:
private final class FrameDisplayEventReceiver extends DisplayEventReceiver implements Runnable {
@Override
public void onVsync(long timestampNanos, long physicalDisplayId, int frame) {
long now = System.nanoTime();
// Vsync产生的时间不能大于当前时间(如果大于, 说明Vsync机制出问题了)
if (timestampNanos > now) {
timestampNanos = now;
}
// 一次只能执行一个Vsync同步信号(如果上一个Vsync同步信号没执行完成, 则不能执行下一个)
if (mHavePendingVsync) {
Log.w(TAG, "Already have a pending vsync event. There should only be one at a time.");
} else {
mHavePendingVsync = true;
}
mTimestampNanos = timestampNanos;
mFrame = frame;
// 发送异步消息(异步消息执行不受SyncBarrier限制)
Message msg = Message.obtain(mHandler, this);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
}
@Override
public void run() {
mHavePendingVsync = false;
doFrame(mTimestampNanos, mFrame);
}
...
}
Native层的Vsync垂直同步脉冲信号会回传到Java层的FrameDisplayEventReceiver#onVsync
.
该方法又向FrameHandler发送包含Runnable的异步信号, 在Runnable#run方法中又会触发doFrame. 至此才真正触发帧渲染的操作.
这里补充一点:
对于非Vsync机制, 是通过向FrameHandler发MSG_DO_FRAME
异步消息, 触发doFrame, 实现刷新一帧的. 为了避免掉帧, 非Vsync是每隔10ms
发送一次消息.
不管是否Vsync机制, 都是每隔16ms刷新一帧. 只不过Vsync机制通过Native层的垂直脉冲控制帧频率; 而非Vsync机制通过Handler机制控制.
// frameTimeNanos表示接收到Vsync垂直同步脉冲信号的时间戳
void doFrame(long frameTimeNanos, int frame) {
final long startNanos;
synchronized (mLock) {
if (!mFrameScheduled) {
return; // no work to do
}
long intendedFrameTimeNanos = frameTimeNanos;
startNanos = System.nanoTime();
// 计算从接收到Vsync垂直同步脉冲信号到真正执行doFrame, 中间的延迟时间
final long jitterNanos = startNanos - frameTimeNanos;
// 检查掉帧
if (jitterNanos >= mFrameIntervalNanos) {
// 计算跳帧数
final long skippedFrames = jitterNanos / mFrameIntervalNanos;
// 跳帧数超过30, Log提示主线程中做了过多工作.
if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) {
Log.i(TAG, ...);
}
final long lastFrameOffset = jitterNanos % mFrameIntervalNanos;
// 计算当前帧的时间戳(必须是mFrameIntervalNanos的整数倍)
frameTimeNanos = startNanos - lastFrameOffset;
}
// 若当前帧的时间戳小于上一帧的时间戳, 可能是VSync机制出了问题, 则再执行一次Vsync垂直同步信号
if (frameTimeNanos < mLastFrameTimeNanos) {
scheduleVsyncLocked();
return;
}
if (mFPSDivisor > 1) {
// 若距离上一帧的时间小于帧之间的时间间隔, 则再执行一次Vsync垂直同步信号
long timeSinceVsync = frameTimeNanos - mLastFrameTimeNanos;
if (timeSinceVsync < (mFrameIntervalNanos * mFPSDivisor) && timeSinceVsync > 0) {
scheduleVsyncLocked();
return;
}
}
// 设置当前帧信息(包括接收Vsync垂直同步脉冲信号的时间戳 和 当前帧绘制的时间戳)
mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos);
mFrameScheduled = false;
// 将当前帧的时间戳赋值给mLastFrameTimeNanos
mLastFrameTimeNanos = frameTimeNanos;
}
// 真正开始渲染当前帧数据, 执行时间戳为frameTimeNanos
try {
AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS);
// 执行类型为CALLBACK_INPUT事件(如Touch事件)
mFrameInfo.markInputHandlingStart();
doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
// 执行类型为CALLBACK_ANIMATION事件(如各种动画)
mFrameInfo.markAnimationsStart();
doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameTimeNanos);
// 执行类型为CALLBACK_TRAVERSAL事件(如layout/draw等重绘操作)
mFrameInfo.markPerformTraversalsStart();
doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
// 执行类型为CALLBACK_COMMIT事件, 作为结束标识(当前帧时间延迟的上报和时间戳调整)
doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
} finally {
AnimationUtils.unlockAnimationClock();
}
}
doFrame逻辑:
(1) 确认当前帧执行的时间戳.
由于接收到Vsync垂直同步脉冲信号的时间和真正调用doFrame的时间可能存在延迟, 因此可能会有跳帧或掉帧的可能.
结合跳帧, 计算出当前帧执行的时间戳, 这个时间戳必须是帧时间间隔的整数倍.
(2) 渲染当前帧数据.
渲染一帧数据, 依次执行如下类型的doCallbacks操作:
CALLBACK_INPUT
CALLBACK_ANIMATION
CALLBACK_INSETS_ANIMATION
CALLBACK_TRAVERSAL
CALLBACK_COMMIT
void doCallbacks(int callbackType, long frameTimeNanos) {
CallbackRecord callbacks;
synchronized (mLock) {
final long now = System.nanoTime();
// 获取dueTime小于当前时间戳的所有callback记录
callbacks = mCallbackQueues[callbackType].extractDueCallbacksLocked(now / TimeUtils.NANOS_PER_MS);
if (callbacks == null) {
return;
}
mCallbacksRunning = true;
if (callbackType == Choreographer.CALLBACK_COMMIT) {
// 计算从CALLBACK_INPUT到CALLBACK_TRAVERSAL中间执行过程的时间
final long jitterNanos = now - frameTimeNanos;
// 如果多于2帧的时间间隔, 则调整当前帧的时间戳, 并赋值给mLastFrameTimeNanos
if (jitterNanos >= 2 * mFrameIntervalNanos) {
final long lastFrameOffset = jitterNanos % mFrameIntervalNanos + mFrameIntervalNanos;
frameTimeNanos = now - lastFrameOffset;
mLastFrameTimeNanos = frameTimeNanos;
}
}
}
try {
// 遍历并执行上述所有callback记录
for (CallbackRecord c = callbacks; c != null; c = c.next) {
c.run(frameTimeNanos);
}
} finally {
// 回收已执行完的callback记录
synchronized (mLock) {
mCallbacksRunning = false;
do {
final CallbackRecord next = callbacks.next;
recycleCallbackLocked(callbacks);
callbacks = next;
} while (callbacks != null);
}
}
}
doCallbacks逻辑:
(1) 从CallbackQueue[]数组中取出所有类型为callbackType且满足dueTime到期时间的CallbackRecord记录(单链表).
(2) 遍历上述CallbackRecord单链表, 执行对应的Runnable操作
(3) 回收上述CallbackRecord单链表, 也就是放到mCallbackPool对象池
当callbackType为CALLBACK_COMMIT
时:
如果从CALLBACK_INPUT到CALLBACK_TRAVERSAL中间执行过程的时间超过2帧的时间间隔, 则调整当前帧的时间戳, 并赋值给mLastFrameTimeNanos.
[ -> frameworks/base/core/java/android/view/ViewRootImpl.java ]
1.CALLBACK_INPUT
对应的Runnable为ConsumeBatchedInputRunnable:
final ConsumeBatchedInputRunnable mConsumedBatchedInputRunnable = new ConsumeBatchedInputRunnable();
final class ConsumeBatchedInputRunnable implements Runnable {
@Override
public void run() {
doConsumeBatchedInput(mChoreographer.getFrameTimeNanos());
}
}
2.CALLBACK_ANIMATION
对应的Runnable为InvalidateOnAnimationRunnable:
final class InvalidateOnAnimationRunnable implements Runnable {
@Override
public void run() {
final int viewCount;
final int viewRectCount;
synchronized (this) {
mPosted = false;
viewCount = mViews.size();
if (viewCount != 0) {
mTempViews = mViews.toArray(mTempViews != null
? mTempViews : new View[viewCount]);
mViews.clear();
}
viewRectCount = mViewRects.size();
if (viewRectCount != 0) {
mTempViewRects = mViewRects.toArray(mTempViewRects != null
? mTempViewRects : new AttachInfo.InvalidateInfo[viewRectCount]);
mViewRects.clear();
}
}
for (int i = 0; i < viewCount; i++) {
mTempViews[i].invalidate();
mTempViews[i] = null;
}
for (int i = 0; i < viewRectCount; i++) {
final View.AttachInfo.InvalidateInfo info = mTempViewRects[i];
info.target.invalidate(info.left, info.top, info.right, info.bottom);
info.recycle();
}
}
}
3.CALLBACK_INSETS_ANIMATION
对应的Runnable为InsetsController#mAnimCallback
mAnimCallback = () -> {
mAnimCallbackScheduled = false;
if (mAnimationControls.isEmpty()) {
return;
}
mTmpFinishedControls.clear();
InsetsState state = new InsetsState(mState, true /* copySources */);
for (int i = mAnimationControls.size() - 1; i >= 0; i--) {
InsetsAnimationControlImpl control = mAnimationControls.get(i);
if (mAnimationControls.get(i).applyChangeInsets(state)) {
mTmpFinishedControls.add(control);
}
}
WindowInsets insets = state.calculateInsets(mFrame, mLastInsets.isRound(),
mLastInsets.shouldAlwaysConsumeSystemBars(), mLastInsets.getDisplayCutout(),
mLastLegacyContentInsets, mLastLegacyStableInsets, mLastLegacySoftInputMode,
null /* typeSideMap */);
mViewRoot.mView.dispatchWindowInsetsAnimationProgress(insets);
for (int i = mTmpFinishedControls.size() - 1; i >= 0; i--) {
dispatchAnimationFinished(mTmpFinishedControls.get(i).getAnimation());
}
};
4.CALLBACK_TRAVERSAL
对应的Runnable为TraversalRunnable:
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
基于Android 10.0的源码剖析
本文以View的requestLayout/invalidate/postInvalidate为切入口, 引申到ViewRootImpl过程分析.
主要按照下面3个步骤:
1.requestLayout / invalidate / postInvalidate的异同
2.ViewRootImpl过程
3.常见问题分析
[ -> frameworks/base/core/java/android/view/View.java ]
public void requestLayout() {
if (mMeasureCache != null) mMeasureCache.clear();
// 步骤1
if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == null) {
ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot != null && viewRoot.isInLayout()) {
if (!viewRoot.requestLayoutDuringLayout(this)) {
return;
}
}
mAttachInfo.mViewRequestingLayout = this;
}
// 步骤2
mPrivateFlags |= PFLAG_FORCE_LAYOUT;
mPrivateFlags |= PFLAG_INVALIDATED;
if (mParent != null && !mParent.isLayoutRequested()) {
mParent.requestLayout();
}
if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == this) {
mAttachInfo.mViewRequestingLayout = null;
}
}
调用时机:
当某些变化导致原有View树的layout发生变化, 可以调用requestLayout重新布局View树.
1.关于requestLayout的叠加
(1) 尽量不要在layout过程中又调用requestLayout.
(2) 如果非要叠加调用requestLayout, 则将当前作出该请求的View先放入mLayoutRequesters列表, 等到调用ViewRootImpl#performLayout的时候再取出mLayoutRequesters列表依次调用各个View#requestLayout. 如果当前正在处理mLayoutRequesters列表, 则不要再次触发requestLayout.
2.mParent.requestLayout()
(1) 我们先搞清楚mParent是啥?
mParent的类型是ViewParent, 通过代码溯源View#assignParent, 可以得出如下结论:
DecorView(即根View)对应的mParent是ViewRootImpl, 普通子View(非根View)对应的mParent是子View的父View(即ViewGroup)
(2) requestLayout调用过程?
该过程是一个从 子View -> 父View -> DecorView -> ViewRootImpl 层层往上的递归调用过程.
View#requestLayout -> ViewGroup#requestLayout -> ... -> DecorView#requestLayout -> ViewRootImpl#requestLayout
[ -> frameworks/base/core/java/android/view/View.java ]
public void invalidate() {
invalidate(true);
}
public void invalidate(boolean invalidateCache) {
invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
}
void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache, boolean fullInvalidate) {
if (skipInvalidate()) {
return;
}
...
// Propagate the damage rectangle to the parent view.
final AttachInfo ai = mAttachInfo;
final ViewParent p = mParent;
if (p != null && ai != null && l < r && t < b) {
final Rect damage = ai.mTmpInvalRect;
damage.set(l, t, r, b);
p.invalidateChild(this, damage);
}
...
}
[ -> frameworks/base/core/java/android/view/ViewGroup.java ]
@Override
public final void invalidateChild(View child, final Rect dirty) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null && attachInfo.mHardwareAccelerated) {
// HW accelerated fast path
onDescendantInvalidated(child, child);
return;
}
ViewParent parent = this;
if (attachInfo != null) {
final int[] location = attachInfo.mInvalidateChildLocation;
location[CHILD_LEFT_INDEX] = child.mLeft;
location[CHILD_TOP_INDEX] = child.mTop;
...
do {
...
parent = parent.invalidateChildInParent(location, dirty);
...
} while (parent != null);
}
}
1. 调用时机:
当前View树需要重绘时. 如果当前View可见, 则会调到onDraw方法.
该方法必须在UI线程调用.
2. View#invalidate的调用逻辑:
从子View -> 父View -> DecorView -> ViewRootImpl 从子到父层层调用.
(1) 硬件加速:
ViewGroup#onDescendantInvalidated -> ...-> DecorView#onDescendantInvalidated -> ViewRootImpl#onDescendantInvalidated
(2) 非硬件加速:
ViewGroup#invalidateChild -> ViewGroup#invalidateChildInParent -> ... -> DecorView#invalidateChildInParent -> ViewRootImpl#invalidateChildInParent
3. skipInvalidate逻辑
private boolean skipInvalidate() {
return (mViewFlags & VISIBILITY_MASK) != VISIBLE && mCurrentAnimation == null &&
(!(mParent instanceof ViewGroup) ||
!((ViewGroup) mParent).isViewTransitioning(this));
}
如果当前View不可见并且当前没有动画时, 则不会invalidate执行重绘.
[ -> frameworks/base/core/java/android/view/View.java ]
public void postInvalidate() {
postInvalidateDelayed(0);
}
public void postInvalidateDelayed(long delayMilliseconds) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
attachInfo.mViewRootImpl.dispatchInvalidateDelayed(this, delayMilliseconds);
}
}
[ -> frameworks/base/core/java/android/view/ViewRootImpl.java ]
public void dispatchInvalidateDelayed(View view, long delayMilliseconds) {
Message msg = mHandler.obtainMessage(MSG_INVALIDATE, view);
mHandler.sendMessageDelayed(msg, delayMilliseconds);
}
调用时机:
和invalidate类似.
不同的是, postInvalidate通过发送一个消息到主线程的消息队列, 在消息队列中执行invalidate方法.
因此postInvalidate可以在非UI线程调用.
相同点:
(1) 都是从 子View -> 父View -> DecorView -> ViewRootImpl 从子到父层层调用.
(2) 都会导致View树重绘, 最终都会调用到ViewRootImpl#scheduleTraversals
不同点:
(1) requestLayout 在UI线程调用
(2) invalidate在UI线程调用. 当View树可见时, 会调用到onDraw
(3) postInvalidate可以在非UI线程调用. 逻辑和invalidate类似, 不同点是postInvalidate通过发消息方式, 使invalidate操作在消息队列里有序执行.
[ -> frameworks/base/core/java/android/view/ViewRootImpl.java ]
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
// 添加同步屏障
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
// 发送并执行遍历操作
mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
if (!mUnbufferedInputDispatch) {
scheduleConsumeBatchedInput();
}
notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
void doTraversal() {
if (mTraversalScheduled) {
mTraversalScheduled = false;
// 移除同步屏障
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
performTraversals();
}
}
1.同步屏障SyncBarrier
当调用postSyncBarrier后, MessageQueue中的同步消息将不能执行, 直到removeSyncBarrier才会执行. 这个不影响异步消息.
在设置了同步屏障后, 发送一个CALLBACK_TRAVERSAL
类型消息到Choreographer的消息队列.
在移除了同步屏障后, 执行performTraversals
private void performTraversals() {
...
// 如果当前View树中包含SurfaceView, 则执行surfaceCreated/surfaceChanged回调
if (mSurfaceHolder != null) {
if (mSurface.isValid()) {
mSurfaceHolder.mSurface = mSurface;
}
mSurfaceHolder.setSurfaceFrameSize(mWidth, mHeight);
if (mSurface.isValid()) {
if (!hadSurface) {
mSurfaceHolder.ungetCallbacks();
mIsCreating = true;
SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
if (callbacks != null) {
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceCreated(mSurfaceHolder);
}
}
surfaceChanged = true;
}
if (surfaceChanged || surfaceGenerationId != mSurface.getGenerationId()) {
SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
if (callbacks != null) {
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceChanged(mSurfaceHolder, lp.format, mWidth, mHeight);
}
}
}
mIsCreating = false;
}
}
...
// mWidth&mHeight为Frame宽高, lp为setView传进来的WindowManager.LayoutParams参数
int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
...
performLayout(lp, mWidth, mHeight);
...
// 调用OnGlobalLayoutListener#onGlobalLayout
if (triggerGlobalLayoutListener) {
mAttachInfo.mRecomputeGlobalAttributes = false;
mAttachInfo.mTreeObserver.dispatchOnGlobalLayout();
}
...
performDraw();
...
}
主要做了2件事:
(1) 如果View树中当前View为SurfaceView, 则执行surfaceCreated/surfaceChanged相关回调.
(2) 依次执行performMeasure -> performLayout -> performDraw
(3) OnGlobalLayoutListener#onGlobalLayout回调中可以获取到View的真是宽高. 因为该方法在performMeasure -> performLayout后面执行.
private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
boolean optical = isLayoutModeOptical(this);
if (optical != isLayoutModeOptical(mParent)) {
Insets insets = getOpticalInsets();
int oWidth = insets.left + insets.right;
int oHeight = insets.top + insets.bottom;
widthMeasureSpec = MeasureSpec.adjust(widthMeasureSpec, optical ? -oWidth : oWidth);
heightMeasureSpec = MeasureSpec.adjust(heightMeasureSpec, optical ? -oHeight : oHeight);
}
// Suppress sign extension for the low bytes
long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);
final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
// Optimize layout by avoiding an extra EXACTLY pass when the view is
// already measured as the correct size. In API 23 and below, this
// extra pass is required to make LinearLayout re-distribute weight.
final boolean specChanged = widthMeasureSpec != mOldWidthMeasureSpec
|| heightMeasureSpec != mOldHeightMeasureSpec;
final boolean isSpecExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY
&& MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY;
final boolean matchesSpecSize = getMeasuredWidth() == MeasureSpec.getSize(widthMeasureSpec)
&& getMeasuredHeight() == MeasureSpec.getSize(heightMeasureSpec);
final boolean needsLayout = specChanged
&& (sAlwaysRemeasureExactly || !isSpecExactly || !matchesSpecSize);
if (forceLayout || needsLayout) {
// first clears the measured dimension flag
mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET;
resolveRtlPropertiesIfNeeded();
int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key);
if (cacheIndex < 0 || sIgnoreMeasureCache) {
// measure ourselves, this should set the measured dimension flag back
onMeasure(widthMeasureSpec, heightMeasureSpec);
mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
} else {
long value = mMeasureCache.valueAt(cacheIndex);
// Casting a long to int drops the high 32 bits, no mask needed
setMeasuredDimensionRaw((int) (value >> 32), (int) value);
mPrivateFlags3 |= PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
}
mPrivateFlags |= PFLAG_LAYOUT_REQUIRED;
}
mOldWidthMeasureSpec = widthMeasureSpec;
mOldHeightMeasureSpec = heightMeasureSpec;
mMeasureCache.put(key, ((long) mMeasuredWidth) << 32 |
(long) mMeasuredHeight & 0xffffffffL); // suppress sign extension
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
setMeasuredDimensionRaw(measuredWidth, measuredHeight);
}
private void setMeasuredDimensionRaw(int measuredWidth, int measuredHeight) {
mMeasuredWidth = measuredWidth;
mMeasuredHeight = measuredHeight;
mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;
}
1. Measure过程调用链路:
ViewRootImpl#performMeasure -> View#measure -> View#onMeasure -> View#setMeasureDimension
2. 缓存策略
为了避免每次重复测量, 采用了缓存策略. 测量缓存数据结构LongSparseLongArray
.
其中key为MeasureSpec, value为MeasuredWidth/MeasuredHeight. 高32位代表宽度, 低32位代表高度.
// key
(long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL
// value
(long) mMeasuredWidth << 32 | (long) mMeasuredHeight & 0xffffffffL
3.测量过程
如果缓存中没有, 则需要测量方法View#onMeasure. 具体的测量宽高方式参考getDefaultSize.
其中size为建议大小getSuggestedMinimumWidth/Height, measureSpec为测量规范.
protected int getSuggestedMinimumWidth() {
return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
}
public static int getDefaultSize(int size, int measureSpec) {
int result = size;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
result = size;
break;
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result;
}
4.MeasureSpec
上面提到了int measureSpec为测量规范. 怎么理解这个测量规范呢? 可以用类MeasureSpec
来描述.
MeasureSpec由mode和size组成, 前2位为mode, 后30位为size. 之所以这么设计, 是出于节省内存考虑.
3种mode类型:
UNSPECIFIED
父View没有对子View做限制
EXACTLY
父View指定了子View的精确大小
AT_MOST
父View指定了子View的最大值, 子View最大到达这个最大值
public static class MeasureSpec {
private static final int MODE_SHIFT = 30;
private static final int MODE_MASK = 0x3 << MODE_SHIFT;
public static final int UNSPECIFIED = 0 << MODE_SHIFT;
public static final int EXACTLY = 1 << MODE_SHIFT;
public static final int AT_MOST = 2 << MODE_SHIFT;
@IntDef({UNSPECIFIED, EXACTLY, AT_MOST})
@Retention(RetentionPolicy.SOURCE)
public @interface MeasureSpecMode {}
public static int makeMeasureSpec(@IntRange(from = 0, to = (1 << MeasureSpec.MODE_SHIFT) - 1) int size, @MeasureSpecMode int mode) {
if (sUseBrokenMakeMeasureSpec) {
return size + mode;
} else {
return (size & ~MODE_MASK) | (mode & MODE_MASK);
}
}
@MeasureSpecMode
public static int getMode(int measureSpec) {
//noinspection ResourceType
return (measureSpec & MODE_MASK);
}
public static int getSize(int measureSpec) {
return (measureSpec & ~MODE_MASK);
}
}
private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth, int desiredWindowHeight) {
mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
}
public void layout(int l, int t, int r, int b) {
if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) {
onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec);
mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
}
int oldL = mLeft;
int oldT = mTop;
int oldB = mBottom;
int oldR = mRight;
boolean changed = isLayoutModeOptical(mParent) ?
setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);
if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
onLayout(changed, l, t, r, b);
if (shouldDrawRoundScrollbar()) {
if(mRoundScrollbarRenderer == null) {
mRoundScrollbarRenderer = new RoundScrollbarRenderer(this);
}
} else {
mRoundScrollbarRenderer = null;
}
mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnLayoutChangeListeners != null) {
ArrayList<OnLayoutChangeListener> listenersCopy =
(ArrayList<OnLayoutChangeListener>)li.mOnLayoutChangeListeners.clone();
int numListeners = listenersCopy.size();
for (int i = 0; i < numListeners; ++i) {
listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB);
}
}
}
final boolean wasLayoutValid = isLayoutValid();
mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;
if (!wasLayoutValid && isFocused()) {
mPrivateFlags &= ~PFLAG_WANTS_FOCUS;
if (canTakeFocus()) {
// We have a robust focus, so parents should no longer be wanting focus.
clearParentsWantFocus();
} else if (getViewRootImpl() == null || !getViewRootImpl().isInLayout()) {
// This is a weird case. Most-likely the user, rather than ViewRootImpl, called
// layout. In this case, there's no guarantee that parent layouts will be evaluated
// and thus the safest action is to clear focus here.
clearFocusInternal(null, /* propagate */ true, /* refocus */ false);
clearParentsWantFocus();
} else if (!hasParentWantsFocus()) {
// original requestFocus was likely on this view directly, so just clear focus
clearFocusInternal(null, /* propagate */ true, /* refocus */ false);
}
// otherwise, we let parents handle re-assigning focus during their layout passes.
} else if ((mPrivateFlags & PFLAG_WANTS_FOCUS) != 0) {
mPrivateFlags &= ~PFLAG_WANTS_FOCUS;
View focused = findFocus();
if (focused != null) {
// Try to restore focus as close as possible to our starting focus.
if (!restoreDefaultFocus() && !hasParentWantsFocus()) {
// Give up and clear focus once we've reached the top-most parent which wants
// focus.
focused.clearFocusInternal(null, /* propagate */ true, /* refocus */ false);
}
}
}
if ((mPrivateFlags3 & PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT) != 0) {
mPrivateFlags3 &= ~PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT;
notifyEnterOrExitForAutoFillIfNeeded(true);
}
}
1. Layout过程调用链路:
ViewRootImpl#performLayout -> View#layout -> View#onLayout
private void performDraw() {
...
final Canvas canvas = mSurface.lockCanvas(dirty);
canvas.setDensity(mDensity);
canvas.translate(-xoff, -yoff);
canvas.setScreenDensity(scalingRequired ? mNoncompatDensity : 0);
...
mView.draw(canvas);
surface.unlockCanvasAndPost(canvas);
}
performDraw调用流程:
draw(fullRedrawNeeded) -> drawSoftware(surface, mAttachInfo, xOffset, yOffset, scalingRequired, dirty, surfaceInsets) -> mView.draw(canvas)
public void draw(Canvas canvas) {
final int privateFlags = mPrivateFlags;
mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
// Step 1, draw the background, if needed
int saveCount;
drawBackground(canvas);
// skip step 2 & 5 if possible (common case)
final int viewFlags = mViewFlags;
boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;
boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;
if (!verticalEdges && !horizontalEdges) {
// Step 3, draw the content
onDraw(canvas);
// Step 4, draw the children
dispatchDraw(canvas);
drawAutofilledHighlight(canvas);
// Overlay is part of the content and draws beneath Foreground
if (mOverlay != null && !mOverlay.isEmpty()) {
mOverlay.getOverlayView().dispatchDraw(canvas);
}
// Step 6, draw decorations (foreground, scrollbars)
onDrawForeground(canvas);
// Step 7, draw the default focus highlight
drawDefaultFocusHighlight(canvas);
if (debugDraw()) {
debugDrawFocus(canvas);
}
// we're done...
return;
}
boolean drawTop = false;
boolean drawBottom = false;
boolean drawLeft = false;
boolean drawRight = false;
float topFadeStrength = 0.0f;
float bottomFadeStrength = 0.0f;
float leftFadeStrength = 0.0f;
float rightFadeStrength = 0.0f;
// Step 2, save the canvas' layers
int paddingLeft = mPaddingLeft;
final boolean offsetRequired = isPaddingOffsetRequired();
if (offsetRequired) {
paddingLeft += getLeftPaddingOffset();
}
int left = mScrollX + paddingLeft;
int right = left + mRight - mLeft - mPaddingRight - paddingLeft;
int top = mScrollY + getFadeTop(offsetRequired);
int bottom = top + getFadeHeight(offsetRequired);
if (offsetRequired) {
right += getRightPaddingOffset();
bottom += getBottomPaddingOffset();
}
final ScrollabilityCache scrollabilityCache = mScrollCache;
final float fadeHeight = scrollabilityCache.fadingEdgeLength;
int length = (int) fadeHeight;
// clip the fade length if top and bottom fades overlap
// overlapping fades produce odd-looking artifacts
if (verticalEdges && (top + length > bottom - length)) {
length = (bottom - top) / 2;
}
// also clip horizontal fades if necessary
if (horizontalEdges && (left + length > right - length)) {
length = (right - left) / 2;
}
if (verticalEdges) {
topFadeStrength = Math.max(0.0f, Math.min(1.0f, getTopFadingEdgeStrength()));
drawTop = topFadeStrength * fadeHeight > 1.0f;
bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, getBottomFadingEdgeStrength()));
drawBottom = bottomFadeStrength * fadeHeight > 1.0f;
}
if (horizontalEdges) {
leftFadeStrength = Math.max(0.0f, Math.min(1.0f, getLeftFadingEdgeStrength()));
drawLeft = leftFadeStrength * fadeHeight > 1.0f;
rightFadeStrength = Math.max(0.0f, Math.min(1.0f, getRightFadingEdgeStrength()));
drawRight = rightFadeStrength * fadeHeight > 1.0f;
}
saveCount = canvas.getSaveCount();
int topSaveCount = -1;
int bottomSaveCount = -1;
int leftSaveCount = -1;
int rightSaveCount = -1;
int solidColor = getSolidColor();
if (solidColor == 0) {
if (drawTop) {
topSaveCount = canvas.saveUnclippedLayer(left, top, right, top + length);
}
if (drawBottom) {
bottomSaveCount = canvas.saveUnclippedLayer(left, bottom - length, right, bottom);
}
if (drawLeft) {
leftSaveCount = canvas.saveUnclippedLayer(left, top, left + length, bottom);
}
if (drawRight) {
rightSaveCount = canvas.saveUnclippedLayer(right - length, top, right, bottom);
}
} else {
scrollabilityCache.setFadeColor(solidColor);
}
// Step 3, draw the content
onDraw(canvas);
// Step 4, draw the children
dispatchDraw(canvas);
// Step 5, draw the fade effect and restore layers
final Paint p = scrollabilityCache.paint;
final Matrix matrix = scrollabilityCache.matrix;
final Shader fade = scrollabilityCache.shader;
// must be restored in the reverse order that they were saved
if (drawRight) {
matrix.setScale(1, fadeHeight * rightFadeStrength);
matrix.postRotate(90);
matrix.postTranslate(right, top);
fade.setLocalMatrix(matrix);
p.setShader(fade);
if (solidColor == 0) {
canvas.restoreUnclippedLayer(rightSaveCount, p);
} else {
canvas.drawRect(right - length, top, right, bottom, p);
}
}
if (drawLeft) {
matrix.setScale(1, fadeHeight * leftFadeStrength);
matrix.postRotate(-90);
matrix.postTranslate(left, top);
fade.setLocalMatrix(matrix);
p.setShader(fade);
if (solidColor == 0) {
canvas.restoreUnclippedLayer(leftSaveCount, p);
} else {
canvas.drawRect(left, top, left + length, bottom, p);
}
}
if (drawBottom) {
matrix.setScale(1, fadeHeight * bottomFadeStrength);
matrix.postRotate(180);
matrix.postTranslate(left, bottom);
fade.setLocalMatrix(matrix);
p.setShader(fade);
if (solidColor == 0) {
canvas.restoreUnclippedLayer(bottomSaveCount, p);
} else {
canvas.drawRect(left, bottom - length, right, bottom, p);
}
}
if (drawTop) {
matrix.setScale(1, fadeHeight * topFadeStrength);
matrix.postTranslate(left, top);
fade.setLocalMatrix(matrix);
p.setShader(fade);
if (solidColor == 0) {
canvas.restoreUnclippedLayer(topSaveCount, p);
} else {
canvas.drawRect(left, top, right, top + length, p);
}
}
canvas.restoreToCount(saveCount);
drawAutofilledHighlight(canvas);
// Overlay is part of the content and draws beneath Foreground
if (mOverlay != null && !mOverlay.isEmpty()) {
mOverlay.getOverlayView().dispatchDraw(canvas);
}
// Step 6, draw decorations (foreground, scrollbars)
onDrawForeground(canvas);
if (debugDraw()) {
debugDrawFocus(canvas);
}
}
1.调用链路
ViewRootImpl#performDraw -> View#draw
2.draw绘制顺序
由下到上的绘制顺序.
(1) drawBackground
绘制背景
(2) save layer (当有水平或垂直fading edges时)
(3) onDraw
绘制当前View的内容
(4) dispatchDraw
绘制当前View的子View
(5) 绘制fading edges和restore layers(当有水平或垂直fading edges时)
(6) onDrawForeground
绘制前景或滚动条
(7) drawDefaultFocusHighlight
绘制获取焦点的View的Focus高亮
**1. 什么时候获取View的测量宽高? **
private void performTraversals() {
...
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
...
performLayout(lp, mWidth, mHeight);
...
if (triggerGlobalLayoutListener) {
mAttachInfo.mRecomputeGlobalAttributes = false;
mAttachInfo.mTreeObserver.dispatchOnGlobalLayout();
}
...
performDraw();
...
}
根据ViewRootImpl#scheduleTraversals的调用逻辑. dispatchOnGlobalLayout在performMeasure -> performLayout之后调用, 通过该回调可以获取到测量的宽高.
App层可以通过注册OnGlobalLayoutListener方式获取.
view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// view.getMeasuredWidth()/view.getMeasuredHeight()
...
}
});
2. 在子线程中可以更新UI吗?
在Activity#onResume之前, 可以在子线程中更新UI.
checkThread线程检查是在ViewRootImpl的方法中进行的 (如invalidate和requestLayout)
而通过溯源代码, ViewRootImpl是在ActivityThread#handleResumeActivity创建的. 在Activity#onResume之前ViewRootImpl还没创建, 所以也不会检查线程和绘制UI.
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
@Override
public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
checkThread();
...
}
void checkThread() {
if (mThread != Thread.currentThread()) {
throw new CalledFromWrongThreadException(
"Only the original thread that created a view hierarchy can touch its views.");
}
}
参考文档:
https://www.charlesproxy.com/download/
命令行安装:
(1) 安装GPG公钥
wget -q -O - https://www.charlesproxy.com/packages/apt/PublicKey | sudo apt-key add
(2) 添加charles仓库到源列表sources.list
sudo sh -c 'echo deb https://www.charlesproxy.com/packages/apt/ charles-proxy main > /etc/apt/sources.list.d/charles.list'
(3)升级源列表sources, 安装charles
sudo apt-get update
sudo apt-get install charles-proxy
破解网址:
https://www.zzzmode.com/mytools/charles/
(1) 从以上网址获取破解的charles.jar文件
(2) Charles安装目录下的charles.jar文件替换成破解的charles.jar
安装目录:
macOS: /Applications/Charles.app/Contents/Java/charles.jar
Windows: C:\Program Files\Charles\lib\charles.jar
Ubuntu: /usr/lib/charles-proxy/charles.jar
Ubuntu下文件替换:
sudo cp charles.jar /usr/lib/charles-proxy
Ubuntu cp命令
https://blog.csdn.net/lianchao668/article/details/8097113
手机连接xx.xx.xx.xx:8889代理后,即可抓取HTTP的包
此时还不能抓HTTPS的包, 需要安装证书.
(1) 手机连接charles代理
(2) 手机下载证书
Charles → Help → SSL Proxying → Install Charles Root Certificate on a Mobile Device or Remote Browser
此时会弹出一个提示窗
在手机QQ浏览器输入chls.pro/ssl
,下载charles-proxy-ssl-proxying-certificate.pem
证书
(3) 安装证书
设置 -> 密码、隐私与安全 -> 系统安全 -> 加密与凭据 -> 从SD卡安装 → 选择下载的pem证书
证书安装完后, 就可以抓取HTTPS的包了(仅对于Android 7.0以下设备)
对于Android 7.0及以上的设备HTTPS抓包, 除以上步骤外, 还要额外做一些处理.
主要有2种方式:
(1) ROOT方式
(2) 非ROOT方式
以小米手机为例. 其他三方机型找官方文档步骤类似.
(1) 手机解锁(只能Windows平台)
参考:
http://www.miui.com/unlock/download.html
1.进入“设置 -> 开发者选项 -> 设备解锁状态”中绑定账号和设备
2.手动进入Bootloader模式(关机后,同时按住开机键和音量下键)
3.下载解锁工具,解压zip包,运行miflash_unlock.exe
4.通过USB连接手机,点击 “解锁”按钮
(2) 下载线刷包
根据机型查找名称:
设备打包信息 → 当前打包分支信息, 机型Redmi Note 8对应的名称为ginkgo
下载线刷包:
下载包 → 线刷包,选择Dev&Alpha和Root,查找ginkgo对应的包,Rom Type选Root, 下载得到线刷包
(3) 执行刷机脚本
线刷包解压后得到如下脚本文件:
flash_all.bat / flash_all.sh (刷所有文件,清除用户数据,清除内置存储数据)
flash_all_except_data_storage.bat / flash_all_except_data_storage.sh (刷升级文件,保留用户数据和内置存储数据)
flash_all_except_storage.bat / flash_all_except_storage.sh (刷升级文件,清除用户数据,保留内置存储数据)
Windows环境运行bat脚本, Ubuntu环境运行sh脚本
手机进入fastboot模式(关机后长按开机+音量下键), 运行./flash_all.sh
直到运行完成, 一般会很快.
至此, 手机ROOT完成, 在设置中可以看到版本信息为开发版.
前面步骤已经介绍了SSL下载和安装过程.
接下来需要额外做的就是将SSL证书安装到系统证书目录.
(1) 将charles-proxy-ssl-proxying-certificate.pem证书文件上传pull到电脑端.
(2) 运行命令openssl x509 -subject_hash_old -in charles-proxy-ssl-proxying-certificate.pem, 生成md5(第一行数字即为md5)
(3) 将pem证书文件更名为< md5>.0
(4) 将更名后的文件push到手机目录: sudo adb push < md5>.0 /system/etc/security/cacert
如果出现权限或只读问题,则执行adb root命令:
adb root
adb disable-verity
adb reboot
adb root
adb remount
检查证书是否安装成功:在 设置 → 安全 → 加密与凭据 → 信任的凭据 可以看到.
至此Android 7.0及以上的设备都可以抓取所有APP的HTTPS请求了.
这种方式只能抓取当前APP的HTTPS请求.
(1) 在AndroidManifest.xml文件中配置android:networkSecurityConfig属性
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:networkSecurityConfig="@xml/network_security_config" ... >
...
</application>
</manifest>
(2) 创建并配置res/xml/network_security_config.xml文件
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" overridePins="true" /> <!--信任系统证书-->
<certificates src="user" overridePins="true" /> <!--信任用户证书-->
</trust-anchors>
</base-config>
</network-security-config>
然后重新打包安装抓包就可以了.
]]>基于Android 10.0的源码剖析, 站在Luoshengyang/Innost/Gityuan肩膀上.
常见的Window类型如下:
完整的Window类型及解释, 可以参考源码WindowManager
在Client端, WindowManager.LayoutParams的x & y & type用来确定Window的三维坐标位置.
public static class WindowManager.LayoutParams extends ViewGroup.LayoutParams
implements Parcelable {
// x坐标
public int x;
// y坐标
public int y;
// 类型(WMS根据type确定Z-Order)
public int type;
...
}
在WMS端, WindowState表示一个窗口实例, 其中属性mBaseLayer和mSubLayer用来确定Z-Order
[ -> frameworks/base/services/core/java/com/android/server/wm/WindowState.java ]
// 计算主序时乘以10000, 目的是为同类型的多个窗口预留空间和Z-Order调整
static final int TYPE_LAYER_MULTIPLIER = 10000;
// 计算主序时加1000, 目的是确定相同主序的子窗口相对于父窗口的上下位置
static final int TYPE_LAYER_OFFSET = 1000;
// 表示主序
final int mBaseLayer;
// 表示子序
final int mSubLayer;
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a,
int viewVisibility, final DisplayContent displayContent) {
...
// 若当前窗口类型为子窗口
if ((mAttrs.type >= FIRST_SUB_WINDOW && mAttrs.type <= LAST_SUB_WINDOW)) {
// 计算主序, 主序与父窗口一致,主序大的窗口位于主序小的窗口上面
mBaseLayer = mPolicy.getWindowLayerLw(parentWindow) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
// 计算子序
mSubLayer = mPolicy.getSubWindowLayerFromTypeLw(a.type);
...
} else { // 若当前窗口类型不是子窗口
// 计算主序
mBaseLayer = mPolicy.getWindowLayerLw(this) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
// 子序为0
mSubLayer = 0;
...
}
...
}
[ -> frameworks/base/services/core/java/com/android/server/policy/WindowManagerPolicy.java ]
default int getWindowLayerLw(WindowState win) {
return getWindowLayerFromTypeLw(win.getBaseType(), win.canAddInternalSystemWindow());
}
default int getWindowLayerFromTypeLw(int type) {
if (isSystemAlertWindowType(type)) {
throw new IllegalArgumentException("Use getWindowLayerFromTypeLw() or getWindowLayerLw() for alert window types");
}
return getWindowLayerFromTypeLw(type, false /* canAddInternalSystemWindow */);
}
default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow) {
if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
return APPLICATION_LAYER; // 2
}
switch (type) {
case TYPE_WALLPAPER:
// wallpaper is at the bottom, though the window manager may move it.
return 1;
case TYPE_PRESENTATION:
case TYPE_PRIVATE_PRESENTATION:
case TYPE_DOCK_DIVIDER:
case TYPE_QS_DIALOG:
return APPLICATION_LAYER;
case TYPE_PHONE:
return 3;
case TYPE_SEARCH_BAR:
case TYPE_VOICE_INTERACTION_STARTING:
return 4;
case TYPE_VOICE_INTERACTION:
// voice interaction layer is almost immediately above apps.
return 5;
case TYPE_INPUT_CONSUMER:
return 6;
case TYPE_SYSTEM_DIALOG:
return 7;
case TYPE_TOAST:
// toasts and the plugged-in battery thing
return 8;
case TYPE_PRIORITY_PHONE:
// SIM errors and unlock. Not sure if this really should be in a high layer.
return 9;
case TYPE_SYSTEM_ALERT:
// like the ANR / app crashed dialogs
// Type is deprecated for non-system apps. For system apps, this type should be
// in a higher layer than TYPE_APPLICATION_OVERLAY.
return canAddInternalSystemWindow ? 13 : 10;
case TYPE_APPLICATION_OVERLAY:
return 12;
case TYPE_DREAM:
// used for Dreams (screensavers with TYPE_DREAM windows)
return 14;
case TYPE_INPUT_METHOD:
// on-screen keyboards and other such input method user interfaces go here.
return 15;
case TYPE_INPUT_METHOD_DIALOG:
// on-screen keyboards and other such input method user interfaces go here.
return 16;
case TYPE_STATUS_BAR:
return 17;
case TYPE_STATUS_BAR_PANEL:
return 18;
case TYPE_STATUS_BAR_SUB_PANEL:
return 19;
case TYPE_KEYGUARD_DIALOG:
return 20;
case TYPE_VOLUME_OVERLAY:
// the on-screen volume indicator and controller shown when the user
// changes the device volume
return 21;
case TYPE_SYSTEM_OVERLAY:
// the on-screen volume indicator and controller shown when the user
// changes the device volume
return canAddInternalSystemWindow ? 22 : 11;
case TYPE_NAVIGATION_BAR:
// the navigation bar, if available, shows atop most things
return 23;
case TYPE_NAVIGATION_BAR_PANEL:
// some panels (e.g. search) need to show on top of the navigation bar
return 24;
case TYPE_SCREENSHOT:
// screenshot selection layer shouldn't go above system error, but it should cover
// navigation bars at the very least.
return 25;
case TYPE_SYSTEM_ERROR:
// system-level error dialogs
return canAddInternalSystemWindow ? 26 : 10;
case TYPE_MAGNIFICATION_OVERLAY:
// used to highlight the magnified portion of a display
return 27;
case TYPE_DISPLAY_OVERLAY:
// used to simulate secondary display devices
return 28;
case TYPE_DRAG:
// the drag layer: input for drag-and-drop is associated with this window,
// which sits above all other focusable windows
return 29;
case TYPE_ACCESSIBILITY_OVERLAY:
// overlay put by accessibility services to intercept user interaction
return 30;
case TYPE_SECURE_SYSTEM_OVERLAY:
return 31;
case TYPE_BOOT_PROGRESS:
return 32;
case TYPE_POINTER:
// the (mouse) pointer layer
return 33;
default:
return APPLICATION_LAYER;
}
}
从主序的确定过程可知:
从大的分类上来说, 系统窗口 > 子窗口 > 应用窗口, 整体上type和主序存在正相关.
但是在单个分类里, 单个窗口的type大小和主序大小不存在正相关或负相关.
主序越大, 窗口Z-Order越靠上面.
default int getSubWindowLayerFromTypeLw(int type) {
switch (type) {
case TYPE_APPLICATION_PANEL:
case TYPE_APPLICATION_ATTACHED_DIALOG:
return APPLICATION_PANEL_SUBLAYER; // 1
case TYPE_APPLICATION_MEDIA:
return APPLICATION_MEDIA_SUBLAYER; // -2
case TYPE_APPLICATION_MEDIA_OVERLAY:
return APPLICATION_MEDIA_OVERLAY_SUBLAYER; // -1
case TYPE_APPLICATION_SUB_PANEL:
return APPLICATION_SUB_PANEL_SUBLAYER; // 2
case TYPE_APPLICATION_ABOVE_SUB_PANEL:
return APPLICATION_ABOVE_SUB_PANEL_SUBLAYER; // 3
}
return 0;
}
窗口子序,用来描述子窗口相对于父窗口的位置.
子序>0表示位于父窗口上面,子序<0表示位于父窗口下面,子序=0表示不是子窗口.
子序越大, 子窗口相对于父窗口越靠上面.
从子序的确定过程可知:
子窗口的type大小和子序大小不存在正相关或负相关.
(1) 视频相关的子窗口类型(TYPE_APPLICATION_MEDIA和TYPE_APPLICATION_MEDIA_OVERLAY)位于父窗口的下面.
(2) 其他类型子窗口位于父窗口上面.
确定了主序和子序, 之后的过程后面再分析, 此处不细纠.
App开发中常见的涉及Window的地方: Activity / Dialog / PopupWindow / Toast / 输入法.
通过查看相关源码, 得出如下结论:
Activity: 创建PhoneWindow, 类型为TYPE_BASE_APPLICATION
Dialog: 创建PhoneWindow, 未指定类型
PopupWindow: 未创建Window, 类型为TYPE_APPLICATION_PANEL
Toast: 类型为TYPE_TOAST
输入法(IMM): 类型为TYPE_INPUT_METHOD
基于Android 10.0的源码剖析, 站在Luoshengyang/Innost/Gityuan肩膀上.
本文主要分析内容:
1.SystemUI(如StatusBar)和Activity中Window的创建和添加.
2.Activity/PhoneWindow/DecorView/StatusBar/ViewRootImpl之间的关系.
限于篇幅原因, WindowManager.addView具体的添加过程在下一篇文章分析.
frameworks/base/packages/SystemUI/src/com/android/systemui/SystemBars.java
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/core/java/android/app/Activity.java
frameworks/base/core/java/android/view/WindowManagerImpl.java
frameworks/base/core/java/android/view/Window.java
frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java
frameworks/base/core/java/com/android/internal/policy/DecorView.java
frameworks/base/packages/SystemUI/AndroidManifest.xml
frameworks/base/packages/SystemUI/res/values/config.xml
frameworks/base/packages/SystemUI/res/layout/super_status_bar.xml
frameworks/base/packages/SystemUI/res/layout/status_bar.xml
frameworks/base/core/res/res/layout/screen_simple.xml
TODO
SystemUI包括很多子类, 状态栏StatusBar是最常见的一种. 本文以StatusBar为例进行分析.
SystemUI运行的进程是SystemUIApplication.
[ -> frameworks/base/packages/SystemUI/AndroidManifest.xml]
<application
android:name=".SystemUIApplication"
android:persistent="true"
android:allowClearUserData="false"
android:allowBackup="false"
android:hardwareAccelerated="true"
android:label="@string/app_label"
android:icon="@drawable/icon"
android:process="com.android.systemui"
android:supportsRtl="true"
android:theme="@style/Theme.SystemUI"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true"
android:appComponentFactory="androidx.core.app.CoreComponentFactory">
...
<service android:name="SystemUIService" android:exported="true"/>
...
</application>
SystemUI调用链:
SystemUIApplication.onCreate -> startSecondaryUserServicesIfNeeded -> startServicesIfNeeded -> mServices[i].start() -> SystemBars.start
[ -> frameworks/base/packages/SystemUI/src/com/android/systemui/SystemBars.java ]
public class SystemBars extends SystemUI {
private SystemUI mStatusBar;
@Override
public void start() {
createStatusBarFromConfig();
}
private void createStatusBarFromConfig() {
// 从config.xml中读取className-"com.android.systemui.statusbar.phone.StatusBar"
final String clsName = mContext.getString(R.string.config_statusBarComponent);
// 反射创建StatusBar对象
Class<?> cls = mContext.getClassLoader().loadClass(clsName);
mStatusBar = (SystemUI) cls.newInstance();
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
// 将StatusBar注入系统UI的根组件
if (mStatusBar instanceof StatusBar) {
SystemUIFactory.getInstance().getRootComponent()
.getStatusBarInjector()
.createStatusBar((StatusBar) mStatusBar);
}
// 创建状态栏View, 并将其添加到WindowManager
mStatusBar.start();
}
}
SystemBars#start做的事情:
1.读取配置文件中的属性config_statusBarComponent, 得到字符串className为StatusBar的字符串.
[ -> frameworks/base/packages/SystemUI/res/values/config.xml ]
<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.StatusBar</string>
2.利用反射机制创建StatusBar对象, 创建状态栏View并将其添加到WindowManager.
[ -> frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java ]
public class StatusBar extends SystemUI implements DemoMode,
ActivityStarter, OnUnlockMethodChangedListener,
OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
ColorExtractor.OnColorsChangedListener, ConfigurationListener,
StatusBarStateController.StateListener, ShadeController,
ActivityLaunchAnimator.Callback, AmbientPulseManager.OnAmbientChangedListener,
AppOpsController.Callback {
protected WindowManager mWindowManager;
protected IWindowManager mWindowManagerService;
// 状态栏最外层View
protected StatusBarWindowView mStatusBarWindow;
// CollapsedStatusBarFragment的根View(即StatusBarWindowView的childView)
protected PhoneStatusBarView mStatusBarView;
@Override
public void start() {
...
// 获取WindowManagerImpl
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
// 获取IWindowManager.Stub.Proxy
mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
...
// 创建状态栏View, 并将其添加到WindowManager
createAndAddWindows(result);
...
}
...
}
// 创建状态栏View, 并将其添加到WindowManager
public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
// 根据布局文件super_status_bar.xml创建StatusBarWindowView. 参考【第2.3.3节】
makeStatusBarView(result);
mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
// 将StatusBarWindowView添加到WindowManager. 参考【第2.4节】
mStatusBarWindowController.add(mStatusBarWindow, getStatusBarHeight());
}
// 获取状态栏高度, App就是借鉴这个方法
public int getStatusBarHeight() {
if (mNaturalBarHeight < 0) {
final Resources res = mContext.getResources();
mNaturalBarHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
}
return mNaturalBarHeight;
}
这里要提一下:
getStatusBarHeight这个方法, App开发中获取状态栏高度就是借鉴的这个方法, 只不过是反射获取该属性.
基本思路就是看源码中StatusBar对应的布局, 读取其高度属性.
protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
...
// 根据布局文件super_status_bar.xml创建StatusBarWindowView
inflateStatusBarWindow(context);
mStatusBarWindow.setService(this);
mStatusBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
...
// status_bar_container位置填充CollapsedStatusBarFragment
// CollapsedStatusBarFragment对应的布局文件为status_bar.xml
FragmentHostManager.get(mStatusBarWindow).addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
// Fragment创建完成时, 初始化
CollapsedStatusBarFragment statusBarFragment = (CollapsedStatusBarFragment) fragment;
statusBarFragment.initNotificationIconArea(mNotificationIconAreaController);
PhoneStatusBarView oldStatusBarView = mStatusBarView;
mStatusBarView = (PhoneStatusBarView) fragment.getView();
mStatusBarView.setBar(this);
mStatusBarView.setPanel(mNotificationPanel);
mStatusBarView.setScrimController(mScrimController);
mStatusBarView.setBouncerShowing(mBouncerShowing);
if (oldStatusBarView != null) {
float fraction = oldStatusBarView.getExpansionFraction();
boolean expanded = oldStatusBarView.isExpanded();
mStatusBarView.panelExpansionChanged(fraction, expanded);
}
...
mStatusBarWindow.setStatusBarView(mStatusBarView);
...
}).getFragmentManager()
.beginTransaction()
.replace(R.id.status_bar_container, new CollapsedStatusBarFragment(), CollapsedStatusBarFragment.TAG)
.commit();
...
// 创建导航栏(仅针对CarStatusBar)
createNavigationBar(result);
...
}
protected void inflateStatusBarWindow(Context context) {
// 从super_status_bar.xml布局文件创建StatusBarWindowView
mStatusBarWindow = (StatusBarWindowView) mInjectionInflater.injectable(
LayoutInflater.from(context)).inflate(R.layout.super_status_bar, null);
}
[ -> frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java ]
// Adds the status bar view to the window manager.
public void add(ViewGroup statusBarView, int barHeight) {
mLp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
barHeight,
WindowManager.LayoutParams.TYPE_STATUS_BAR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
PixelFormat.TRANSLUCENT);
mLp.token = new Binder();
mLp.gravity = Gravity.TOP;
mLp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
mLp.setTitle("StatusBar");
mLp.packageName = mContext.getPackageName();
mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
mStatusBarView = statusBarView;
mBarHeight = barHeight;
mWindowManager.addView(mStatusBarView, mLp);
mLpChanged.copyFrom(mLp);
onThemeChanged();
}
总结StatusBar#start做的事情:
一句话总结就是创建状态栏View并将其添加到WindowManager.
具体过程为:
1.根据布局文件super_status_bar.xml创建StatusBarWindowView
2.上述布局文件中id为status_bar_container的位置填充CollapsedStatusBarFragment
3.创建导航栏(仅针对CarStatusBar)
4.StatusBarWindowView添加到WindowManager.
(1) 状态栏相关的布局文件为:
[ -> frameworks/base/packages/SystemUI/res/layout/super_status_bar.xml ]
<com.android.systemui.statusbar.phone.StatusBarWindowView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:sysui="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.android.systemui.statusbar.BackDropView
android:id="@+id/backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
sysui:ignoreRightInset="true">
<ImageView android:id="@+id/backdrop_back"
android:layout_width="match_parent"
android:scaleType="centerCrop"
android:layout_height="match_parent" />
<ImageView android:id="@+id/backdrop_front"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:visibility="invisible" />
</com.android.systemui.statusbar.BackDropView>
<com.android.systemui.statusbar.ScrimView
android:id="@+id/scrim_behind"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAccessibility="no"
sysui:ignoreRightInset="true"/>
<FrameLayout
android:id="@+id/status_bar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<include layout="@layout/status_bar_expanded"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible" />
<include layout="@layout/brightness_mirror" />
<com.android.systemui.statusbar.ScrimView
android:id="@+id/scrim_in_front"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAccessibility="no"
sysui:ignoreRightInset="true"/>
<LinearLayout
android:id="@+id/lock_icon_container"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/status_bar_height"
android:layout_gravity="top|center_horizontal">
<com.android.systemui.statusbar.phone.LockIcon
android:id="@+id/lock_icon"
android:layout_width="@dimen/keyguard_lock_width"
android:layout_height="@dimen/keyguard_lock_height"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/keyguard_lock_padding"
android:contentDescription="@string/accessibility_unlock_button"
android:src="@*android:drawable/ic_lock"
android:scaleType="center" />
<com.android.keyguard.KeyguardMessageArea
android:id="@+id/keyguard_message_area"
style="@style/Keyguard.TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/keyguard_lock_padding"
android:gravity="center"
android:singleLine="true"
android:ellipsize="marquee"
android:focusable="true" />
</LinearLayout>
</com.android.systemui.statusbar.phone.StatusBarWindowView>
(2) CollapsedStatusBarFragment对应的布局文件为status_bar.xml
[ -> frameworks/base/packages/SystemUI/res/layout/status_bar.xml ]
<com.android.systemui.statusbar.phone.PhoneStatusBarView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
android:layout_width="match_parent"
android:layout_height="@dimen/status_bar_height"
android:id="@+id/status_bar"
android:background="@drawable/system_bar_background"
android:orientation="vertical"
android:focusable="false"
android:descendantFocusability="afterDescendants"
android:accessibilityPaneTitle="@string/status_bar">
<ImageView
android:id="@+id/notification_lights_out"
android:layout_width="@dimen/status_bar_icon_size"
android:layout_height="match_parent"
android:paddingStart="@dimen/status_bar_padding_start"
android:paddingBottom="2dip"
android:src="@drawable/ic_sysbar_lights_out_dot_small"
android:scaleType="center"
android:visibility="gone"/>
<LinearLayout android:id="@+id/status_bar_contents"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingStart="@dimen/status_bar_padding_start"
android:paddingEnd="@dimen/status_bar_padding_end"
android:paddingTop="@dimen/status_bar_padding_top"
android:orientation="horizontal">
<FrameLayout
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="1">
<include layout="@layout/heads_up_status_bar_layout" />
<LinearLayout
android:id="@+id/status_bar_left_side"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:clipChildren="false">
<ViewStub
android:id="@+id/operator_name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout="@layout/operator_name" />
<com.android.systemui.statusbar.policy.Clock
android:id="@+id/clock"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textAppearance="@style/TextAppearance.StatusBar.Clock"
android:singleLine="true"
android:paddingStart="@dimen/status_bar_left_clock_starting_padding"
android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
android:gravity="center_vertical|start"/>
<com.android.systemui.statusbar.AlphaOptimizedFrameLayout
android:id="@+id/notification_icon_area"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal"
android:clipChildren="false"/>
</LinearLayout>
</FrameLayout>
<android.widget.Space
android:id="@+id/cutout_space_view"
android:layout_width="0dp"
android:layout_height="match_parent"
android:gravity="center_horizontal|center_vertical"/>
<com.android.systemui.statusbar.AlphaOptimizedFrameLayout
android:id="@+id/centered_icon_area"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
android:clipChildren="false"
android:gravity="center_horizontal|center_vertical"/>
<com.android.keyguard.AlphaOptimizedLinearLayout android:id="@+id/system_icon_area"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal"
android:gravity="center_vertical|end">
<include layout="@layout/system_icons" />
</com.android.keyguard.AlphaOptimizedLinearLayout>
</LinearLayout>
<ViewStub
android:id="@+id/emergency_cryptkeeper_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout="@layout/emergency_cryptkeeper_text"/>
</com.android.systemui.statusbar.phone.PhoneStatusBarView>
[ -> frameworks/base/core/java/android/app/ActivityThread.java ]
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
...
final Activity a = performLaunchActivity(r, customIntent);
...
return a;
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity);
}
// 创建Activity实例
ContextImpl appContext = createBaseContextForActivity(r);
java.lang.ClassLoader cl = appContext.getClassLoader();
Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
try {
// 创建Application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
appContext.setOuterContext(activity);
// 将Activity attach到Application
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,
r.assistToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
// 调用Activity.onCreate方法. 参考【第3.2.2节】
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
r.activity = activity;
}
r.setState(ON_CREATE);
synchronized (mResourcesManager) {
mActivities.put(r.token, r);
}
return activity;
}
[ -> frameworks/base/core/java/android/app/Activity.java ]
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
attachBaseContext(context);
mFragments.attachHost(null /*parent*/);
// 创建PhoneWindow
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
if (info.uiOptions != 0) {
mWindow.setUiOptions(info.uiOptions);
}
mUiThread = Thread.currentThread();
mMainThread = aThread;
mInstrumentation = instr;
mToken = token;
mAssistToken = assistToken;
mIdent = ident;
mApplication = application;
mIntent = intent;
mReferrer = referrer;
mComponent = intent.getComponent();
mActivityInfo = info;
mTitle = title;
mParent = parent;
mEmbeddedID = id;
mLastNonConfigurationInstances = lastNonConfigurationInstances;
if (voiceInteractor != null) {
if (lastNonConfigurationInstances != null) {
mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
} else {
mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this, Looper.myLooper());
}
}
// 设置WindowManagerImpl
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
// 设置父Window
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
// 获取本地创建的WindowManagerImpl(这个和上面setWindowManager设置进来不是同一个实例)
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
mWindow.setColorMode(info.colorMode);
setAutofillOptions(application.getAutofillOptions());
setContentCaptureOptions(application.getContentCaptureOptions());
}
在App开发过程中, Activity#onCreate方法会调用setContentView(layoutResID).
那么我们来看下setContentView.
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
@Override
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID, getContext());
transitionTo(newScene);
} else {
// 将布局layoutResID添加到DecorView中id为R.id.content的位置
mLayoutInflater.inflate(layoutResID, mContentParent);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
mContentParentExplicitlySet = true;
}
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward, String reason) {
unscheduleGcIdler();
mSomeActivitiesChanged = true;
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
final Activity a = r.activity;
final int forwardBit = isForward ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
// 当Window还未添加到WindowManager, 且还未finish当前Activity或未启动新Activity时, 需要先添加到WindowManager
boolean willBeVisible = !a.mStartedActivity;
if (!willBeVisible) {
willBeVisible = ActivityTaskManager.getService().willActivityBeVisible(a.getActivityToken());
}
if (r.window == null && !a.mFinished && willBeVisible) {
// 拿到PhoneWindow
r.window = r.activity.getWindow();
// 拿到DecorView
View decor = r.window.getDecorView();
// 设置DecorView不可见
decor.setVisibility(View.INVISIBLE);
// 获取本地创建的WindowManagerImpl
ViewManager wm = a.getWindowManager();
// 设置Window各属性(如type为TYPE_BASE_APPLICATION)
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
// 获取DecorView的ViewPootImpl(每个View都有一个ViewRootImpl)
ViewRootImpl impl = decor.getViewRootImpl();
// 通知子View已经被重建(DecorView还是旧实例, Activity是新实例, 因此需要更新callbacks)
// 1.通常情况下, ViewRootImpl通过WindowManagerImpl#addView->ViewRootImpl#setView设置Activity的callbacks回调
// 2.但是如果DecorView复用时, 需要主动告诉ViewRootImpl callbacks可能发生变化
if (impl != null) {
impl.notifyChildRebuilt();
}
}
// 当Activity可见时, 添加DecorView到WindowManagerImpl或回调Window属性变化方法
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
} else {
a.onWindowAttributesChanged(l);
}
}
} else if (!willBeVisible) {
r.hideForNow = true;
}
// Get rid of anything left hanging around.
cleanUpPendingRemoveWindows(r, false /* force */);
if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
// 调用Activity.onConfigurationChanged方法
if (r.newConfig != null) {
performConfigurationChangedForActivity(r, r.newConfig);
r.newConfig = null;
}
// 更新DecorView的LayoutParams
WindowManager.LayoutParams l = r.window.getAttributes();
if ((l.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != forwardBit) {
l.softInputMode = (l.softInputMode & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) | forwardBit;
if (r.activity.mVisibleFromClient) {
ViewManager wm = a.getWindowManager();
View decor = r.window.getDecorView();
wm.updateViewLayout(decor, l);
}
}
r.activity.mVisibleFromServer = true;
mNumVisibleActivities++;
// 设置Activity可见
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();
}
}
r.nextIdle = mNewActivities;
mNewActivities = r;
Looper.myQueue().addIdleHandler(new Idler());
}
在Activity创建过程中, 会创建和添加PhoneWindow.
Activity中PhoneWindow的创建和添加过程:
1.handleLaunchActivity过程
(1) 创建Activity实例和Application实例, 调用Activity#attach将Activity attach到Application.
(2) 在Activity中创建PhoneWindow, PhoneWindow又创建DecorView. 设置WindowManagerImpl到PhoneWindow.
(3) 调用Activity#onCreate -> setContentView(layoutResID) 将layoutResId添加到DecorView中R.id.content位置.
2.handleResumeActivity过程
(1) PhoneWindow中的DecorView添加到WindowManager
(2) 设置DecorView可见
第3节已经分析了Activity中PhoneWindow的创建和添加过程.
在Activity#onCreate中会调用PhoneWindow#installDecor创建DecorView和子View.
这一节来具体分析下PhoneWindow和DecorView的组成.
[ -> frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java ]
// 创建DecorView及其子View
private void installDecor() {
mForceDecorInstall = false;
if (mDecor == null) {
// 创建DecorView
mDecor = generateDecor(-1);
mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mDecor.setIsRootNamespace(true);
if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
}
} else {
mDecor.setWindow(this);
}
if (mContentParent == null) {
// 根据设置的Window相关属性, 设置PhoneWindow特性. 给PhoneWindow的根DecorView添加子View, 并返回ContentView
mContentParent = generateLayout(mDecor);
// Set up decor part of UI to ignore fitsSystemWindows if appropriate.
mDecor.makeOptionalFitsSystemWindows();
// 对于R.layout.screen_simple没有该元素, 但对于R.layout.screen_action_bar包含该元素
final DecorContentParent decorContentParent = (DecorContentParent) mDecor.findViewById(R.id.decor_content_parent);
// 如果根View为ActionBarOverlayLayout, 则设置ActionBarOverlayLayout的title/icon/logo/menu等
if (decorContentParent != null) {
mDecorContentParent = decorContentParent;
mDecorContentParent.setWindowCallback(getCallback());
if (mDecorContentParent.getTitle() == null) {
mDecorContentParent.setWindowTitle(mTitle);
}
final int localFeatures = getLocalFeatures();
for (int i = 0; i < FEATURE_MAX; i++) {
if ((localFeatures & (1 << i)) != 0) {
mDecorContentParent.initFeature(i);
}
}
mDecorContentParent.setUiOptions(mUiOptions);
if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) != 0 ||
(mIconRes != 0 && !mDecorContentParent.hasIcon())) {
mDecorContentParent.setIcon(mIconRes);
} else if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) == 0 &&
mIconRes == 0 && !mDecorContentParent.hasIcon()) {
mDecorContentParent.setIcon(getContext().getPackageManager().getDefaultActivityIcon());
mResourcesSetFlags |= FLAG_RESOURCE_SET_ICON_FALLBACK;
}
if ((mResourcesSetFlags & FLAG_RESOURCE_SET_LOGO) != 0 ||
(mLogoRes != 0 && !mDecorContentParent.hasLogo())) {
mDecorContentParent.setLogo(mLogoRes);
}
PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
if (!isDestroyed() && (st == null || st.menu == null) && !mIsStartingWindow) {
invalidatePanelMenu(FEATURE_ACTION_BAR);
}
} else {
// 如果有title元素, 更新title
mTitleView = findViewById(R.id.title);
if (mTitleView != null) {
if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) {
final View titleContainer = findViewById(R.id.title_container);
if (titleContainer != null) {
titleContainer.setVisibility(View.GONE);
} else {
mTitleView.setVisibility(View.GONE);
}
mContentParent.setForeground(null);
} else {
mTitleView.setText(mTitle);
}
}
}
...
}
}
protected DecorView generateDecor(int featureId) {
Context context;
if (mUseDecorContext) {
Context applicationContext = getContext().getApplicationContext();
if (applicationContext == null) {
context = getContext();
} else {
context = new DecorContext(applicationContext, getContext());
if (mTheme != -1) {
context.setTheme(mTheme);
}
}
} else {
context = getContext();
}
return new DecorView(context, featureId, this, getAttributes());
}
protected ViewGroup generateLayout(DecorView decor) {
// Apply data from current theme.
TypedArray a = getWindowStyle();
mIsFloating = a.getBoolean(R.styleable.Window_windowIsFloating, false);
int flagsToUpdate = (FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR) & (~getForcedWindowFlags());
if (mIsFloating) {
setLayout(WRAP_CONTENT, WRAP_CONTENT);
setFlags(0, flagsToUpdate);
} else {
setFlags(FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR, flagsToUpdate);
}
if (a.getBoolean(R.styleable.Window_windowNoTitle, false)) {
requestFeature(FEATURE_NO_TITLE);
} else if (a.getBoolean(R.styleable.Window_windowActionBar, false)) {
// Don't allow an action bar if there is no title.
requestFeature(FEATURE_ACTION_BAR);
}
if (a.getBoolean(R.styleable.Window_windowActionBarOverlay, false)) {
requestFeature(FEATURE_ACTION_BAR_OVERLAY);
}
if (a.getBoolean(R.styleable.Window_windowActionModeOverlay, false)) {
requestFeature(FEATURE_ACTION_MODE_OVERLAY);
}
if (a.getBoolean(R.styleable.Window_windowSwipeToDismiss, false)) {
requestFeature(FEATURE_SWIPE_TO_DISMISS);
}
if (a.getBoolean(R.styleable.Window_windowFullscreen, false)) {
setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN & (~getForcedWindowFlags()));
}
if (a.getBoolean(R.styleable.Window_windowTranslucentStatus, false)) {
setFlags(FLAG_TRANSLUCENT_STATUS, FLAG_TRANSLUCENT_STATUS & (~getForcedWindowFlags()));
}
if (a.getBoolean(R.styleable.Window_windowTranslucentNavigation, false)) {
setFlags(FLAG_TRANSLUCENT_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION & (~getForcedWindowFlags()));
}
if (a.getBoolean(R.styleable.Window_windowOverscan, false)) {
setFlags(FLAG_LAYOUT_IN_OVERSCAN, FLAG_LAYOUT_IN_OVERSCAN&(~getForcedWindowFlags()));
}
if (a.getBoolean(R.styleable.Window_windowShowWallpaper, false)) {
setFlags(FLAG_SHOW_WALLPAPER, FLAG_SHOW_WALLPAPER&(~getForcedWindowFlags()));
}
if (a.getBoolean(R.styleable.Window_windowEnableSplitTouch,
getContext().getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.HONEYCOMB)) {
setFlags(FLAG_SPLIT_TOUCH, FLAG_SPLIT_TOUCH&(~getForcedWindowFlags()));
}
a.getValue(R.styleable.Window_windowMinWidthMajor, mMinWidthMajor);
a.getValue(R.styleable.Window_windowMinWidthMinor, mMinWidthMinor);
if (a.hasValue(R.styleable.Window_windowFixedWidthMajor)) {
if (mFixedWidthMajor == null) mFixedWidthMajor = new TypedValue();
a.getValue(R.styleable.Window_windowFixedWidthMajor, mFixedWidthMajor);
}
if (a.hasValue(R.styleable.Window_windowFixedWidthMinor)) {
if (mFixedWidthMinor == null) mFixedWidthMinor = new TypedValue();
a.getValue(R.styleable.Window_windowFixedWidthMinor, mFixedWidthMinor);
}
if (a.hasValue(R.styleable.Window_windowFixedHeightMajor)) {
if (mFixedHeightMajor == null) mFixedHeightMajor = new TypedValue();
a.getValue(R.styleable.Window_windowFixedHeightMajor, mFixedHeightMajor);
}
if (a.hasValue(R.styleable.Window_windowFixedHeightMinor)) {
if (mFixedHeightMinor == null) mFixedHeightMinor = new TypedValue();
a.getValue(R.styleable.Window_windowFixedHeightMinor, mFixedHeightMinor);
}
if (a.getBoolean(R.styleable.Window_windowContentTransitions, false)) {
requestFeature(FEATURE_CONTENT_TRANSITIONS);
}
if (a.getBoolean(R.styleable.Window_windowActivityTransitions, false)) {
requestFeature(FEATURE_ACTIVITY_TRANSITIONS);
}
mIsTranslucent = a.getBoolean(R.styleable.Window_windowIsTranslucent, false);
final Context context = getContext();
final int targetSdk = context.getApplicationInfo().targetSdkVersion;
final boolean targetPreHoneycomb = targetSdk < android.os.Build.VERSION_CODES.HONEYCOMB;
final boolean targetPreIcs = targetSdk < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH;
final boolean targetPreL = targetSdk < android.os.Build.VERSION_CODES.LOLLIPOP;
final boolean targetPreQ = targetSdk < Build.VERSION_CODES.Q;
final boolean targetHcNeedsOptions = context.getResources().getBoolean(R.bool.target_honeycomb_needs_options_menu);
final boolean noActionBar = !hasFeature(FEATURE_ACTION_BAR) || hasFeature(FEATURE_NO_TITLE);
if (targetPreHoneycomb || (targetPreIcs && targetHcNeedsOptions && noActionBar)) {
setNeedsMenuKey(WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE);
} else {
setNeedsMenuKey(WindowManager.LayoutParams.NEEDS_MENU_SET_FALSE);
}
if (!mForcedStatusBarColor) {
mStatusBarColor = a.getColor(R.styleable.Window_statusBarColor, 0xFF000000);
}
if (!mForcedNavigationBarColor) {
mNavigationBarColor = a.getColor(R.styleable.Window_navigationBarColor, 0xFF000000);
mNavigationBarDividerColor = a.getColor(R.styleable.Window_navigationBarDividerColor, 0x00000000);
}
if (!targetPreQ) {
mEnsureStatusBarContrastWhenTransparent = a.getBoolean(R.styleable.Window_enforceStatusBarContrast, false);
mEnsureNavigationBarContrastWhenTransparent = a.getBoolean(R.styleable.Window_enforceNavigationBarContrast, true);
}
WindowManager.LayoutParams params = getAttributes();
// Non-floating windows on high end devices must put up decor beneath the system bars and
// therefore must know about visibility changes of those.
if (!mIsFloating) {
if (!targetPreL && a.getBoolean(R.styleable.Window_windowDrawsSystemBarBackgrounds, false)) {
setFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS & ~getForcedWindowFlags());
}
if (mDecor.mForceWindowDrawsBarBackgrounds) {
params.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
}
}
if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
decor.setSystemUiVisibility(decor.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
if (a.getBoolean(R.styleable.Window_windowLightNavigationBar, false)) {
decor.setSystemUiVisibility(decor.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
}
if (a.hasValue(R.styleable.Window_windowLayoutInDisplayCutoutMode)) {
int mode = a.getInt(R.styleable.Window_windowLayoutInDisplayCutoutMode, -1);
params.layoutInDisplayCutoutMode = mode;
}
if (mAlwaysReadCloseOnTouchAttr || getContext().getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.HONEYCOMB) {
if (a.getBoolean(R.styleable.Window_windowCloseOnTouchOutside, false)) {
setCloseOnTouchOutsideIfNotSet(true);
}
}
if (!hasSoftInputMode()) {
params.softInputMode = a.getInt(R.styleable.Window_windowSoftInputMode, params.softInputMode);
}
if (a.getBoolean(R.styleable.Window_backgroundDimEnabled, mIsFloating)) {
/* All dialogs should have the window dimmed */
if ((getForcedWindowFlags()&WindowManager.LayoutParams.FLAG_DIM_BEHIND) == 0) {
params.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
}
if (!haveDimAmount()) {
params.dimAmount = a.getFloat(android.R.styleable.Window_backgroundDimAmount, 0.5f);
}
}
if (params.windowAnimations == 0) {
params.windowAnimations = a.getResourceId(R.styleable.Window_windowAnimationStyle, 0);
}
// The rest are only done if this window is not embedded; otherwise,
// the values are inherited from our container.
if (getContainer() == null) {
if (mBackgroundDrawable == null) {
if (mFrameResource == 0) {
mFrameResource = a.getResourceId(R.styleable.Window_windowFrame, 0);
}
if (a.hasValue(R.styleable.Window_windowBackground)) {
mBackgroundDrawable = a.getDrawable(R.styleable.Window_windowBackground);
}
}
if (a.hasValue(R.styleable.Window_windowBackgroundFallback)) {
mBackgroundFallbackDrawable = a.getDrawable(R.styleable.Window_windowBackgroundFallback);
}
if (mLoadElevation) {
mElevation = a.getDimension(R.styleable.Window_windowElevation, 0);
}
mClipToOutline = a.getBoolean(R.styleable.Window_windowClipToOutline, false);
mTextColor = a.getColor(R.styleable.Window_textColor, Color.TRANSPARENT);
}
// Inflate the window decor.
int layoutResource;
int features = getLocalFeatures();
// System.out.println("Features: 0x" + Integer.toHexString(features));
if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {
layoutResource = R.layout.screen_swipe_dismiss;
setCloseOnSwipeEnabled(true);
} else if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
if (mIsFloating) {
TypedValue res = new TypedValue();
getContext().getTheme().resolveAttribute(
R.attr.dialogTitleIconsDecorLayout, res, true);
layoutResource = res.resourceId;
} else {
layoutResource = R.layout.screen_title_icons;
}
// XXX Remove this once action bar supports these features.
removeFeature(FEATURE_ACTION_BAR);
// System.out.println("Title Icons!");
} else if ((features & ((1 << FEATURE_PROGRESS) | (1 << FEATURE_INDETERMINATE_PROGRESS))) != 0
&& (features & (1 << FEATURE_ACTION_BAR)) == 0) {
// Special case for a window with only a progress bar (and title).
// XXX Need to have a no-title version of embedded windows.
layoutResource = R.layout.screen_progress;
// System.out.println("Progress!");
} else if ((features & (1 << FEATURE_CUSTOM_TITLE)) != 0) {
// Special case for a window with a custom title.
// If the window is floating, we need a dialog layout
if (mIsFloating) {
TypedValue res = new TypedValue();
getContext().getTheme().resolveAttribute(
R.attr.dialogCustomTitleDecorLayout, res, true);
layoutResource = res.resourceId;
} else {
layoutResource = R.layout.screen_custom_title;
}
// XXX Remove this once action bar supports these features.
removeFeature(FEATURE_ACTION_BAR);
} else if ((features & (1 << FEATURE_NO_TITLE)) == 0) {
// If no other features and not embedded, only need a title.
// If the window is floating, we need a dialog layout
if (mIsFloating) {
TypedValue res = new TypedValue();
getContext().getTheme().resolveAttribute(R.attr.dialogTitleDecorLayout, res, true);
layoutResource = res.resourceId;
} else if ((features & (1 << FEATURE_ACTION_BAR)) != 0) {
layoutResource = a.getResourceId(
R.styleable.Window_windowActionBarFullscreenDecorLayout,
R.layout.screen_action_bar);
} else {
layoutResource = R.layout.screen_title;
}
// System.out.println("Title!");
} else if ((features & (1 << FEATURE_ACTION_MODE_OVERLAY)) != 0) {
layoutResource = R.layout.screen_simple_overlay_action_mode;
} else {
// Embedded, so no decoration is needed.
layoutResource = R.layout.screen_simple;
// System.out.println("Simple!");
}
mDecor.startChanging();
// DecorView添加子View. 从父到子依次是:DecorView -> DecorCaptionView(不一定包含) -> root(即layoutResource对应的View)
mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
// 获取R.id.content对应的ContentView
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
if ((features & (1 << FEATURE_INDETERMINATE_PROGRESS)) != 0) {
ProgressBar progress = getCircularProgressBar(false);
if (progress != null) {
progress.setIndeterminate(true);
}
}
if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {
registerSwipeCallbacks(contentParent);
}
// 仅最顶层Window执行
if (getContainer() == null) {
mDecor.setWindowBackground(mBackgroundDrawable);
final Drawable frame;
if (mFrameResource != 0) {
frame = getContext().getDrawable(mFrameResource);
} else {
frame = null;
}
mDecor.setWindowFrame(frame);
mDecor.setElevation(mElevation);
mDecor.setClipToOutline(mClipToOutline);
if (mTitle != null) {
setTitle(mTitle);
}
if (mTitleColor == 0) {
mTitleColor = mTextColor;
}
setTitleColor(mTitleColor);
}
mDecor.finishChanging();
return contentParent;
}
[ -> frameworks/base/core/java/com/android/internal/policy/DecorView.java ]
void onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
if (mBackdropFrameRenderer != null) {
loadBackgroundDrawablesIfNeeded();
mBackdropFrameRenderer.onResourcesLoaded(
this, mResizingBackgroundDrawable, mCaptionBackgroundDrawable,
mUserCaptionBackgroundDrawable, getCurrentColor(mStatusColorViewState),
getCurrentColor(mNavigationColorViewState));
}
// 创建DecorCaptionView(即包含系统按钮如最大化,关闭等的标题)
mDecorCaptionView = createDecorCaptionView(inflater);
final View root = inflater.inflate(layoutResource, null);
if (mDecorCaptionView != null) {
// 从父到子依次是:DecorView -> DecorCaptionView -> root
if (mDecorCaptionView.getParent() == null) {
addView(mDecorCaptionView, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
mDecorCaptionView.addView(root, new ViewGroup.MarginLayoutParams(MATCH_PARENT, MATCH_PARENT));
} else {
// 从父到子依次是:DecorView -> root
addView(root, 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
mContentRoot = (ViewGroup) root;
initializeElevation();
}
private DecorCaptionView createDecorCaptionView(LayoutInflater inflater) {
DecorCaptionView decorCaptionView = null;
for (int i = getChildCount() - 1; i >= 0 && decorCaptionView == null; i--) {
View view = getChildAt(i);
if (view instanceof DecorCaptionView) {
// The decor was most likely saved from a relaunch - so reuse it.
decorCaptionView = (DecorCaptionView) view;
removeViewAt(i);
}
}
final WindowManager.LayoutParams attrs = mWindow.getAttributes();
final boolean isApplication = attrs.type == TYPE_BASE_APPLICATION ||
attrs.type == TYPE_APPLICATION || attrs.type == TYPE_DRAWN_APPLICATION;
final WindowConfiguration winConfig = getResources().getConfiguration().windowConfiguration;
if (!mWindow.isFloating() && isApplication && winConfig.hasWindowDecorCaption()) {
if (decorCaptionView == null) {
decorCaptionView = inflateDecorCaptionView(inflater);
}
decorCaptionView.setPhoneWindow(mWindow, true /*showDecor*/);
} else {
decorCaptionView = null;
}
// Tell the decor if it has a visible caption.
enableCaption(decorCaptionView != null);
return decorCaptionView;
}
一句话总结PhoneWindow#installDecor:
该方法在Activity#setContentView(layoutResID)里调用. 用来在PhoneWindow创建DecorView及其子View.
PhoneWindow#installDecor具体步骤:
1.generateDecor
: 创建DecorView(即一个FrameLayout)
2.generateLayout
: 根据设置的Window相关属性, 设置PhoneWindow特性. 给PhoneWindow的根DecorView添加子View, 并返回ContentView
(1) 读取frameworks/base/core/res/res/values/attrs.xml
中Window相关的属性< declare-styleable name="Window">
(2) 根据设置的Window各属性值, 设置PhoneWindow的特性(例如requestFeature/setFlags/WindowManager.LayoutParams), 以及选择对应的layout(默认为screen_simple)
(3) DecorView添加子View. 从父到子依次是:DecorView -> DecorCaptionView(不一定包含) -> root(即上述layout对应的View)
(4) 返回root(即R.layout.screen_simple
)中R.id.content对应的ContentView(即一个FrameLayout)
DecorCaptionView即包含系统按钮如最大化,关闭等的标题, 此处不细纠.
[ -> frameworks/base/core/res/res/layout/screen_simple.xml ]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<ViewStub
android:id="@+id/action_mode_bar_stub"
android:inflatedId="@+id/action_mode_bar"
android:layout="@layout/action_mode_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="?attr/actionBarTheme" />
<FrameLayout
android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foregroundInsidePadding="false"
android:foregroundGravity="fill_horizontal|top"
android:foreground="?android:attr/windowContentOverlay" />
</LinearLayout>
上图是根据源码总结出来的各个类的关系图. 主要包含3部分:
1.StatusBar
状态栏(系统UI), 其根View为StatusBarWindowView, 通过WindowManagerImpl.addView添加到窗口管理器.
2.DecorView
(1) 应用程序View. 通过WindowManagerImpl.addView添加到窗口管理器. 一个页面对应一个Activity, 一个Activity包含一个PhoneWindow, PhoneWindow的根View即为DecorView, DecorView为FrameLayout.
(2) 根据创建Activity时设置的Window属性的不同, 选择不同的layout布局, 并将该layout布局添加到DecorView中. 最简单的为R.layout.screen_simple.
(3) 上述layout布局R.layout.screen_simple为LinearLayout, 包含2个元素: @id/action_mode_bar_stub和@android:id/content. 即标题栏和内容体. 在Activity#onCreate -> setContentView(layoutResID)调用时, 会将layoutResID填充到@android:id/content
3.NavigationBar
通常指的手机底部的虚拟按键.
上面我们已经知道StatusBar和DecorView都会添加到WindowManagerImpl, 通过窗口管理器进行管理. 因此开发者可以定制状态栏和应用程序的UI样式及他们之间的显示关系.
下面以沉浸式状态栏实现为例:
我们实现这样的效果需要遵循几个步骤:
(1) 状态栏透明
(2) DecorView占满整个屏幕
(3) NavigationBar的控制
实现代码如下:
private static void transparentStatusBar(final Activity activity) {
// Android Android 4.4以下, 跳过
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
return;
}
Window window = activity.getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// Android 5.0及以上, 设置DecorView全屏和系统状态栏透明
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
int option = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
window.getDecorView().setSystemUiVisibility(option);
window.setStatusBarColor(Color.TRANSPARENT);
} else {
// Android 4.4 设置系统状态栏透明(不能实现DecorView全屏)
// 由于Android 4.4不存在PhoneWindow#setStatusBarColor这个方法.
// 因此设置透明状态栏需要在DecorView添加一个AlphaStatusBarView
addStatusBarAlpha(activity, 0)
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
// 仅仅用于Android 4.4
private static void addStatusBarAlpha(final Activity activity, final int alpha) {
ViewGroup parent = (ViewGroup) activity.getWindow().getDecorView()
View fakeStatusBarView = parent.findViewWithTag(TAG_ALPHA);
if (fakeStatusBarView != null) {
if (fakeStatusBarView.getVisibility() == View.GONE) {
fakeStatusBarView.setVisibility(View.VISIBLE);
}
fakeStatusBarView.setBackgroundColor(Color.argb(alpha, 0, 0, 0));
} else {
parent.addView(createAlphaStatusBarView(parent.getContext(), alpha));
}
}
// 仅仅用于Android 4.4
private static View createAlphaStatusBarView(final Context context, final int alpha) {
View statusBarView = new View(context);
statusBarView.setLayoutParams(new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight()));
statusBarView.setBackgroundColor(Color.argb(alpha, 0, 0, 0));
statusBarView.setTag(TAG_ALPHA);
return statusBarView;
}
系统UI的可见性 :
系统UI(如StatusBar和NavigationBar), 可以在Activity中通过DecorView#setSystemUiVisibility控制.
(1) 设置DecorView全屏
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
(2) 隐藏NavigationBar
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
(3) 其他参考View.SYSTEM_UI_FLAG_XXX
基于Android 10.0的源码剖析, 站在Luoshengyang/Innost/Gityuan肩膀上.
本文主要介绍WMS服务的启动过程, 以及WMS的重要组成元素.
frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
frameworks/base/services/core/java/com/android/server/DisplayThread.java
frameworks/base/services/core/java/com/android/server/wm/WindowState.java
frameworks/base/services/core/java/com/android/server/wm/AppWindowToken.java
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
frameworks/base/services/core/java/com/android/server/policy/WindowManagerPolicy.java
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
frameworks/base/services/core/java/com/android/server/wm/WindowAnimator.java
frameworks/base/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java
frameworks/base/services/core/java/com/android/server/wm/TaskPositioningController.java
frameworks/base/services/core/java/com/android/server/wm/DragDropController.java
[ -> frameworks/base/services/java/com/android/server/SystemServer.java ]
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
...
// 初始化系统上下文
createSystemContext();
// 初始化SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
...
// 启动相互依赖关系复杂的服务
startBootstrapServices();
// 启动相互独立的基本服务
startCoreServices();
// 启动其他服务
startOtherServices();
...
}
private void startOtherServices() {
// 启动WMS前, 需要先启动SensorService
ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
mSensorServiceStart = null;
// 见【第2.2节】
WindowManagerService wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore, new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
...
// 所有WMS相关的实体对象初始化完成
wm.onInitReady();
...
// Display ready
wm.displayReady();
...
// WMS ready
wm.systemReady();
...
final WindowManagerService windowManagerF = wm;
// 启动SystemUIService服务
startSystemUi(context, windowManagerF);
...
}
private static void startSystemUi(Context context, WindowManagerService windowManager) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService"));
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
// System UI已启动
windowManager.onSystemUiStarted();
}
[ -> frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java ]
// ActivityTaskManager服务相关, 管理Activity和其容器(如task/stacks/displays)的系统服务
final IActivityTaskManager mActivityTaskManager;
final ActivityTaskManagerService mAtmService;
// DisplayManager服务相关, 管理Display属性
final DisplayManagerInternal mDisplayManagerInternal;
final DisplayManager mDisplayManager;
final DisplayWindowSettings mDisplayWindowSettings;
// ActivityManager服务相关, 用于和四大组件交互
final IActivityManager mActivityManager;
final ActivityManagerInternal mAmInternal;
// PowerManager服务相关, 管理电源状态
PowerManager mPowerManager;
PowerManagerInternal mPowerManagerInternal;
// 输入管理服务
final InputManagerService mInputManager;
// 包管理本地系统服务
final PackageManagerInternal mPmInternal;
// 根窗口容器
RootWindowContainer mRoot;
// 提供UI相关行为的策略类, 其实现类为PhoneWindowManager
WindowManagerPolicy mPolicy;
// 在一个单独的task中执行动画和Surface操作的类
final WindowAnimator mAnimator;
// 用来确定Window和Surface位置的类
final WindowSurfacePlacer mWindowPlacerLocked;
// 任务快照管理器(当App不可见时, 会将Task的快照以Bitmap形式存在缓存中)
final TaskSnapshotController mTaskSnapshotController;
// Task定位控制器
final TaskPositioningController mTaskPositioningController;
// View的拖/拉操作控制器
final DragDropController mDragDropController;
// 当前活跃状态的Session连接队列(通常一个进程中包含一个Session, 用于和WindowManager交互)
final ArraySet<Session> mSessions = new ArraySet<>();
// <IBinder, WindowState>客户端Window token和服务端WindowState的映射
final WindowHashMap mWindowMap = new WindowHashMap();
// AppWindowToken是一个窗口容器类, 可以理解为正在显示Window的App或Activity的窗口令牌(继承于WindowToken)
// replace超时的AppWindowToken令牌列表
final ArrayList<AppWindowToken> mWindowReplacementTimeouts = new ArrayList<>();
// WindowState表示服务端描述的Window
final ArrayList<WindowState> mResizingWindows = new ArrayList<>();
final ArrayList<WindowState> mPendingRemove = new ArrayList<>();
final ArrayList<WindowState> mDestroySurface = new ArrayList<>();
final ArrayList<WindowState> mDestroyPreservedSurface = new ArrayList<>();
final ArrayList<WindowState> mForceRemoves = new ArrayList<>();
ArrayList<WindowState> mWaitingForDrawn = new ArrayList<>();
private ArrayList<WindowState> mHidingNonSystemOverlayWindows = new ArrayList<>();
WindowState[] mPendingRemoveTmp = new WindowState[20];
// 主线程Handler
final H mH = new H();
public static WindowManagerService main(final Context context, final InputManagerService im,
final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm) {
return main(context, im, showBootMsgs, onlyCore, policy, atm, SurfaceControl.Transaction::new);
}
public static WindowManagerService main(final Context context, final InputManagerService im,
final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm, TransactionFactory transactionFactory) {
DisplayThread.getHandler().runWithScissors(() ->
sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy, atm, transactionFactory), 0);
return sInstance;
}
private WindowManagerService(Context context, InputManagerService inputManager,
boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm, TransactionFactory transactionFactory) {
installLock(this, INDEX_WINDOW);
mGlobalLock = atm.getGlobalLock();
mAtmService = atm;
mContext = context;
mAllowBootMessages = showBootMsgs;
mOnlyCore = onlyCore;
// 各种变量读取
mLimitedAlphaCompositing = context.getResources().getBoolean(
com.android.internal.R.bool.config_sf_limitedAlpha);
mHasPermanentDpad = context.getResources().getBoolean(
com.android.internal.R.bool.config_hasPermanentDpad);
mInTouchMode = context.getResources().getBoolean(
com.android.internal.R.bool.config_defaultInTouchMode);
mDrawLockTimeoutMillis = context.getResources().getInteger(
com.android.internal.R.integer.config_drawLockTimeoutMillis);
mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
com.android.internal.R.bool.config_allowAnimationsInLowPowerMode);
mMaxUiWidth = context.getResources().getInteger(
com.android.internal.R.integer.config_maxUiWidth);
mDisableTransitionAnimation = context.getResources().getBoolean(
com.android.internal.R.bool.config_disableTransitionAnimation);
mPerDisplayFocusEnabled = context.getResources().getBoolean(
com.android.internal.R.bool.config_perDisplayFocusEnabled);
mLowRamTaskSnapshotsAndRecents = context.getResources().getBoolean(
com.android.internal.R.bool.config_lowRamTaskSnapshotsAndRecents);
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
// Display设置
mDisplayWindowSettings = new DisplayWindowSettings(this);
mTransactionFactory = transactionFactory;
mTransaction = mTransactionFactory.make();
// PhoneWindowManager(继承于WindowManagerPolicy, 用来提供UI相关的一些行为)
mPolicy = policy;
// 在一个单独的task中执行动画和Surface操作的类
mAnimator = new WindowAnimator(this);
// 根Window容器
mRoot = new RootWindowContainer(this);
// 用来确定Window和Surface的位置
mWindowPlacerLocked = new WindowSurfacePlacer(this);
// 任务快照管理器(当App不可见时, 会将Task的快照以Bitmap形式存在缓存中)
mTaskSnapshotController = new TaskSnapshotController(this);
LocalServices.addService(WindowManagerPolicy.class, mPolicy);
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
// Keyguard处理器
mKeyguardDisableHandler = KeyguardDisableHandler.create(mContext, mPolicy, mH);
// PowerManager是控制设备电池状态的管理器
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
// PowerManagerInternal是PowerMananger的本地服务
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
if (mPowerManagerInternal != null) {
mPowerManagerInternal.registerLowPowerModeObserver(
new PowerManagerInternal.LowPowerModeListener() {
@Override
public int getServiceType() {
return ServiceType.ANIMATION;
}
@Override
public void onLowPowerModeChanged(PowerSaveState result) {
synchronized (mGlobalLock) {
// 低电量模式发生变化时, 需要调整对应的动画
final boolean enabled = result.batterySaverEnabled;
if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) {
mAnimationsDisabled = enabled;
dispatchNewAnimatorScaleLocked(null);
}
}
}
});
// 获取是否允许动画
mAnimationsDisabled = mPowerManagerInternal.getLowPowerState(ServiceType.ANIMATION).batterySaverEnabled;
}
mScreenFrozenLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
mScreenFrozenLock.setReferenceCounted(false);
// 获取IActivity.Stub.Proxy(new BinderProxy())
mActivityManager = ActivityManager.getService();
// 获取IActivityTaskManager.Stub.Proxy
mActivityTaskManager = ActivityTaskManager.getService();
// ActivityManagerInternal是ActivityManager的本地服务
mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
// ActivityTaskManagerInternal是ActivityTaskManager的本地服务
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
AppOpsManager.OnOpChangedInternalListener opListener =
new AppOpsManager.OnOpChangedInternalListener() {
@Override
public void onOpChanged(int op, String packageName) {
updateAppOpsState();
}
};
mAppOps.startWatchingMode(OP_SYSTEM_ALERT_WINDOW, null, opListener);
mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW, null, opListener);
// PackageManagerInternal是PackageManager的本地服务
mPmInternal = LocalServices.getService(PackageManagerInternal.class);
// 注册Package suspend/unsuspend广播
final IntentFilter suspendPackagesFilter = new IntentFilter();
suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);
context.registerReceiverAsUser(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String[] affectedPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(intent.getAction());
updateHiddenWhileSuspendedState(new ArraySet<>(Arrays.asList(affectedPackages)), suspended);
}
}, UserHandle.ALL, suspendPackagesFilter, null, null);
// 获取并设置window scale设置
final ContentResolver resolver = context.getContentResolver();
mWindowAnimationScaleSetting = Settings.Global.getFloat(resolver,
Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
mTransitionAnimationScaleSetting = Settings.Global.getFloat(resolver,
Settings.Global.TRANSITION_ANIMATION_SCALE,
context.getResources().getFloat(
R.dimen.config_appTransitionAnimationDurationScaleDefault));
setAnimatorDurationScale(Settings.Global.getFloat(resolver,
Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting));
mForceDesktopModeOnExternalDisplays = Settings.Global.getInt(resolver,
DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0;
// 注册广播, 当DevicePolicyManager状态发生变化时设置keyguard属性是否可用
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
mLatencyTracker = LatencyTracker.getInstance(context);
mSettingsObserver = new SettingsObserver();
mHoldingScreenWakeLock = mPowerManager.newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM);
mHoldingScreenWakeLock.setReferenceCounted(false);
mSurfaceAnimationRunner = new SurfaceAnimationRunner(mPowerManagerInternal);
mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);
// Task定位控制器
mTaskPositioningController = new TaskPositioningController(this, mInputManager,
mActivityTaskManager, mH.getLooper());
// View的拖/拉操作控制器
mDragDropController = new DragDropController(this, mH.getLooper());
mSystemGestureExclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
DeviceConfig.getInt(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
mSystemGestureExcludedByPreQStickyImmersive =
DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
new HandlerExecutor(mH), properties -> {
synchronized (mGlobalLock) {
final int exclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
properties.getInt(KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
final boolean excludedByPreQSticky = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_WINDOW_MANAGER,
KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
if (mSystemGestureExcludedByPreQStickyImmersive != excludedByPreQSticky
|| mSystemGestureExclusionLimitDp != exclusionLimitDp) {
mSystemGestureExclusionLimitDp = exclusionLimitDp;
mSystemGestureExcludedByPreQStickyImmersive = excludedByPreQSticky;
mRoot.forAllDisplays(DisplayContent::updateSystemGestureExclusionLimit);
}
}
});
// 注册WindowManager的本地服务WindowManagerInternal
LocalServices.addService(WindowManagerInternal.class, new LocalService());
}
public void onInitReady() {
// 初始化PhoneWindowManager(继承于WindowManagerPolicy, 用来提供UI相关的一些行为)
initPolicy();
// 添加Watchdog monitor
Watchdog.getInstance().addMonitor(this);
// 调用SurfaceControl.openTransaction(), 启动一个事务
openSurfaceTransaction();
// 创建水印
createWatermarkInTransaction();
// 结束事务
closeSurfaceTransaction("createWatermarkInTransaction");
// 显示模拟器显示层
showEmulatorDisplayOverlayIfNeeded();
}
public void displayReady() {
synchronized (mGlobalLock) {
// 设置RootWindowContainer的Window列表的最大宽度
if (mMaxUiWidth > 0) {
mRoot.forAllDisplays(displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth));
}
final boolean changed = applyForcedPropertiesForDefaultDisplay();
mAnimator.ready();
mDisplayReady = true;
if (changed) {
// 重新配置DiaplayContent属性
reconfigureDisplayLocked(getDefaultDisplayContentLocked());
}
mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN);
}
// 1.修改当前configuration 2.确保当前Activity正在运行当前configuration
mActivityTaskManager.updateConfiguration(null);
// 更新CircularDisplayMask
updateCircularDisplayMaskIfNeeded();
}
public void systemReady() {
mSystemReady = true;
mPolicy.systemReady();
mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady);
mTaskSnapshotController.systemReady();
// 是否支持色域
mHasWideColorGamutSupport = queryWideColorGamutSupport();
// 是否支持HDR渲染
mHasHdrSupport = queryHdrSupport();
UiThread.getHandler().post(mSettingsObserver::updateSystemUiSettings);
UiThread.getHandler().post(mSettingsObserver::updatePointerLocation);
// 获取IVrManager.Stub.Proxy, 并注册状态变化listener
IVrManager vrManager = IVrManager.Stub.asInterface(ServiceManager.getService(Context.VR_SERVICE));
if (vrManager != null) {
final boolean vrModeEnabled = vrManager.getVrModeState();
synchronized (mGlobalLock) {
vrManager.registerListener(mVrStateCallbacks);
if (vrModeEnabled) {
mVrModeEnabled = vrModeEnabled;
mVrStateCallbacks.onVrStateChanged(vrModeEnabled);
}
}
}
}
WMS主要用于窗口的添加和移除操作, 其对应的方法是addWindow和removeWindow.
关于窗口的添加和删除过程, 放到后面文章去分析.
public int addWindow(Session session, IWindow client, int seq,
LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame,
Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel,
InsetsState outInsetsState)
void removeWindow(Session session, IWindow client)
基于Android 10.0的源码剖析, 站在Luoshengyang/Innost/Gityuan肩膀上.
本文以查询联系人demo为切入点, 分析ContentProvider原理.
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/core/java/android/content/ContentProvider.java
frameworks/base/core/java/android/content/ContentProviderNative.java
frameworks/base/core/java/android/app/ContentProviderHolder.java
frameworks/base/core/java/android/content/ContentResolver.java
frameworks/base/core/java/android/app/IActivityManager.aidl
frameworks/base/core/java/android/os/ICancellationSignal.aidl
frameworks/base/core/java/android/database/BulkCursorToCursorAdaptor.java
frameworks/base/core/java/android/database/AbstractWindowedCursor.java
frameworks/base/core/java/android/database/AbstractCursor.java
frameworks/base/core/java/android/database/CursorWindow.java
frameworks/base/core/jni/android_database_CursorWindow.cpp
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
frameworks/base/services/core/java/com/android/server/pm/ComponentResolver.java
packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsProvider2.java
TODO
通过ContentProvider操作手机通信录的demo示例:
// 查询联系人信息
public void getContactInfo() {
ContentResolver contentResolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://com.android.contacts/contacts");
Cursor cursor = contentResolver.query(uri, null, null, null, null);
while(cursor.moveToNext()){
// 获取联系人姓名
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
// 获取联系人手机号码
Cursor phones = contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId,
null, null);
while (phones.moveToNext()) {
String phone = phones.getString(phones.getColumnIndex("data1"));
}
// 获取联系人Email
Cursor emails = contentResolver.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + contactId,
null, null);
while (emails.moveToNext()) {
String email = emails.getString(emails.getColumnIndex("data1"));
}
}
}
// 添加联系人信息
public void addContactInfo() {
ContentValues values = new ContentValues();
// 首先向RawContacts.CONTENT_URI执行一个空值插入,目的是获取系统返回的rawContactId
Uri rawContactUri = getContext().getContentResolver().insert(RawContacts.CONTENT_URI, values);
long rawContactId = ContentUris.parseId(rawContactUri);
// 往data表中插入联系人信息
values.clear();
values.put(Data.RAW_CONTACT_ID, rawContactId);
values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
// 名字
values.put(StructuredName.GIVEN_NAME, "zhangsan");
// 手机号码
values.put(Phone.NUMBER, "5554");
values.put(Phone.TYPE, Phone.TYPE_MOBILE);
// Email
values.put(Email.DATA, "ljq218@126.com");
values.put(Email.TYPE, Email.TYPE_WORK);
getContext().getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
}
本文以获取联系人姓名(即query操作) 为例.
[ -> frameworks/base/core/java/android/app/ContextImpl.java ]
private final ApplicationContentResolver mContentResolver;
private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,
@NonNull LoadedApk packageInfo, @Nullable String splitName,
@Nullable IBinder activityToken, @Nullable UserHandle user, int flags,
@Nullable ClassLoader classLoader, @Nullable String overrideOpPackageName) {
...
mContentResolver = new ApplicationContentResolver(this, mainThread);
}
@Override
public ContentResolver getContentResolver() {
return mContentResolver;
}
根据上面代码可知, ContextImpl.getContentResolver获取到ApplicationContentResolver对象.
[ -> frameworks/base/core/java/android/app/ContextImpl.java ]
private static final class ApplicationContentResolver extends ContentResolver {
private final ActivityThread mMainThread;
public ApplicationContentResolver(Context context, ActivityThread mainThread) {
super(context);
mMainThread = Preconditions.checkNotNull(mainThread);
}
@Override
protected IContentProvider acquireProvider(Context context, String auth) {
return mMainThread.acquireProvider(context,
ContentProvider.getAuthorityWithoutUserId(auth),
resolveUserIdFromAuthority(auth), true);
}
@Override
protected IContentProvider acquireExistingProvider(Context context, String auth) {
return mMainThread.acquireExistingProvider(context,
ContentProvider.getAuthorityWithoutUserId(auth),
resolveUserIdFromAuthority(auth), true);
}
@Override
protected IContentProvider acquireUnstableProvider(Context c, String auth) {
return mMainThread.acquireProvider(c,
ContentProvider.getAuthorityWithoutUserId(auth),
resolveUserIdFromAuthority(auth), false);
}
protected int resolveUserIdFromAuthority(String auth) {
return ContentProvider.getUserIdFromAuthority(auth, getUserId());
}
...
}
而ApplicationContentResolver继承ContentResolver, 我们看下父类的实现:
public abstract class ContentResolver implements ContentInterface {
...
public final @Nullable Cursor query(@RequiresPermission.Read @NonNull Uri uri,
@Nullable String[] projection, @Nullable String selection,
@Nullable String[] selectionArgs, @Nullable String sortOrder) {
return query(uri, projection, selection, selectionArgs, sortOrder, null);
}
public final @Nullable Cursor query(@RequiresPermission.Read @NonNull Uri uri,
@Nullable String[] projection, @Nullable String selection,
@Nullable String[] selectionArgs, @Nullable String sortOrder,
@Nullable CancellationSignal cancellationSignal) {
// 将查询条件封装到Bundle. 参考【第4.1节】
Bundle queryArgs = createSqlQueryBundle(selection, selectionArgs, sortOrder);
// 查询操作. 参考【第4.2节】
return query(uri, projection, queryArgs, cancellationSignal);
}
...
}
其中 ContentResolver.query(…) 各参数含义:
public static @Nullable Bundle createSqlQueryBundle(
@Nullable String selection,
@Nullable String[] selectionArgs,
@Nullable String sortOrder) {
if (selection == null && selectionArgs == null && sortOrder == null) {
return null;
}
Bundle queryArgs = new Bundle();
if (selection != null) {
queryArgs.putString(QUERY_ARG_SQL_SELECTION, selection);
}
if (selectionArgs != null) {
queryArgs.putStringArray(QUERY_ARG_SQL_SELECTION_ARGS, selectionArgs);
}
if (sortOrder != null) {
queryArgs.putString(QUERY_ARG_SQL_SORT_ORDER, sortOrder);
}
return queryArgs;
}
@Override
public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,
@Nullable String[] projection, @Nullable Bundle queryArgs,
@Nullable CancellationSignal cancellationSignal) {
// 此处mWrapped为空, 调不到
if (mWrapped != null) {
return mWrapped.query(uri, projection, queryArgs, cancellationSignal);
}
// 获取ContentProviderProxy对象(stable为false). 参考【第5节】
IContentProvider unstableProvider = acquireUnstableProvider(uri);
if (unstableProvider == null) {
return null;
}
IContentProvider stableProvider = null;
Cursor qCursor = null;
try {
long startTime = SystemClock.uptimeMillis();
ICancellationSignal remoteCancellationSignal = null;
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
// 拿到ICancellationSignal.Stub.Proxy
remoteCancellationSignal = unstableProvider.createCancellationSignal();
// 设置远程代理
cancellationSignal.setRemote(remoteCancellationSignal);
}
try {
// ContentProviderProxy#query. 参考【第7节】
qCursor = unstableProvider.query(mPackageName, uri, projection, queryArgs, remoteCancellationSignal);
} catch (DeadObjectException e) {
unstableProviderDied(unstableProvider);
// 获取ContentProviderProxy对象(stable为true)
stableProvider = acquireProvider(uri);
if (stableProvider == null) {
return null;
}
// ContentProviderProxy#query
qCursor = stableProvider.query(mPackageName, uri, projection, queryArgs, remoteCancellationSignal);
}
if (qCursor == null) {
return null;
}
// 获取查到的行数, 当qCursor被关闭时会抛出异常
qCursor.getCount();
// CursorWrapperInner封装qCursor和provder并返回
final IContentProvider provider = (stableProvider != null) ? stableProvider : acquireProvider(uri);
final CursorWrapperInner wrapper = new CursorWrapperInner(qCursor, provider);
stableProvider = null;
qCursor = null;
return wrapper;
} catch (RemoteException e) {
return null;
} finally {
// 资源释放
if (qCursor != null) {
qCursor.close();
}
if (cancellationSignal != null) {
cancellationSignal.setRemote(null);
}
if (unstableProvider != null) {
releaseUnstableProvider(unstableProvider);
}
if (stableProvider != null) {
releaseProvider(stableProvider);
}
}
}
ApplicationContentResolver#query分为2个主要步骤:获取Provider
和query查询
.
[ -> frameworks/base/core/java/android/app/ContextImpl.java ]
// 根据Uri查询ContentProvider
public final IContentProvider acquireUnstableProvider(Uri uri) {
// uri必须以content开头
if (!SCHEME_CONTENT.equals(uri.getScheme())) {
return null;
}
// 获取authority(全格式为host:port)
String auth = uri.getAuthority();
if (auth != null) {
// 走到实现类ApplicationContentResolver#acquireUnstableProvider
// 最终走到ActivityThread.acquireProvider
return acquireUnstableProvider(mContext, uri.getAuthority());
}
return null;
}
[ -> frameworks/base/core/java/android/app/ActivityThread.java ]
public final IContentProvider acquireProvider(Context c, String auth, int userId, boolean stable) {
// 先从map缓存中查询本地ContentProvider. 参考【第5.2.2节】
final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
if (provider != null) {
return provider;
}
// IActivity.Stub.Proxy#getContentProvider获取ContentProviderHolder. 参考【第5.3节】
ContentProviderHolder holder = null;
synchronized (getGetProviderLock(auth, userId)) {
holder = ActivityManager.getService().getContentProvider(getApplicationThread(), c.getOpPackageName(), auth, userId, stable);
}
if (holder == null) {
return null;
}
// 增加引用计数, 同时删除老的provider
holder = installProvider(c, holder, holder.info, true /*noisy*/, holder.noReleaseNeeded, stable);
// ContentProviderProxy
return holder.provider;
}
获取ContentProvider过程:
1.先根据ProviderKey从本地缓存中查询, 若查询到则直接返回
2.若本地缓存没有, 则通过Binder通信找AMS获取
其中ProviderKey由authority和userId组成. 它们的获取逻辑为:
[ -> frameworks/base/core/java/android/content/ContentProvider.java ]
// 例如userId@some.authority, 返回值为some.authority
public static String getAuthorityWithoutUserId(String auth) {
if (auth == null) return null;
int end = auth.lastIndexOf('@');
return auth.substring(end+1);
}
// 例如userId@some.authority, 返回值为userId
public static int getUserIdFromAuthority(String auth, int defaultUserId) {
if (auth == null) return defaultUserId;
int end = auth.lastIndexOf('@');
if (end == -1) return defaultUserId;
String userIdString = auth.substring(0, end);
try {
return Integer.parseInt(userIdString);
} catch (NumberFormatException e) {
return UserHandle.USER_NULL;
}
}
// 从缓存查询ContentProvider
public final IContentProvider acquireExistingProvider(Context c, String auth, int userId, boolean stable) {
synchronized (mProviderMap) {
// 根据authority和userId封装ProviderKey对象
final ProviderKey key = new ProviderKey(auth, userId);
// 根据ProviderKey查询ProviderClientRecord
final ProviderClientRecord pr = mProviderMap.get(key);
if (pr == null) {
return null;
}
// 拿到ContentProviderProxy
IContentProvider provider = pr.mProvider;
// 拿到mRemote-Transport(即ContentProviderNative实现类)
IBinder jBinder = provider.asBinder();
if (!jBinder.isBinderAlive()) {
// 若mRemote所在进程已经死掉, 则从mProviderMap和mProviderRefCountMap中移除该provider
// 及引用计数, 并告诉AMS该provider不可用
handleUnstableProviderDiedLocked(jBinder, true);
return null;
}
// 获取provider引用计数, 引用计数+1
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
if (prc != null) {
// 参考【第5.2.3节】
incProviderRefLocked(prc, stable);
}
return provider;
}
}
private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
if (stable) {
prc.stableCount += 1;
if (prc.stableCount == 1) {
int unstableDelta;
if (prc.removePending) {
unstableDelta = -1;
prc.removePending = false;
mH.removeMessages(H.REMOVE_PROVIDER, prc);
} else {
unstableDelta = 0;
}
ActivityManager.getService().refContentProvider(prc.holder.connection, 1, unstableDelta);
}
} else {
prc.unstableCount += 1;
if (prc.unstableCount == 1) {
if (prc.removePending) {
prc.removePending = false;
mH.removeMessages(H.REMOVE_PROVIDER, prc);
} else {
ActivityManager.getService().refContentProvider(prc.holder.connection, 0, 1);
}
}
}
}
若本地缓存没有查找到, 则通过Binder通信找AMS获取.
下面主要分析ActivityManager.getService().getContentProvider(...)
过程.
之前文章 AIDL过程 已经分析过ActivityManager.getService()拿到IActivityManager.Stub.Proxy对象.
在那篇文章是以startService为例, AMP向AMS发送启动服务的请求, 不关注返回值. 本文是getContentProvider, 是AMP向AMS发送获取ContentProvider对象的请求, AMS会向AMP返回ContentProvider.
那么通过AMP.getContentProvider(…)获取到的provider究竟是什么呢? 我们通过下面的分析会知道是ContentProviderProxy.
interface IActivityManager {
...
ContentProviderHolder getContentProvider(in IApplicationThread caller,
in String callingPackage, in String name, int userId, boolean stable);
...
}
IActivityManager.aidl文件编译后的Java产物为:
public interface IActivityManager extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder
implements android.app.IActivityManager
{
private static final java.lang.String DESCRIPTOR = "android.app.IActivityManager";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
// Cast an IBinder object into an android.app.IActivityManager interface,
// generating a proxy if needed.
public static android.app.IActivityManager asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof android.app.IActivityManager))) {
return ((android.app.IActivityManager)iin);
}
return new android.app.IActivityManager.Stub.Proxy(obj);
}
@Override
public android.os.IBinder asBinder()
{
return this;
}
@Override
public boolean onTransact(int code, android.os.Parcel data,
android.os.Parcel reply, int flags) throws android.os.RemoteException
{
java.lang.String descriptor = DESCRIPTOR;
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(descriptor);
return true;
}
case TRANSACTION_getContentProvider:
{
data.enforceInterface(descriptor);
IApplicationThread _arg0 = (IApplicationThread) data.readStrongBinder();
java.lang.String _arg1 = (java.lang.String) data.readString();
java.lang.String _arg2 = data.readString();
int _arg3 = data.readInt();
boolean _arg4 = data.readBoolean();
android.app.ContentProviderHolder _result = this.getContentProvider(_arg0, _arg1, _arg2, _arg3, _arg4);
reply.writeNoException();
if ((_result!=null)) {
reply.writeInt(1);
// 会走到ContentProviderHolder.writeToParcel, reply中写进的provider是Transport
_result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
reply.writeInt(0);
}
return true;
}
default:
{
return super.onTransact(code, data, reply, flags);
}
}
}
private static class Proxy implements android.app.IActivityManager
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override
public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override
public android.app.ContentProviderHolder getContentProvider(
in IApplicationThread caller, java.lang.String callingPackage,
java.lang.String name, int userId,
boolean stable) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
android.app.ContentProviderHolder _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStrongBinder(caller);
_data.writeString(callingPackage);
_data.writeString(name);
_data.writeInt(userId);
_data.writeBoolean(stable);
mRemote.transact(Stub.TRANSACTION_getContentProvider, _data, _reply, 0);
_reply.readException();
if ((0!=_reply.readInt())) {
// 最终ContentProviderHolder中读取出来的provider是ContentProviderProxy
_result = android.app.ContentProviderHolder.CREATOR.createFromParcel(_reply);
} else {
_result = null;
}
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_getContentProvider = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public android.app.ContentProviderHolder getContentProvider(
in IApplicationThread caller, java.lang.String callingPackage,
java.lang.String name, int userId,
boolean stable) throws android.os.RemoteException;
}
在文章 AIDL过程 已经分析过IActivityManager.aidl的调用逻辑:
IActivityManager.Stub.Proxy#getContentProvider -> mRemote.transact ->
IActivityManager.Stub#onTransact -> IActivityManager#getContentProvider(AMS端) ->
ContentViewHolder.writeToParcel(AMS端) -> ContentProviderHolder.CREATOR.createFromParcel(AMP端)
我们再看AMS.getContentProvider过程, 那么它返回的provider是什么呢?
[ -> frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java ]
@Override
public final ContentProviderHolder getContentProvider(
IApplicationThread caller, String callingPackage, String name, int userId,
boolean stable) {
// 不允许isolate进程调用
enforceNotIsolatedCaller("getContentProvider");
...
final int callingUid = Binder.getCallingUid();
return getContentProviderImpl(caller, name, null, callingUid, callingPackage, null, stable, userId);
}
private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
String name, IBinder token, int callingUid, String callingPackage,
String callingTag, boolean stable, int userId) {
ContentProviderRecord cpr;
ContentProviderConnection conn = null;
ProviderInfo cpi = null;
boolean providerRunning = false;
synchronized(this) {
long startTime = SystemClock.uptimeMillis();
ProcessRecord r = null;
if (caller != null) {
r = getRecordForAppLocked(caller);
}
boolean checkCrossUser = true;
// 根据name获取ContentProviderRecord对象, 若普通用户未获取到, 则从系统用户获取
cpr = mProviderMap.getProviderByName(name, userId);
if (cpr == null && userId != UserHandle.USER_SYSTEM) {
cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
if (cpr != null) {
cpi = cpr.info;
if (isSingleton(cpi.processName, cpi.applicationInfo, cpi.name, cpi.flags)
&& isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
userId = UserHandle.USER_SYSTEM;
checkCrossUser = false;
} else {
cpr = null;
cpi = null;
}
}
}
// 检查ContentProviderRecord所在进程是否被杀, 若进程被杀, 执行数据清理操作
if (cpr != null && cpr.proc != null) {
// 检查provider是否正在运行
providerRunning = !cpr.proc.killed;
if (cpr.proc.killed && cpr.proc.killedByAm) {
appDiedLocked(cpr.proc);
}
}
// 若provider正在运行
if (providerRunning) {
cpi = cpr.info;
String msg;
if (r != null && cpr.canRunHere(r)) {
// 权限检查
...
ContentProviderHolder holder = cpr.newHolder(null);
holder.provider = null;
return holder;
}
// IPackageManager.Stub.Proxy#resolveContentProvider.
// Binder通信PMP请求PMS解析出ContentProvider, 即PMS.resolveContentProvider
// 而PMS又通过ComponentResolver组件解析器解析出ProviderInfo.
// 对于联系人ProviderInfo中provider名称是ContactsProvider2, 参考【第5.3.3节】
if (AppGlobals.getPackageManager().resolveContentProvider(name, 0 /*flags*/, userId) == null) {
return null;
}
final long origId = Binder.clearCallingIdentity();
// ContentProviderRecord计数+1
conn = incProviderCountLocked(r, cpr, token, callingUid, callingPackage, callingTag, stable);
if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
// 更新lru进程信息
mProcessList.updateLruProcessLocked(cpr.proc, false, null);
}
}
final int verifiedAdj = cpr.proc.verifiedAdj;
boolean success = updateOomAdjLocked(cpr.proc, true, OomAdjuster.OOM_ADJ_REASON_GET_PROVIDER);
if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
success = false;
}
if (!success) {
boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
appDiedLocked(cpr.proc);
if (!lastRef) {
return null;
}
providerRunning = false;
conn = null;
} else {
cpr.proc.verifiedAdj = cpr.proc.setAdj;
}
Binder.restoreCallingIdentity(origId);
}
// 若provider不在运行
if (!providerRunning) {
// IPackageManager.Stub.Proxy#resolveContentProvider.
// Binder通信PMP请求PMS解析出ContentProvider, 即PMS.resolveContentProvider
// 而PMS又通过ComponentResolver组件解析器解析出ProviderInfo.
// 对于联系人ProviderInfo中provider名称是ContactsProvider2, 参考【第5.3.3节】
cpi = AppGlobals.getPackageManager().resolveContentProvider(name, STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
if (cpi == null) {
return null;
}
// If the provider is a singleton AND
// (it's a call within the same user || the provider is a
// privileged app)
// Then allow connecting to the singleton provider
boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, cpi.name, cpi.flags)
&& isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
if (singleton) {
userId = UserHandle.USER_SYSTEM;
}
cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
// 各种有效性检查, 包括:系统是否ready
...
// 根据ComponentName从mProviderMap中查找, 若没找到则新建
ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
cpr = mProviderMap.getProviderByClass(comp, userId);
final boolean firstClass = cpr == null;
if (firstClass) {
try {
ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(
cpi.applicationInfo.packageName, STOCK_PM_FLAGS, userId);
ai = getAppInfoForUser(ai, userId);
cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
} catch (RemoteException ex) {
// pm is in same process, this will never happen.
} finally {
Binder.restoreCallingIdentity(ident);
}
}
// 如果是单进程, 或provider允许多进程多个实例
if (r != null && cpr.canRunHere(r)) {
return cpr.newHolder(null);
}
// 检查当前ContentProviderRecord是否已启动
final int N = mLaunchingProviders.size();
int i;
for (i = 0; i < N; i++) {
if (mLaunchingProviders.get(i) == cpr) {
break;
}
}
// 若当前ContentProviderRecord未启动
if (i >= N) {
final long origId = Binder.clearCallingIdentity();
try {
// Content provider is now in use, its package can't be stopped.
AppGlobals.getPackageManager().setPackageStoppedState(cpr.appInfo.packageName, false, userId);
// 获取当前ContentProvider所在进程
ProcessRecord proc = getProcessRecordLocked(cpi.processName, cpr.appInfo.uid, false);
if (proc != null && proc.thread != null && !proc.killed) {
// 若进程正在运行中, 且cpi还未发布, 则将其加到map中并发布Provider
if (!proc.pubProviders.containsKey(cpi.name)) {
proc.pubProviders.put(cpi.name, cpr);
// 安装和发布provider
proc.thread.scheduleInstallProvider(cpi);
}
} else {
// 否则启动新进程
proc = startProcessLocked(cpi.processName,
cpr.appInfo, false, 0,
new HostingRecord("content provider",
new ComponentName(cpi.applicationInfo.packageName, cpi.name)), false, false, false);
}
// cpr添加到mLaunchingProviders列表
cpr.launchingApp = proc;
mLaunchingProviders.add(cpr);
} finally {
Binder.restoreCallingIdentity(origId);
}
}
// ContentProviderRecord对象存到mProviderMap
if (firstClass) {
mProviderMap.putProviderByClass(comp, cpr);
}
mProviderMap.putProviderByName(name, cpr);
// provider引用+1
conn = incProviderCountLocked(r, cpr, token, callingUid, callingPackage, callingTag, stable);
if (conn != null) {
conn.waiting = true;
}
}
}
// 等待provider被发布, 超时时间20秒
final long timeout = SystemClock.uptimeMillis() + CONTENT_PROVIDER_WAIT_TIMEOUT;
boolean timedOut = false;
synchronized (cpr) {
while (cpr.provider == null) {
try {
final long wait = Math.max(0L, timeout - SystemClock.uptimeMillis());
if (conn != null) {
conn.waiting = true;
}
cpr.wait(wait);
if (cpr.provider == null) {
timedOut = true;
break;
}
} catch (InterruptedException ex) {
} finally {
if (conn != null) {
conn.waiting = false;
}
}
}
}
// 超时返空
if (timedOut) {
return null;
}
// 返回ContentProviderHolder. 持有的provider是ContactsProvider2(可理解为Transport)
return cpr.newHolder(conn);
}
AMS.getContentProvider(String name, int userId)总结:
1.根据name从mProviderMap中查找ContentProviderRecord对象cpr, 若普通用户未获取到, 则从系统用户获取
2.如果cpr非空, 则检查cpr所在进程是否被杀, 若进程被杀, 执行数据清理操作. 检查provider是否正在运行
3.若provider正在运行:
(1) 通过IPackageManger.Stub.Proxy#resolveContentProvider解析出ProviderInfo, 且cpr引用计数+1, 并更新lru进程信息
4.若provider不在运行:
(1) 通过IPackageManger.Stub.Proxy#resolveContentProvider解析出ProviderInfo
(2) 根据ProviderInfo封装ComponentName, 并从mProviderMap中查找cpr, 若没找到则新建一个
(3) 如果当前是单进程, 或provider允许多进程多个实例, 则直接返回
(4) 检查cpr是否在mLaunchingProviders列表, 若不在, 则检查cpr所在进程是否正在运行.
(5) 若cpr所在进程正在运行, 但ProviderInfo对应的provider还未发布, 则将ProviderInfo加到map中, 执行ApplicationThread#scheduleInstallProvider发布Provider
(6) 若cpr所在进程不在运行, 则启动新进程. cpr添加到mLaunchingProviders和mProviderMap, cpr引用计数+1, 等待provider被发布, 超时时间20秒, 若超时返空
5.返回ContentProviderHolder. 此时持有的provider是ContactsProvider2(可理解为Transport)
[ -> frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java ]
@Override
public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
return resolveContentProviderInternal(name, flags, userId);
}
private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
flags = updateFlagsForComponent(flags, userId, name);
final int callingUid = Binder.getCallingUid();
// 组件解析器解析ComponentResolver.queryProvider. 参考【第5.3.4节】
final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, userId);
if (providerInfo == null) {
return null;
}
if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
return null;
}
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName);
final ComponentName component = new ComponentName(providerInfo.packageName, providerInfo.name);
if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
return null;
}
return providerInfo;
}
}
我们知道PMS.resolveContentProvider最终会拿到ContactsProvider2. 那么它是怎么拿到的呢? 我们继续往下看这个过程.
[ -> frameworks/base/services/core/java/com/android/server/pm/ComponentResolver.java ]
ProviderInfo queryProvider(String authority, int flags, int userId) {
synchronized (mLock) {
final PackageParser.Provider p = mProvidersByAuthority.get(authority);
if (p == null) {
return null;
}
final PackageSetting ps = (PackageSetting) p.owner.mExtras;
if (ps == null) {
return null;
}
return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), userId);
}
}
现在分析下mProvidersByAuthority的取值.
根据赋值的地方反查可得出如下调用链:
PMS: PackageHandler.INIT_COPY -> startCopy -> handleReturnCode -> processPendingInstall ->
processInstallRequestsAsync -> installPackagesLI -> commitPackagesLocked ->
commitReconciledScanResultLocked -> commitPackageSettings
ComponentResolver: addAllComponents -> addProvidersLocked
我们再看下ComponentResolver#addProvidersLocked实现.
private void addProvidersLocked(PackageParser.Package pkg, boolean chatty) {
final int providersSize = pkg.providers.size();
StringBuilder r = null;
for (int i = 0; i < providersSize; i++) {
PackageParser.Provider p = pkg.providers.get(i);
p.info.processName = fixProcessName(pkg.applicationInfo.processName, p.info.processName);
mProviders.addProvider(p);
p.syncable = p.info.isSyncable;
if (p.info.authority != null) {
String[] names = p.info.authority.split(";");
p.info.authority = null;
for (int j = 0; j < names.length; j++) {
if (j == 1 && p.syncable) {
p = new PackageParser.Provider(p);
p.syncable = false;
}
if (!mProvidersByAuthority.containsKey(names[j])) {
mProvidersByAuthority.put(names[j], p);
if (p.info.authority == null) {
p.info.authority = names[j];
} else {
p.info.authority = p.info.authority + ";" + names[j];
}
} else {
final PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
final ComponentName component =
(other != null && other.getComponentName() != null)
? other.getComponentName() : null;
final String packageName = component != null ? component.getPackageName() : "?";
}
}
}
}
}
其中有个很重要的角色包解析器PackageParser
, 它会在App安装过程中解析各种文件包括AndroidManifest.xml
解析出来的信息会封装在PackageParser.Package
对象中.
我们再看下Contacts应用程序的providers包下的AndroidManifest.xml文件.
[ -> packages/providers/ContactsProvider/AndroidManifest.xml ]
...
<application android:process="android.process.acore"
android:label="@string/app_label"
android:icon="@drawable/app_icon"
android:allowBackup="false"
android:usesCleartextTraffic="false">
<provider android:name="ContactsProvider2"
android:authorities="contacts;com.android.contacts"
android:label="@string/provider_label"
android:multiprocess="false"
android:exported="true"
android:grantUriPermissions="true"
android:readPermission="android.permission.READ_CONTACTS"
android:writePermission="android.permission.WRITE_CONTACTS"
android:visibleToInstantApps="true">
<path-permission
android:pathPrefix="/search_suggest_query"
android:readPermission="android.permission.GLOBAL_SEARCH" />
<path-permission
android:pathPrefix="/search_suggest_shortcut"
android:readPermission="android.permission.GLOBAL_SEARCH" />
<path-permission
android:pathPattern="/contacts/.*/photo"
android:readPermission="android.permission.GLOBAL_SEARCH" />
<grant-uri-permission android:pathPattern=".*" />
</provider>
...
</application>
...
mProvidersByAuthority最终会存储key为contacts和com.android.contacts, value为ContactsProvider2的信息. 因此我们得出结论, PMS.resolveContentProvider拿到的是ContactsProvider2对应的ProviderInfo.
那么经过AIDL Binder通信, AMP.getContentProvider拿到的究竟是什么呢?
我们再看下ContentProviderHolder的实现:
[ -> frameworks/base/core/java/android/app/ContentProviderHolder.java ]
public class ContentProviderHolder implements Parcelable {
public final ProviderInfo info;
public IContentProvider provider;
public IBinder connection;
public boolean noReleaseNeeded;
public ContentProviderHolder(ProviderInfo _info) {
info = _info;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
info.writeToParcel(dest, 0);
if (provider != null) {
// 写入的是Transport
dest.writeStrongBinder(provider.asBinder());
} else {
dest.writeStrongBinder(null);
}
dest.writeStrongBinder(connection);
dest.writeInt(noReleaseNeeded ? 1 : 0);
}
public static final Parcelable.Creator<ContentProviderHolder> CREATOR
= new Parcelable.Creator<ContentProviderHolder>() {
@Override
public ContentProviderHolder createFromParcel(Parcel source) {
return new ContentProviderHolder(source);
}
@Override
public ContentProviderHolder[] newArray(int size) {
return new ContentProviderHolder[size];
}
};
private ContentProviderHolder(Parcel source) {
info = ProviderInfo.CREATOR.createFromParcel(source);
// 拿到的provider是ContentProviderProxy
provider = ContentProviderNative.asInterface(source.readStrongBinder());
connection = source.readStrongBinder();
noReleaseNeeded = source.readInt() != 0;
}
}
结合上面的IActivityManager.aidl分析过程中的调用链:
IActivityManager.Stub.Proxy#getContentProvider -> mRemote.transact ->
IActivityManager.Stub#onTransact -> IActivityManager#getContentProvider(AMS端) ->
ContentViewHolder.writeToParcel(AMS端) -> ContentProviderHolder.CREATOR.createFromParcel(AMP端)
我们已经知道了AMS.getContentProvider拿到的是ContactsProvider2(可理解为Transport和ContentProviderNative)
结合ContentProviderHolder源码可知, ContentViewHolder.writeToParcel(AMS端)写入的是Transport, ContentProviderHolder.CREATOR.createFromParcel(AMP端)拿到的是ContentProviderProxy.
最终ActivityManager.getService().getContentProvider(…) 拿到的是ContentProviderProxy
同时只有provider先发布, 才能获取到provider. 发布逻辑主要在ApplicationThread.scheduleInstallProvider
[ -> frameworks/base/core/java/android/app/ActivityThread.java ]
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleInstallProvider(ProviderInfo provider) {
sendMessage(H.INSTALL_PROVIDER, provider);
}
}
class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
...
case INSTALL_PROVIDER:
handleInstallProvider((ProviderInfo) msg.obj);
break;
...
}
}
}
public void handleInstallProvider(ProviderInfo info) {
installContentProviders(mInitialApplication, Arrays.asList(info));
}
private void installContentProviders(Context context, List<ProviderInfo> providers) {
final ArrayList<ContentProviderHolder> results = new ArrayList<>();
for (ProviderInfo cpi : providers) {
// 安装ContentProvider
// 新建ContentProvider并设置上下文Context
// 将Provider本地对象封装到ContentProviderRecord中并添加到各map中
ContentProviderHolder cph = installProvider(context, null, cpi, false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
if (cph != null) {
cph.noReleaseNeeded = true;
results.add(cph);
}
}
// 发布ContentProvider. AMP#publishContentProviders(向AMS发送Binder请求)
// 主要就是将进程中pubProviders的provider添加到相关map, 并设置provider和进程等信息
// 然后通过notifyAll通知provider发布完成.
ActivityManager.getService().publishContentProviders(getApplicationThread(), results);
}
ApplicationThread.installContentProviders()过程分为2个过程:
1.installProvider: 安装Provider
2.publishContentProviders: 发布Provider
// 安装Provider.
// 进程本地或SystemServer进程的provider是永久安装不释放的(noReleaseNeeded为true), 没有引用计数. 其他远程provider是引用计数, 初始计数为1
// 当provider安装时, 需要增加引用计数(若支持引用计数)并返回provider
private ContentProviderHolder installProvider(Context context,
ContentProviderHolder holder, ProviderInfo info,
boolean noisy, boolean noReleaseNeeded, boolean stable) {
// localProvider指ContentProvider(联系人为ContactsProvider2), provider指Transport-ContentProviderNative实现类
ContentProvider localProvider = null;
IContentProvider provider;
if (holder == null || holder.provider == null) {
Context c = null;
ApplicationInfo ai = info.applicationInfo;
if (context.getPackageName().equals(ai.packageName)) {
c = context;
} else if (mInitialApplication != null && mInitialApplication.getPackageName().equals(ai.packageName)) {
c = mInitialApplication;
} else {
c = context.createPackageContext(ai.packageName, Context.CONTEXT_INCLUDE_CODE);
}
if (info.splitName != null) {
c = c.createContextForSplit(info.splitName);
}
final java.lang.ClassLoader cl = c.getClassLoader();
LoadedApk packageInfo = peekPackageInfo(ai.packageName, true);
if (packageInfo == null) {
// System startup case.
packageInfo = getSystemContext().mPackageInfo;
}
// 新建ContentProvider(联系人为ContactsProvider2), 并初始化
// 参考【第5.3.3节】PMS.resolveContentProvider可知, ProviderInfo的name是ContactsProvider2
localProvider = packageInfo.getAppFactory().instantiateProvider(cl, info.name);
// 返回Transport(ContentProviderNative的实现类)
provider = localProvider.getIContentProvider();
localProvider.attachInfo(c, info);
} else {
// 安装外部Provider
provider = holder.provider;
}
ContentProviderHolder retHolder;
synchronized (mProviderMap) {
// 返回ContentProvider的本地对象Transport(也是一个Binder)
IBinder jBinder = provider.asBinder();
if (localProvider != null) {
ComponentName cname = new ComponentName(info.packageName, info.name);
ProviderClientRecord pr = mLocalProvidersByName.get(cname);
if (pr != null) {
// 使用本地provider
provider = pr.mProvider;
} else {
// ContentProviderHolder是Parcelable
// 写入ContentProviderHolder的provider是Transport, 经过Binder通信传输后, 拿到的provider是ContentProviderProxy对象
holder = new ContentProviderHolder(info);
holder.provider = provider;
holder.noReleaseNeeded = true;
// 新建ProviderClientRecord, 并将其添加到各个map中
pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
mLocalProviders.put(jBinder, pr);
mLocalProvidersByName.put(cname, pr);
}
retHolder = pr.mHolder;
} else {
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
if (prc != null) {
// provider引用+1, 同时释放老的provider
// We need to transfer our new reference to the existing
// ref count, releasing the old one... but only if
// release is needed (that is, it is not running in the
// system process).
if (!noReleaseNeeded) {
incProviderRefLocked(prc, stable);
ActivityManager.getService().removeContentProvider(holder.connection, stable);
}
} else {
ProviderClientRecord client = installProviderAuthoritiesLocked(provider, localProvider, holder);
if (noReleaseNeeded) {
prc = new ProviderRefCount(holder, client, 1000, 1000);
} else {
prc = stable ? new ProviderRefCount(holder, client, 1, 0) : new ProviderRefCount(holder, client, 0, 1);
}
mProviderRefCountMap.put(jBinder, prc);
}
retHolder = prc.holder;
}
}
return retHolder;
}
// 添加到mProviderMap中(key为ProviderKey, value为ProviderClientRecord)
// ProviderKey包含元素authrity和userId, ProviderClientRecord包含元素auths/provider/localProvider/holder
private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
ContentProvider localProvider, ContentProviderHolder holder) {
final String auths[] = holder.info.authority.split(";");
final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
if (provider != null) {
// If this provider is hosted by the core OS and cannot be upgraded,
// then I guess we're okay doing blocking calls to it.
for (String auth : auths) {
switch (auth) {
case ContactsContract.AUTHORITY:
case CallLog.AUTHORITY:
case CallLog.SHADOW_AUTHORITY:
case BlockedNumberContract.AUTHORITY:
case CalendarContract.AUTHORITY:
case Downloads.Impl.AUTHORITY:
case "telephony":
Binder.allowBlocking(provider.asBinder());
}
}
}
final ProviderClientRecord pcr = new ProviderClientRecord(auths, provider, localProvider, holder);
for (String auth : auths) {
final ProviderKey key = new ProviderKey(auth, userId);
final ProviderClientRecord existing = mProviderMap.get(key);
if (existing == null) {
mProviderMap.put(key, pcr);
}
}
return pcr;
}
[ -> frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java ]
// 遍历ContentProviderHolder列表, 从调用进程的pubProviders map中查找是否包含指定名称的ContentProviderRecord
// 若存在则将其存到相关map中, 并检查是否在launching过程中, 若是则将其从mLaunchingProviders列表移除, 同时杀死provider所在进程
// 否则设置provider和进程信息后, notifyAll通知provider发布完成.
public final void publishContentProviders(IApplicationThread caller, List<ContentProviderHolder> providers) {
if (providers == null) {
return;
}
enforceNotIsolatedCaller("publishContentProviders");
synchronized (this) {
// 获取调用进程
final ProcessRecord r = getRecordForAppLocked(caller);
final int N = providers.size();
for (int i = 0; i < N; i++) {
ContentProviderHolder src = providers.get(i);
if (src == null || src.info == null || src.provider == null) {
continue;
}
// 以name为key, 从当前进程发布的provider map中查找ContentProviderRecord对象
ContentProviderRecord dst = r.pubProviders.get(src.info.name);
if (dst != null) {
// 存到map中
ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
mProviderMap.putProviderByClass(comp, dst);
String names[] = dst.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
mProviderMap.putProviderByName(names[j], dst);
}
// 检查当前ContentProviderRecord是否在mLaunchingProviders列表, 若在则从列表移除
int launchingCount = mLaunchingProviders.size();
int j;
boolean wasInLaunchingProviders = false;
for (j = 0; j < launchingCount; j++) {
if (mLaunchingProviders.get(j) == dst) {
mLaunchingProviders.remove(j);
wasInLaunchingProviders = true;
j--;
launchingCount--;
}
}
// 若在mLaunchingProviders列表, 则发消息杀死该provider所在的进程
if (wasInLaunchingProviders) {
mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
}
r.addPackage(dst.info.applicationInfo.packageName, dst.info.applicationInfo.longVersionCode, mProcessStats);
// 设置provider和进程, 并通知provider发布完成
synchronized (dst) {
dst.provider = src.provider;
dst.setProcess(r);
dst.notifyAll();
}
// 更新oomAdj
updateOomAdjLocked(r, true, OomAdjuster.OOM_ADJ_REASON_GET_PROVIDER);
}
}
}
}
final class MainHandler extends Handler {
public MainHandler(Looper looper) {
super(looper, null, true);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
...
case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
ProcessRecord app = (ProcessRecord)msg.obj;
synchronized (ActivityManagerService.this) {
// 如果当前provider在launching过程中, 则杀死provider所在的进程
processContentProviderPublishTimedOutLocked(app);
}
} break;
...
}
}
}
private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
cleanupAppInLaunchingProvidersLocked(app, true);
mProcessList.removeProcessLocked(app, false, true, "timeout publishing content providers");
}
[ -> frameworks/base/core/java/android/content/ContentProviderNative.java ]
final class ContentProviderProxy implements IContentProvider
{
// Transport
private IBinder mRemote;
public ContentProviderProxy(IBinder remote)
{
mRemote = remote;
}
@Override
public IBinder asBinder()
{
return mRemote;
}
@Override
public Cursor query(String callingPkg, Uri url, @Nullable String[] projection,
@Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal)
throws RemoteException {
BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor();
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
// 封装data
data.writeInterfaceToken(IContentProvider.descriptor);
data.writeString(callingPkg);
url.writeToParcel(data, 0);
int length = 0;
if (projection != null) {
length = projection.length;
}
data.writeInt(length);
for (int i = 0; i < length; i++) {
data.writeString(projection[i]);
}
data.writeBundle(queryArgs);
data.writeStrongBinder(adaptor.getObserver().asBinder());
data.writeStrongBinder(cancellationSignal != null ? cancellationSignal.asBinder() : null);
// mRemote为Transport, Binder通信最终会走到Transport.onTransact方法
mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0);
DatabaseUtils.readExceptionFromParcel(reply);
if (reply.readInt() != 0) {
// 从reply中读取BulkCursorDescriptor
BulkCursorDescriptor d = BulkCursorDescriptor.CREATOR.createFromParcel(reply);
Binder.copyAllowBlocking(mRemote, (d.cursor != null) ? d.cursor.asBinder() : null);
// 初始化BulkCursorToCursorAdaptor
adaptor.initialize(d);
} else {
adaptor.close();
adaptor = null;
}
return adaptor;
} catch (RemoteException ex) {
adaptor.close();
throw ex;
} catch (RuntimeException ex) {
adaptor.close();
throw ex;
} finally {
data.recycle();
reply.recycle();
}
}
...
}
[ -> frameworks/base/core/java/android/content/ContentProviderNative.java ]
由于Transport继承ContentProviderNative, 因此等价于调用ContentProviderNative.onTransact
abstract public class ContentProviderNative extends Binder implements IContentProvider {
public ContentProviderNative()
{
attachInterface(this, descriptor);
}
/**
* Cast a Binder object into a content resolver interface, generating
* a proxy if needed.
*/
static public IContentProvider asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IContentProvider in = (IContentProvider)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ContentProviderProxy(obj);
}
/**
* Gets the name of the content provider.
* Should probably be part of the {@link IContentProvider} interface.
* @return The content provider name.
*/
public abstract String getProviderName();
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case QUERY_TRANSACTION:
{
data.enforceInterface(IContentProvider.descriptor);
String callingPkg = data.readString();
Uri url = Uri.CREATOR.createFromParcel(data);
String[] projection
int num = data.readInt();
String[] projection = null;
if (num > 0) {
projection = new String[num];
for (int i = 0; i < num; i++) {
projection[i] = data.readString();
}
}
Bundle queryArgs = data.readBundle();
IContentObserver observer = IContentObserver.Stub.asInterface(data.readStrongBinder());
ICancellationSignal cancellationSignal = ICancellationSignal.Stub.asInterface(data.readStrongBinder());
// 真正执行数据查询工作
Cursor cursor = query(callingPkg, url, projection, queryArgs, cancellationSignal);
if (cursor != null) {
CursorToBulkCursorAdaptor adaptor = null;
try {
adaptor = new CursorToBulkCursorAdaptor(cursor, observer, getProviderName());
cursor = null;
BulkCursorDescriptor d = adaptor.getBulkCursorDescriptor();
adaptor = null;
// 将数据写入reply并返回
reply.writeNoException();
reply.writeInt(1);
d.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} finally {
// Close cursor if an exception was thrown while constructing the adaptor.
if (adaptor != null) {
adaptor.close();
}
if (cursor != null) {
cursor.close();
}
}
} else {
reply.writeNoException();
reply.writeInt(0);
}
return true;
}
case GET_TYPE_TRANSACTION: ...
case INSERT_TRANSACTION: ...
case BULK_INSERT_TRANSACTION: ...
case APPLY_BATCH_TRANSACTION: ...
case DELETE_TRANSACTION: ...
case UPDATE_TRANSACTION: ...
case OPEN_FILE_TRANSACTION: ...
case OPEN_ASSET_FILE_TRANSACTION: ...
case CALL_TRANSACTION: ...
case GET_STREAM_TYPES_TRANSACTION: ...
case OPEN_TYPED_ASSET_FILE_TRANSACTION: ...
case CREATE_CANCELATION_SIGNAL_TRANSACTION: ...
case CANONICALIZE_TRANSACTION: ...
case UNCANONICALIZE_TRANSACTION: ...
case REFRESH_TRANSACTION: ...
}
return super.onTransact(code, data, reply, flags);
}
@Override
public IBinder asBinder()
{
return this;
}
}
[ -> frameworks/base/core/java/android/content/ContentProvider.java ]
// Binder object that deals with remoting.
class Transport extends ContentProviderNative {
volatile AppOpsManager mAppOpsManager = null;
volatile int mReadOp = AppOpsManager.OP_NONE;
volatile int mWriteOp = AppOpsManager.OP_NONE;
volatile ContentInterface mInterface = ContentProvider.this;
ContentProvider getContentProvider() {
return ContentProvider.this;
}
@Override
public String getProviderName() {
return getContentProvider().getClass().getName();
}
@Override
public Cursor query(String callingPkg, Uri uri, @Nullable String[] projection,
@Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal) {
uri = validateIncomingUri(uri);
uri = maybeGetUriWithoutUserId(uri);
// 若没有读Uri权限FLAG_GRANT_READ_URI_PERMISSION
if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
// 返回指定列的空Cursor
if (projection != null) {
return new MatrixCursor(projection, 0);
}
// ContentProvider.query查询所有列(projection为null). 参考【第7.4节】
cursor = mInterface.query(uri, projection, queryArgs, CancellationSignal.fromTransport(cancellationSignal));
if (cursor == null) {
return null;
}
// 返回包含所有列的空Cursor
return new MatrixCursor(cursor.getColumnNames(), 0);
}
// ContentProvider.query查询所有列(projection为null)
return mInterface.query(uri, projection, queryArgs, CancellationSignal.fromTransport(cancellationSignal));
}
...
}
前面已经分析过了: AMS.getContentProvider拿到的是ContactsProvider2, AMP.getContentProvider拿到的是ContentProviderProxy.
而mInterface=ContentProvider.this, 对于联系人查询可知, mInterface对应ContactsProvider2.
[ -> frameworks/base/core/java/android/content/ContentProvider.java ]
@Override
public @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection,
@Nullable Bundle queryArgs, @Nullable CancellationSignal cancellationSignal) {
queryArgs = queryArgs != null ? queryArgs : Bundle.EMPTY;
String sortClause = queryArgs.getString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER);
// 一般走不到这里
if (sortClause == null && queryArgs.containsKey(ContentResolver.QUERY_ARG_SORT_COLUMNS)) {
sortClause = ContentResolver.createSqlSortClause(queryArgs);
}
return query(
uri,
projection,
queryArgs.getString(ContentResolver.QUERY_ARG_SQL_SELECTION),
queryArgs.getStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS),
sortClause,
cancellationSignal);
}
[ -> packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsProvider2.java ]
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
return query(uri, projection, selection, selectionArgs, sortOrder, null);
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder, CancellationSignal cancellationSignal) {
...
return queryDirectoryIfNecessary(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal);
}
protected Cursor queryLocal(final Uri uri, final String[] projection, String selection,
String[] selectionArgs, String sortOrder, final long directoryId,
final CancellationSignal cancellationSignal) {
...
final int match = sUriMatcher.match(uri);
switch (match) {
...
case CONTACTS: {
setTablesAndProjectionMapForContacts(qb, projection);
appendLocalDirectoryAndAccountSelectionIfNeeded(qb, directoryId, uri);
break;
}
case CONTACTS_ID: ...
...
}
...
Cursor cursor = doQuery(db, qb, projection, selection, selectionArgs, localizedSortOrder, groupBy, having, limit, cancellationSignal);
return cursor;
}
private Cursor doQuery(final SQLiteDatabase db, SQLiteQueryBuilder qb, String[] projection,
String selection, String[] selectionArgs, String sortOrder, String groupBy,
String having, String limit, CancellationSignal cancellationSignal) {
if (projection != null && projection.length == 1
&& BaseColumns._COUNT.equals(projection[0])) {
qb.setProjectionMap(sCountProjectionMap);
}
final Cursor c = qb.query(db, projection, selection, selectionArgs, groupBy, having,
sortOrder, limit, cancellationSignal);
if (c != null) {
c.setNotificationUri(getContext().getContentResolver(), ContactsContract.AUTHORITY_URI);
}
return c;
}
剩下的操作就是SQLite数据库操作了. 并且Cursor操作直接操作到Native层了. 本节暂不分析SQLite原理.
通过ContentProviderProxy.query查询操作最终拿到的Cursor是BulkCursorToCursorAdaptor类型.
通过ApplicationContentResolver.query拿到的是CursorWrapperInner(new BulkCursorToCursorAdaptor())
ContentProvider整个查询过程分为如下步骤:
1.ContextImpl.getContentResolver()
: 拿到ApplicationContentResolver
2.ApplicationContentResolver.query
: 执行查询操作, 该过程又分为3个过程:
2.1 获取ContentProviderProxy.
其调用链为:
ApplicationContentResolver.acquireProvider -> ActivityManager.getService().getContentProvider(...) ->
IActivityManager.Stub.Proxy#getContentProvider -> mRemote.transact ->
IActivityManager.Stub#onTransact -> ActivityManagerService#getContentProvider(AMS端) ->
ContentViewHolder.writeToParcel(AMS端) -> ContentProviderHolder.CREATOR.createFromParcel(AMP端)
2.2 发布ContentProvider(仅当provider未发布时)
ApplicationThread.scheduleInstallProvider, AMS发布的provider是ContactsProvider2, 而AMP端拿到的provider是ContentProviderProxy. 发布超时时间是20秒
2.3 query操作
ContentProviderProxy.query -> ContactsProvider2.query -> SQLite操作, 同时拿到new CursorWrapperInner(new BulkCursorToCursorAdaptor()).
后续操作都是通过CursorWrapperInner来进行读取.
根据ContactsProvider2的继承关系, 可知Contacts中的数据操作还是SQLite操作
public class ContactsProvider2 extends AbstractContactsProvider
public abstract class AbstractContactsProvider extends ContentProvider implements SQLiteTransactionListener
当其他App想访问数据库中的数据时, Contacts端需要提供一个ContactProvider2的接口来提供服务, 其他App端通过Binder通信来请求这个ContactsProvider2服务.
实际上, 根据源码目录:
packages/apps/Contacts: 联系人App
packages/providers/ContactsProvider: 数据提供接口
ContentProvider的这种设计和App开发中调用第三方SDK有种类似的感觉.
]]>基于Android 10.0的源码剖析, 站在Luoshengyang/Innost/Gityuan肩膀上.
本文分析广播Broadcast发送过程.
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
frameworks/base/services/core/java/com/android/server/pm/ComponentResolver.java
frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
frameworks/base/services/core/java/com/android/server/am/BroadcastRecord.java
frameworks/base/core/java/android/app/ContextImpl.java
TODO
[ -> frameworks/base/core/java/android/app/ContextImpl.java ]
@Override
public void sendBroadcast(Intent intent) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
intent.prepareToLeaveProcess(this);
ActivityManager.getService().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false, getUserId());
}
[ -> frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java ]
public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
String[] requiredPermissions, int appOp, Bundle bOptions,
boolean serialized, boolean sticky, int userId) {
enforceNotIsolatedCaller("broadcastIntent");
synchronized(this) {
intent = verifyBroadcastLocked(intent);
final ProcessRecord callerApp = getRecordForAppLocked(caller);
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
return broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null,
intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
requiredPermissions, appOp, bOptions, serialized, sticky,
callingPid, callingUid, callingUid, callingPid, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}
final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, Intent intent, String resolvedType,
IIntentReceiver resultTo, int resultCode, String resultData,
Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid,
int realCallingPid, int userId) {
return broadcastIntentLocked(callerApp, callerPackage, intent, resolvedType, resultTo,
resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions, ordered,
sticky, callingPid, callingUid, realCallingUid, realCallingPid, userId,
false /* allowBackgroundActivityStarts */);
}
具体实现细节看下面代码:
final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, Intent intent, String resolvedType,
IIntentReceiver resultTo, int resultCode, String resultData,
Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid,
int realCallingPid, int userId, boolean allowBackgroundActivityStarts) {
intent = new Intent(intent);
// 1.根据各种限制设置intent的flags: 比如Instant App不能使用FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS, 广播不会发送到杀死的进程, 系统还没启动不允许启动新进程
// 2.检查接收广播的userId是否正在运行
// 3.权限和限制检查: 如CHANGE_DEVICE_IDLE_TEMP_WHITELIST权限, START_ACTIVITIES_FROM_BACKGROUND权限, OP_RUN_ANY_IN_BACKGROUND操作权限
// 4.非系统用户不允许发送ProtectedBroadcast, 系统用户指(ROOT_UID/SYSTEM_UID/PHONE_UID/BLUETOOTH_UID/NFC_UID/SE_UID/NETWORK_STACK_UID)
...
userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true, ALLOW_NON_FULL, "broadcast", callerPackage);
boolean timeoutExempt = false;
final String action = intent.getAction();
if (action != null) {
// 如果action所属Intent需要发送给未启动的或后台的进程, 则Intent添加flags为FLAG_RECEIVER_INCLUDE_BACKGROUND
if (getBackgroundLaunchBroadcasts().contains(action)) {
intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
}
// 包管理器发出的和包移除相关的action的处理,如ACTION_UID_REMOVED/ACTION_PACKAGE_REMOVED/ACTION_PACKAGE_CHANGED/...
...
}
// sticky广播处理, 常规的sendBroadcast发送的都是非sticky广播, 走不到这里
if (sticky) {
// 权限和条件检查包括: Manifest.permission.BROADCAST_STICKY权限检查, requiredPermissions和Component为空检查, mStickyBroadcasts重复广播检查
...
// 将发送的广播Intent替换或插入到mStickyBroadcasts队列中相应位置
ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
if (stickies == null) {
stickies = new ArrayMap<>();
mStickyBroadcasts.put(userId, stickies);
}
ArrayList<Intent> list = stickies.get(intent.getAction());
if (list == null) {
list = new ArrayList<>();
stickies.put(intent.getAction(), list);
}
final int stickiesCount = list.size();
int i;
for (i = 0; i < stickiesCount; i++) {
if (intent.filterEquals(list.get(i))) {
// This sticky already exists, replace it.
list.set(i, new Intent(intent));
break;
}
}
if (i >= stickiesCount) {
list.add(new Intent(intent));
}
}
// 设置广播的目标用户数组users
int[] users;
if (userId == UserHandle.USER_ALL) {
// 所有启动用户
users = mUserController.getStartedUserArray();
} else {
// 特定用户
users = new int[] {userId};
}
// Figure out who all will receive this broadcast.
// 收集receivers列表组件信息. 参考【第3.3节】
List receivers = null;
if ((intent.getFlags() & Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
}
// 通过IntentResolver收集已注册的Receiver列表registeredReceivers
List<BroadcastFilter> registeredReceivers = null;
if (intent.getComponent() == null) {
if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
for (int i = 0; i < users.length; i++) {
// 过滤Shell限制的用户
...
List<BroadcastFilter> registeredReceiversForUser =
mReceiverResolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, users[i]);
if (registeredReceivers == null) {
registeredReceivers = registeredReceiversForUser;
} else if (registeredReceiversForUser != null) {
registeredReceivers.addAll(registeredReceiversForUser);
}
}
} else {
registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
}
}
final boolean replacePending = (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
// 整体逻辑: 将新发送的无序广播入队列
int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
if (!ordered && NR > 0) {
// If we are not serializing this broadcast, then send the
// registered receivers separately so they don't wait for the
// components to be launched.
if (isCallerSystem) {
checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, isProtectedBroadcast, registeredReceivers);
}
final BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
resultCode, resultData, resultExtras, ordered, sticky, false, userId,
allowBackgroundActivityStarts, timeoutExempt);
final boolean replaced = replacePending && (queue.replaceParallelBroadcastLocked(r) != null);
if (!replaced) {
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
registeredReceivers = null;
NR = 0;
}
// Merge into one list receivers.
// 1.receivers中移除如下action对应的广播: ACTION_PACKAGE_ADDED/ACTION_PACKAGE_RESTARTED/ACTION_PACKAGE_DATA_CLEARED/ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
// 2.将registeredReceivers列表合并到receivers列表
...
if (isCallerSystem) {
checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, isProtectedBroadcast, receivers);
}
// 将新发送的有序广播入队列
if ((receivers != null && receivers.size() > 0) || resultTo != null) {
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
resultData, resultExtras, ordered, sticky, false, userId,
allowBackgroundActivityStarts, timeoutExempt);
final BroadcastRecord oldRecord = replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
if (oldRecord != null) {
// Replaced, fire the result-to receiver.
if (oldRecord.resultTo != null) {
final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
oldRecord.intent, Activity.RESULT_CANCELED, null, null, false, false, oldRecord.userId);
}
} else {
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
} else {
// 该广播没有广播接收器, 说明是隐式广播, 记录一下即可
if (intent.getComponent() == null && intent.getPackage() == null
&& (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
}
}
return ActivityManager.BROADCAST_SUCCESS;
}
private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, int callingUid, int[] users) {
List<ResolveInfo> receivers = null;
try {
for (int user : users) {
// 过滤掉有Shell限制的用户
...
List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
.queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
// 如果目标不是系统用户, 过滤掉newReceivers列表中所有仅系统用户可见的广播
...
if (receivers == null) {
receivers = newReceivers;
} else if (newReceivers != null) {
// 遍历receivers和newReceivers列表, 将flags为ActivityInfo.FLAG_SINGLE_USER的广播添加到singleUserReceivers和receivers列表
...
}
}
} catch (RemoteException ex) {
// pm is in same process, this will never happen.
}
return receivers;
}
AMS.collectReceiverComponents过程:
1.该过程目的是收集BroadcastReceiver目标组件列表. 具体过程如下
2.遍历目标用户数组users,过滤掉有Shell限制的用户
3.执行PMS.queryIntentReceivers, 利用组件解析器ComponentResolver解析出BroadcastReceiver组件列表
4.过滤掉上述BroadcastReceiver组件列表中, 目标用户是非系统用户但是仅系统用户可见的广播
5.将上述组件列表中flags为ActivityInfo.FLAG_SINGLE_USER的广播添加到singleUserReceivers列表和receivers列表
[ -> frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java ]
调用链:queryIntentReceivers -> queryIntentReceiversInternal
@Override
public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
String resolvedType, int flags, int userId) {
return new ParceledListSlice<>(
queryIntentReceiversInternal(intent, resolvedType, flags, userId, false /*allowDynamicSplits*/));
}
queryIntentReceiversInternal实现:
private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
// 检查userId在用户管理服务中是否能找到
if (!sUserManager.exists(userId)) return Collections.emptyList();
final int callingUid = Binder.getCallingUid();
// 请求只能来自系统用户或具备INTERACT_ACROSS_USERS/INTERACT_ACROSS_USERS_FULL权限的用户, 否则抛异常
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
false /*requireFullPermission*/, false /*checkShell*/, "query intent receivers");
// 更新flags
flags = updateFlagsForResolve(flags, userId, intent, callingUid, false /*includeInstantApps*/);
// 获取Component
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
intent = intent.getSelector();
comp = intent.getComponent();
}
}
final String instantAppPkgName = getInstantAppPackageName(callingUid);
if (comp != null) {
final List<ResolveInfo> list = new ArrayList<>(1);
final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
if (ai != null) {
// 如下两种情况Activity不能使用. blockResolution为true
// 1) the calling package is normal and the activity is within an instant application or
// 2) the calling package is ephemeral and the activity is not visible to instant applications.
...
if (!blockResolution) {
ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
list.add(ri);
}
}
// 过滤掉list中的临时的BroadcastReceiver组件
return applyPostResolutionFilter(list, instantAppPkgName, allowDynamicSplits, callingUid, false, userId, intent);
}
synchronized (mPackages) {
String pkgName = intent.getPackage();
if (pkgName == null) {
// 通过组件解析器ComponentResolver解析出符合条件的组件信息列表
final List<ResolveInfo> result = mComponentResolver.queryReceivers(intent, resolvedType, flags, userId);
// 过滤掉临时的Activity
return applyPostResolutionFilter(result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId, intent);
}
// 获取包解析信息
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
// 通过组件解析器ComponentResolver解析出符合条件的组件信息列表
final List<ResolveInfo> result = mComponentResolver.queryReceivers(intent, resolvedType, flags, pkg.receivers, userId);
// 过滤掉临时的Activity
return applyPostResolutionFilter(result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId, intent);
}
return Collections.emptyList();
}
}
PMS.queryIntentReceivers过程:
1.首先是边界条件检查:检查userId是否存在, 检查请求只能来自系统用户或具备INTERACT_ACROSS_USERS/INTERACT_ACROSS_USERS_FULL权限的用户.
2.利用组件解析器ComponentResolver解析出和BroadcastReceiver对应的组件列表List< ActivityInfo>, 过滤掉其中的临时组件并返回
(1)如果Intent.getComponent非空, 则根据Component解析
(2)否则根据MIME Type/scheme/action等信息解析(执行ComponentResolver.queryReceivers)
注意:
ComponentResolver
:组件解析器. Resolves all Android component types [activities, services, providers and receivers].
PackageParser
:包解析器
[ -> frameworks/base/services/core/java/com/android/server/pm/ComponentResolver.java ]
List<ResolveInfo> queryReceivers(Intent intent, String resolvedType, int flags, int userId) {
synchronized (mLock) {
return mReceivers.queryIntent(intent, resolvedType, flags, userId);
}
}
[ -> frameworks/base/services/core/java/com/android/server/pm/ComponentResolver.java ]
private static final class ActivityIntentResolver extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
@Override
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId) {
if (!sUserManager.exists(userId)) return null;
mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
return super.queryIntent(intent, resolvedType, defaultOnly, userId);
}
List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) {
return null;
}
mFlags = flags;
return super.queryIntent(intent, resolvedType, (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
}
public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId) {
String scheme = intent.getScheme();
ArrayList<R> finalList = new ArrayList<R>();
F[] firstTypeCut = null;
F[] secondTypeCut = null;
F[] thirdTypeCut = null;
F[] schemeCut = null;
// 找出和MIME Type匹配的所有filter
if (resolvedType != null) {
int slashpos = resolvedType.indexOf('/');
if (slashpos > 0) {
final String baseType = resolvedType.substring(0, slashpos);
if (!baseType.equals("*")) {
if (resolvedType.length() != slashpos+2 || resolvedType.charAt(slashpos+1) != '*') {
firstTypeCut = mTypeToFilter.get(resolvedType);
secondTypeCut = mWildTypeToFilter.get(baseType);
} else {
firstTypeCut = mBaseTypeToFilter.get(baseType);
secondTypeCut = mWildTypeToFilter.get(baseType);
}
thirdTypeCut = mWildTypeToFilter.get("*");
} else if (intent.getAction() != null) {
firstTypeCut = mTypedActionToFilter.get(intent.getAction());
}
}
}
// 找出和scheme匹配的所有filter
if (scheme != null) {
schemeCut = mSchemeToFilter.get(scheme);
}
// 找出和action匹配的所有filter
if (resolvedType == null && scheme == null && intent.getAction() != null) {
firstTypeCut = mActionToFilter.get(intent.getAction());
}
// 过滤掉以上各filter组中不符合条件的元素, 将其封装为ResolveInfo对象添加到finalList
FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
if (firstTypeCut != null) {
buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
scheme, firstTypeCut, finalList, userId);
}
if (secondTypeCut != null) {
buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
scheme, secondTypeCut, finalList, userId);
}
if (thirdTypeCut != null) {
buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
scheme, thirdTypeCut, finalList, userId);
}
if (schemeCut != null) {
buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
scheme, schemeCut, finalList, userId);
}
filterResults(finalList);
// 按优先级降序排列
sortResults(finalList);
return finalList;
}
}
ComponentResolver.queryReceivers -> ActivityIntentResolver.queryIntent过程:
1.找出符合条件的IntentFilter数组:
(1)找出MIME Type匹配的IntentFilter数组
(2)找出scheme匹配的IntentFilter数组
(3)找出action匹配的IntentFilter数组
2.以Intent和上述IntentFilter数组作为入参,调用ComponentResolver.buildResolveList获取符合条件的BroadcastReceiver组件信息列表List< ActivityResolveInfo>
3.将List< ActivityResolveInfo>按优先级降序排序并返回
调用链:queryIntentForPackage -> queryIntentFromList
List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
int flags, List<PackageParser.Activity> packageActivities, int userId) {
if (!sUserManager.exists(userId)) {
return null;
}
if (packageActivities == null) {
return null;
}
mFlags = flags;
final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
final int activitiesSize = packageActivities.size();
ArrayList<PackageParser.ActivityIntentInfo[]> listCut = new ArrayList<>(activitiesSize);
ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
for (int i = 0; i < activitiesSize; ++i) {
intentFilters = packageActivities.get(i).intents;
if (intentFilters != null && intentFilters.size() > 0) {
PackageParser.ActivityIntentInfo[] array = new PackageParser.ActivityIntentInfo[intentFilters.size()];
intentFilters.toArray(array);
listCut.add(array);
}
}
return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
}
queryIntentFromList实现:
public List<R> queryIntentFromList(Intent intent, String resolvedType, boolean defaultOnly,
ArrayList<F[]> listCut, int userId) {
ArrayList<R> resultList = new ArrayList<R>();
final boolean debug = localLOGV || ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
final String scheme = intent.getScheme();
int N = listCut.size();
for (int i = 0; i < N; ++i) {
buildResolveList(intent, categories, debug, defaultOnly, resolvedType, scheme, listCut.get(i), resultList, userId);
}
filterResults(resultList);
sortResults(resultList);
return resultList;
}
private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories,
boolean debug, boolean defaultOnly, String resolvedType, String scheme,
F[] src, List<R> dest, int userId) {
final String action = intent.getAction();
final Uri data = intent.getData();
final String packageName = intent.getPackage();
final boolean excludingStopped = intent.isExcludingStopped();
final int N = src != null ? src.length : 0;
boolean hasNonDefaults = false;
F filter;
for (int i=0; i<N && (filter=src[i]) != null; i++) {
int match;
// 过滤掉target为stopped状态的filter
if (excludingStopped && isFilterStopped(filter, userId)) {
continue;
}
// 过滤掉packageName不匹配的filter
if (packageName != null && !isPackageForFilter(packageName, filter)) {
continue;
}
// 过滤掉重复filter
if (!allowFilterResult(filter, dest)) {
continue;
}
// filter各属性匹配
match = filter.match(action, resolvedType, scheme, data, categories, TAG);
if (match >= 0) {
if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) {
// 匹配成功, 将filter信息封装成ResolveInfo并添加到dest列表
final R oneResult = newResult(filter, match, userId);
if (oneResult != null) {
dest.add(oneResult);
}
} else {
hasNonDefaults = true;
}
}
}
}
@Override
protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, int match, int userId) {
// 各种边界条件检查包括: userId是否存在, Component和flag是否可用和匹配, PackageSetting是否为空, instant app和ephemeral app相关检查
...
// 创建ResolveInfo对象并设置各属性
final ResolveInfo res = new ResolveInfo();
res.activityInfo = ai;
if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
res.filter = info;
}
res.handleAllWebDataURI = info.handleAllWebDataURI();
res.priority = info.getPriority();
res.preferredOrder = activity.owner.mPreferredOrder;
res.match = match;
res.isDefault = info.hasDefault;
res.labelRes = info.labelRes;
res.nonLocalizedLabel = info.nonLocalizedLabel;
if (sPackageManagerInternal.userNeedsBadging(userId)) {
res.noResourceId = true;
} else {
res.icon = info.icon;
}
res.iconResourceId = info.icon;
res.system = res.activityInfo.applicationInfo.isSystemApp();
res.isInstantAppAvailable = userState.instantApp;
return res;
}
ComponentResolver.buildResolveList过程:
1.该方法主要做的事情:根据IntentFilter[]条件, 利用组件解析器ComponentResolver查找符合条件的BroadcastReceiver组件信息列表. 入参为Intent和数组IntentFilter[], 出参为List< ActivityResolveInfo>.
2.遍历IntentFilter数组, 过滤掉如下IntentFilter: target为stopped状态、packageName不匹配或者重复的filter
3.IntentFilter和Intent进行匹配, 如匹配成功, 则进行边界条件检查后将IntentFilter信息封装成ResolveInfo对象, 添加到dest列表返回
4.IntentFilter边界条件检查包括: userId是否存在, Component和flag是否可用和匹配, PackageSetting是否为空, instant app和ephemeral app相关检查
[ -> frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java ]
BroadcastQueue broadcastQueueForIntent(Intent intent) {
if (isOnOffloadQueue(intent.getFlags())) {
return mOffloadBroadcastQueue;
}
final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
}
[ -> frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java ]
这小节参考文章 registerReceiver过程 第6节.
ContextImpl.sendBroadcast过程:
1.边界和限制条件检查:
(1)根据各种限制设置intent的flags: 比如Instant App不能使用FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS, 广播不会发送到杀死的进程, 系统还没启动不允许启动新进程
(2)检查接收广播的userId是否正在运行
(3)权限和限制检查: 如CHANGE_DEVICE_IDLE_TEMP_WHITELIST权限, START_ACTIVITIES_FROM_BACKGROUND权限, OP_RUN_ANY_IN_BACKGROUND操作权限
(4)非系统用户不允许发送ProtectedBroadcast, 系统用户指(ROOT_UID/SYSTEM_UID/PHONE_UID/BLUETOOTH_UID/NFC_UID/SE_UID/NETWORK_STACK_UID)
2.特殊action处理:
(1)若action目标为发送给未启动的或后台的进程, 则Intent添加flags为FLAG_RECEIVER_INCLUDE_BACKGROUND
(2)若action为包管理器发出的和包移除相关的action, 则做相应逻辑处理. 如ACTION_UID_REMOVED/ACTION_PACKAGE_REMOVED/ACTION_PACKAGE_CHANGED/…
3.Sticky广播处理(仅针对sendStickyBroadcast):
(1)权限和条件检查包括: Manifest.permission.BROADCAST_STICKY权限检查, requiredPermissions和Component为空检查, mStickyBroadcasts重复广播检查
(2)将发送的广播Intent替换或插入到mStickyBroadcasts队列中相应位置
4.设置广播的目标用户数组users, 如果userId为USER_ALL则users为所有启动用户, 否则users为userId
5.执行AMS.collectReceiverComponents, 利用组件解析器ComponentResolver收集符合条件的BroadcastReceiver组件列表信息
6.若Intent.getComponent为空, 则执行ActivityIntentResolver.queryIntent, 解析出所有已注册的BroadcastReceiver组件列表
7.无序广播处理:将步骤6的广播入队到无序广播队列, 并执行广播接收器处理逻辑BroadcastQueue.scheduleBroadcastsLocked
8.有序广播处理(仅针对sendOrderedBroadcast):
(1)集合步骤5和6的BroadcastReceiver列表, 移除Package操作相关的广播ACTION_PACKAGE_ADDED/ACTION_PACKAGE_RESTARTED/ACTION_PACKAGE_DATA_CLEARED/ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
(2)若BroadcastReceiver列表非空. 如果原来广播队列就有相同Intent的广播且Intent.flags为FLAG_RECEIVER_REPLACE_PENDING, 则先把老的广播替换掉,并调用BroadcastQueue.performReceiveLocked对老广播执行广播接收操作;
否则将广播插入有序广播队列, 并调用BroadQueue.scheduleBroadcastsLocked处理下一个广播接收操作
广播发送过程总结:
1.先将广播添加到无序广播列表
2.找出该广播对应的所有接收器, 并执行广播接收器操作
基于Android 10.0的源码剖析, 站在Luoshengyang/Innost/Gityuan肩膀上.
本文分析广播接收器BroadcastReceiver注册过程.
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
frameworks/base/services/core/java/com/android/server/am/BroadcastRecord.java
frameworks/base/core/java/android/content/BroadcastReceiver.java
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/core/java/android/app/LoadedApk.java
frameworks/base/core/java/android/app/ActivityThread.java
TODO
[ -> frameworks/base/core/java/android/app/ContextImpl.java ]
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return registerReceiver(receiver, filter, null, null);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
return registerReceiverInternal(receiver, getUserId(), filter, broadcastPermission, scheduler, getOuterContext(), 0);
}
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context, int flags) {
// 获取InnerReceiver, 基本思路是从mReceivers映射表中查找和BroadcastReceiver一一对应的ReceiverDispatcher, 进而获取InnerReceiver. 如果没有则新建. 参考【第3节】
IIntentReceiver rd = null;
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
try {
// AMS.registerReceiver注册广播. 参考【第4节】
final Intent intent = ActivityManager.getService().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
broadcastPermission, userId, flags);
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
intent.prepareToEnterProcess();
}
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
ContextImpl.registerReceiver(BroadcastReceiver, IntentFilter)过程:
1.根据BroadcastReceiver获取对应的ReceiverDispatcher
(1)先根据LoadedApk.getReceiverDispatcher, 从ArrayMap<BroadcastReceiver, ReceiverDispatcher>映射表中得到和BroadcastReceiver对应的ReceiverDispatcher
(2)如果LoadedApk为空, 则新建LoadedApk.ReceiverDispatcher
2.执行ReceiverDispatcher.getIIntentReceiver()得到InnerReceiver(即IIntentReceiver.Stub)
3.调用AMS.registerReceiver注册广播.
[ -> frameworks/base/core/java/android/app/LoadedApk.java ]
public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
Context context, Handler handler,
Instrumentation instrumentation, boolean registered) {
synchronized (mReceivers) {
LoadedApk.ReceiverDispatcher rd = null;
ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
if (registered) {
map = mReceivers.get(context);
if (map != null) {
rd = map.get(r);
}
}
if (rd == null) {
rd = new ReceiverDispatcher(r, context, handler, instrumentation, registered);
if (registered) {
if (map == null) {
map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
mReceivers.put(context, map);
}
map.put(r, rd);
}
}
rd.mForgotten = false;
return rd.getIIntentReceiver();
}
}
ReceiverDispatcher作用:
(1) 首先BroadcastReceiver和ReceiverDispatcher是一一对应的, 一个广播接收器对应一个广播派发器.
(2) 它是负责将广播Broadcast派发给BroadcastReceiver执行的广播派发器.
(3) 它主要是通过内部类InnerReceiver和Args执行广播派发过程.
[ -> frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java ]
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission, int userId, int flags) {
// 不能从isolated进程调用, 否则会抛出异常
enforceNotIsolatedCaller("registerReceiver");
ProcessRecord callerApp = null;
final boolean visibleToInstantApps = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
int callingUid;
int callingPid;
boolean instantApp;
synchronized(this) {
if (caller != null) {
callerApp = getRecordForAppLocked(caller);
callingUid = callerApp.info.uid;
callingPid = callerApp.pid;
} else {
callerPackage = null;
callingUid = Binder.getCallingUid();
callingPid = Binder.getCallingPid();
}
instantApp = isInstantApp(callerApp, callerPackage, callingUid);
userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
// 先根据IntentFilter获取actions列表, 再从mStickyBroadcasts中找到包含action的所有Intent, 统一集中到stickyIntents
Iterator<String> actions = filter.actionsIterator();
if (actions == null) {
ArrayList<String> noAction = new ArrayList<String>(1);
noAction.add(null);
actions = noAction.iterator();
}
ArrayList<Intent> stickyIntents = null;
int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
while (actions.hasNext()) {
String action = actions.next();
for (int id : userIds) {
ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
if (stickies != null) {
ArrayList<Intent> intents = stickies.get(action);
if (intents != null) {
if (stickyIntents == null) {
stickyIntents = new ArrayList<Intent>();
}
stickyIntents.addAll(intents);
}
}
}
}
}
// 遍历stickyIntents, 根据IntentFilter匹配action&category&schema&data各属性都匹配的intent, 统一集中到allSticky
ArrayList<Intent> allSticky = null;
if (stickyIntents != null) {
final ContentResolver resolver = mContext.getContentResolver();
for (int i = 0, N = stickyIntents.size(); i < N; i++) {
Intent intent = stickyIntents.get(i);
// instantApp过滤
if (instantApp && (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
continue;
}
if (filter.match(resolver, intent, true, TAG) >= 0) {
if (allSticky == null) {
allSticky = new ArrayList<Intent>();
}
allSticky.add(intent);
}
}
}
// The first sticky in the list is returned directly back to the client.
Intent sticky = allSticky != null ? allSticky.get(0) : null;
synchronized (this) {
// mRegisteredReceivers中添加ReceiverList, mReceiverResolver中添加BroadcastFilter
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
rl = new ReceiverList(this, callerApp, callingPid, callingUid, userId, receiver);
if (rl.app != null) {
// 如果超出单个App允许注册的最大广播数1000,则抛出异常
final int totalReceiversForApp = rl.app.receivers.size();
if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) {
...
}
rl.app.receivers.add(rl);
} else {
// 进程为空, 释放广播
receiver.asBinder().linkToDeath(rl, 0);
rl.linkedToDeath = true;
}
mRegisteredReceivers.put(receiver.asBinder(), rl);
}
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId, instantApp, visibleToInstantApps);
if (!rl.containsFilter(filter)) {
rl.add(bf);
mReceiverResolver.addFilter(bf);
}
// 遍历allSticky列表, 根据intent封装BroadcastRecord广播记录, 并入队BroadcastQueue
if (allSticky != null) {
ArrayList receivers = new ArrayList();
receivers.add(bf);
final int stickyCount = allSticky.size();
for (int i = 0; i < stickyCount; i++) {
Intent intent = allSticky.get(i);
// 根据intent的flags标记获取前台/后台/离线广播队列BroadcastQueue. 参考【第5节】
BroadcastQueue queue = broadcastQueueForIntent(intent);
// 创建BroadcastRecord
BroadcastRecord r = new BroadcastRecord(queue, intent, null,
null, -1, -1, false, null, null, OP_NONE, null, receivers,
null, 0, null, null, false, true, true, -1, false,
false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */);
// 添加到无序广播列表mParallelBroadcasts. 参考【第6节】
queue.enqueueParallelBroadcastLocked(r);
// 处理广播
queue.scheduleBroadcastsLocked();
}
}
return sticky;
}
}
BroadcastQueue broadcastQueueForIntent(Intent intent) {
if (isOnOffloadQueue(intent.getFlags())) {
return mOffloadBroadcastQueue;
}
final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
}
[ -> frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java ]
public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
mParallelBroadcasts.add(r);
}
public void scheduleBroadcastsLocked() {
if (mBroadcastsScheduled) {
return;
}
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
private final class BroadcastHandler extends Handler {
public BroadcastHandler(Looper looper) {
super(looper, null, true);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BROADCAST_INTENT_MSG: {
processNextBroadcast(true);
} break;
case BROADCAST_TIMEOUT_MSG: {
synchronized (mService) {
broadcastTimeoutLocked(true);
}
} break;
}
}
}
final void processNextBroadcast(boolean fromMsg) {
synchronized (mService) {
processNextBroadcastLocked(fromMsg, false);
}
}
final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
mService.updateCpuStats();
if (fromMsg) {
mBroadcastsScheduled = false;
}
// First, deliver any non-serialized broadcasts right away.
// 遍历无序广播列表mParallelBroadcasts, 获取每个广播对象BroadcastRecord的所有接收者BroadcastFilter,并发送给BroadcastFilter
// 同时将广播添加到历史广播列表
BroadcastRecord r;
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);
r.dispatchTime = SystemClock.uptimeMillis();
r.dispatchClockTime = System.currentTimeMillis();
final int N = r.receivers.size();
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
// 将当前广播发送给广播接收器处理. 参考【第7.1节】
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
}
addBroadcastToHistoryLocked(r);
}
// 检查当前是否有进程正在处理广播mPendingBroadcast.如有则不往下继续执行, 先等广播处理完; 若无则继续往下执行, 处理下一个广播
if (mPendingBroadcast != null) {
boolean isDead;
if (mPendingBroadcast.curApp.pid > 0) {
synchronized (mService.mPidsSelfLocked) {
ProcessRecord proc = mService.mPidsSelfLocked.get(mPendingBroadcast.curApp.pid);
isDead = proc == null || proc.isCrashing();
}
} else {
final ProcessRecord proc = mService.mProcessList.mProcessNames.get(
mPendingBroadcast.curApp.processName, mPendingBroadcast.curApp.uid);
isDead = proc == null || !proc.pendingStart;
}
if (!isDead) {
// It's still alive, so keep waiting
return;
} else {
mPendingBroadcast.state = BroadcastRecord.IDLE;
mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
mPendingBroadcast = null;
}
}
boolean looped = false;
// 其他广播处理, 按先后顺序依次是:
// 1. mAlarmBroadcasts
// 2. the next "overdue" deferral
// 3. the next ordinary ordered broadcast
// 4. the next not-yet-overdue deferral
do {
final long now = SystemClock.uptimeMillis();
// 获取下一个广播
r = mDispatcher.getNextBroadcastLocked(now);
// 如果广播都处理完了, 则做一些扫尾工作包括: 延迟广播检查和执行, GC, oomAdj更新等. 不再往下执行
if (r == null) {
mDispatcher.scheduleDeferralCheckLocked(false);
mService.scheduleAppGcsLocked();
if (looped) {
mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_START_RECEIVER);
}
if (mService.mUserController.mBootCompleted && mLogLatencyMetrics) {
mLogLatencyMetrics = false;
}
return;
}
boolean forceReceive = false;
// 处理并执行超时广播
int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
if (mService.mProcessesReady && !r.timeoutExempt && r.dispatchTime > 0) {
if ((numReceivers > 0) && (now > r.dispatchTime + (2 * mConstants.TIMEOUT * numReceivers))) {
broadcastTimeoutLocked(false); // forcibly finish this broadcast
forceReceive = true;
r.state = BroadcastRecord.IDLE;
}
}
if (r.state != BroadcastRecord.IDLE) {
return;
}
// Is the current broadcast is done for any reason?
// 当前广播处理完了, 则处理cross-BroadcastRecord refcount相关,并执行广播接收
if (r.receivers == null || r.nextReceiver >= numReceivers || r.resultAbort || forceReceive) {
if (r.resultTo != null) {
boolean sendResult = true;
if (r.splitToken != 0) {
int newCount = mSplitRefcounts.get(r.splitToken) - 1;
if (newCount == 0) {
mSplitRefcounts.delete(r.splitToken);
} else {
sendResult = false;
mSplitRefcounts.put(r.splitToken, newCount);
}
}
if (sendResult) {
performReceiveLocked(r.callerApp, r.resultTo, new Intent(r.intent), r.resultCode,
r.resultData, r.resultExtras, false, false, r.userId);
r.resultTo = null;
}
}
// 取消超时广播
cancelBroadcastTimeoutLocked();
// 将当前广播添加到历史广播列表
addBroadcastToHistoryLocked(r);
// 记录隐式广播
if (r.intent.getComponent() == null && r.intent.getPackage() == null
&& (r.intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
r.manifestCount, r.manifestSkipCount, r.finishTime-r.dispatchTime);
}
// 当前广播处理完, mCurrentBroadcast置空
mDispatcher.retireBroadcastLocked(r);
r = null;
looped = true;
continue;
}
// 如果下一个广播是延迟广播, 则针对mSplitRefcounts做相关处理, 同时将延迟广播添加到延迟广播列表
if (!r.deferred) {
final int receiverUid = r.getReceiverUid(r.receivers.get(r.nextReceiver));
if (mDispatcher.isDeferringLocked(receiverUid)) {
BroadcastRecord defer;
if (r.nextReceiver + 1 == numReceivers) {
defer = r;
mDispatcher.retireBroadcastLocked(r);
} else {
defer = r.splitRecipientsLocked(receiverUid, r.nextReceiver);
if (r.resultTo != null) {
int token = r.splitToken;
if (token == 0) {
r.splitToken = defer.splitToken = nextSplitTokenLocked();
mSplitRefcounts.put(r.splitToken, 2);
} else {
final int curCount = mSplitRefcounts.get(token);
mSplitRefcounts.put(token, curCount + 1);
}
}
}
mDispatcher.addDeferredBroadcast(receiverUid, defer);
r = null;
looped = true;
continue;
}
}
} while (r == null);
// 处理下一个广播, 并通过Handler延迟发送广播超时消息, 便于杀死超时广播
int recIdx = r.nextReceiver++;
r.receiverTime = SystemClock.uptimeMillis();
if (recIdx == 0) {
r.dispatchTime = r.receiverTime;
r.dispatchClockTime = System.currentTimeMillis();
}
if (!mPendingBroadcastTimeoutMessage) {
long timeoutTime = r.receiverTime + mConstants.TIMEOUT;
setBroadcastTimeoutLocked(timeoutTime);
}
final BroadcastOptions brOptions = r.options;
final Object nextReceiver = r.receivers.get(recIdx);
if (nextReceiver instanceof BroadcastFilter) {
BroadcastFilter filter = (BroadcastFilter)nextReceiver;
// 将当前广播发送给广播接收器处理. 参考【第7.1节】
deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
// 当前广播处理完后, 继续处理下一个广播
if (r.receiver == null || !r.ordered) {
r.state = BroadcastRecord.IDLE;
scheduleBroadcastsLocked();
} else {
if (filter.receiverList != null) {
maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
}
if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
scheduleTempWhitelistLocked(filter.owningUid, brOptions.getTemporaryAppWhitelistDuration(), r);
}
}
return;
}
// 各种检查包括:targetSdkVersion, Appop操作权限, 防火墙, 权限review, 用户运行状态, 后台执行检查等. 如果不符合条件将skip
boolean skip = false;
...
if (skip) {
// skip当前广播, 执行下一个广播
r.delivery[recIdx] = BroadcastRecord.DELIVERY_SKIPPED;
r.receiver = null;
r.curFilter = null;
r.state = BroadcastRecord.IDLE;
r.manifestSkipCount++;
scheduleBroadcastsLocked();
return;
}
// 设置当前广播的Receiver为已接收状态DELIVERY_DELIVERED
ResolveInfo info = (ResolveInfo)nextReceiver;
ComponentName component = new ComponentName(info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
r.manifestCount++;
r.delivery[recIdx] = BroadcastRecord.DELIVERY_DELIVERED;
r.state = BroadcastRecord.APP_RECEIVE;
r.curComponent = component;
r.curReceiver = info.activityInfo;
if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
scheduleTempWhitelistLocked(receiverUid, brOptions.getTemporaryAppWhitelistDuration(), r);
}
// Broadcast is being executed, its package can't be stopped.
AppGlobals.getPackageManager().setPackageStoppedState(r.curComponent.getPackageName(), false, r.userId);
// 若当前进程活着, 则处理当前广播
if (app != null && app.thread != null && !app.killed) {
app.addPackage(info.activityInfo.packageName, info.activityInfo.applicationInfo.longVersionCode, mService.mProcessStats);
maybeAddAllowBackgroundActivityStartsToken(app, r);
processCurBroadcastLocked(r, app, skipOomAdj);
return;
}
// 若当前进程未启动, 则先启动进程, 若进程启动失败, 则finishReceiver并准备执行下一个广播
if ((r.curApp=mService.startProcessLocked(targetProcess,
info.activityInfo.applicationInfo, true,
r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
new HostingRecord("broadcast", r.curComponent),
(r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
== null) {
finishReceiverLocked(r, r.resultCode, r.resultData, r.resultExtras, r.resultAbort, false);
scheduleBroadcastsLocked();
r.state = BroadcastRecord.IDLE;
return;
}
maybeAddAllowBackgroundActivityStartsToken(r.curApp, r);
mPendingBroadcast = r;
mPendingBroadcastRecvIndex = recIdx;
}
processNextBroadcast过程:
1.无序广播处理:
(1)遍历无序广播列表mParallelBroadcasts
(2)获取每个广播对象BroadcastRecord的全部广播接收者列表BroadcastFilter
(3)调用BroadcastQueue.deliverToRegisteredReceiverLocked, 依次将当前广播发送给步骤1的广播接收者处理
(4)将已处理的广播加入历史广播列表
2.检查当前是否有进程正在处理广播mPendingBroadcast. 如有则不往下继续执行, 先等广播处理完; 若无则继续往下执行, 处理下一个广播
3.获取有序或延时广播处理:执行do while循环, 直到查找到下一个广播r:
(1)获取下一个广播r
(2)若当前广播为空, 则做一些扫尾工作包括: 延迟广播检查和执行, GC, oomAdj更新等并return
(3)若当前广播非空, 则判断广播处理是否超时, 若超时则调用broadcastTimeoutLocked超时处理并弹出ANR提示(超时时间是10秒), finish当前广播并设置广播状态为IDLE
(4)若当前广播的所有广播接收器列表已完成处理:
(4.1)更新cross-BroadcastRecord refcount计数,并调用performReceiveLocked执行BroadcastReceiver.onReceive广播接收操作和执行广播finish操作
(4.2)取消超时广播
(4.3)将当前广播添加到历史广播列表
(4.4)若当前广播为隐式广播, 则记录隐式广播
(4.5)当前广播处理完, mCurrentBroadcast置空, continue并执行下一轮do while循环
(5)如果下一个广播是延迟广播, 则针对mSplitRefcounts做相关处理, 同时将延迟广播添加到延迟广播列表
4.将步骤3的有序或延时广播r发送给当前索引nextReceiver的广播接收器处理(filter非空):
(1)获取广播r的当前广播接收器BroadcastFilter的索引nextReceiver. 并通过Handler超时机制发送消息, 便于杀死超时广播
(2)获取索引nextReceiver的广播接收器BroadcastFilter:
(2.1)调用deliverToRegisteredReceiverLocked将当前广播发送给广播接收器BroadcastFilter执行
(2.2)若当前广播处理完, 设置广播状态为IDLE, 并调用scheduleBroadcastsLocked继续处理下一个广播并return
5.若filter为空, 根据nextReceiver得到ResolveInfo且非空:
(1)先执行各种检查包括:targetSdkVersion, Appop操作权限, 防火墙, 权限review, 用户运行状态, 后台执行检查等.
(2)如果上述条件不符合, 则设置广播接收器状态为DELIVERY_SKIPPED, 设置广播状态为IDLE, 调用scheduleBroadcastsLocked处理下一个广播并return
(3)根据ResolveInfo构造ComponentName对象设置给当前广播, 设置广播接收器状态为DELIVERY_DELIVERED, 设置广播状态为APP_RECEIVE
(4)若当前进程活着, 则处理当前广播
(5)若当前进程未启动, 则先启动进程, 若进程启动失败, 则finishReceiverLocked结束当前广播接收操作, 设置广播状态为IDLE, 并调用scheduleBroadcastsLocked执行下一个广播接收操作
[ -> frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java ]
private void deliverToRegisteredReceiverLocked(BroadcastRecord r, BroadcastFilter filter, boolean ordered, int index) {
// 各种检查:权限, 防火墙, 权限review. 如果不符合条件将skip
boolean skip = false;
...
if (skip) {
r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED;
return;
}
// 设置当前广播的Receiver为已接收状态DELIVERY_DELIVERED
r.delivery[index] = BroadcastRecord.DELIVERY_DELIVERED;
// 如果是有序广播, 则更新广播状态为CALL_IN_RECEIVE, 同时将当前广播添加到curReceivers列表和更新oomAdj
if (ordered) {
r.receiver = filter.receiverList.receiver.asBinder();
r.curFilter = filter;
filter.receiverList.curBroadcast = r;
r.state = BroadcastRecord.CALL_IN_RECEIVE;
if (filter.receiverList.app != null) {
r.curApp = filter.receiverList.app;
filter.receiverList.app.curReceivers.add(r);
mService.updateOomAdjLocked(r.curApp, true, OomAdjuster.OOM_ADJ_REASON_START_RECEIVER);
}
}
if (filter.receiverList.app != null && filter.receiverList.app.inFullBackup) {
// 对于有序广播, 如果是inFullBackup状态, 则跳过当前Receiver
if (ordered) {
skipReceiverLocked(r);
}
} else {
// 设置广播接收时间
r.receiverTime = SystemClock.uptimeMillis();
maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
// 广播接收器执行广播接收操作. 执行【第7.2节】
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
// 无序广播是fire-and-forget处理方式, 不需要调用finishReceiverLocked(), 通过activity-start token方式管理无序广播
if (r.allowBackgroundActivityStarts && !r.ordered) {
postActivityStartTokenRemoval(filter.receiverList.app, r);
}
}
// 有序广播设置状态CALL_DONE_RECEIVE
if (ordered) {
r.state = BroadcastRecord.CALL_DONE_RECEIVE;
}
}
BroadcastQueue.deliverToRegisteredReceiverLocked过程:
入参为(BroadcastRecord r, BroadcastFilter filter, boolean ordered, int index), 其中r代表当前广播, filter代表广播接收器
1.首先进行条件检查:权限, 防火墙, 权限review. 如果不符合条件将直接return并设置当前广播的接收器BroadcastReceiver状态为DELIVERY_SKIPPED
2.如果符合条件, 设置当前广播的接收器BroadcastReceiver状态为DELIVERY_DELIVERED
3.如果是有序广播, 更新当前广播状态为CALL_IN_RECEIVE(表示处理中), 同时将当前广播添加到curReceivers列表并更新oomAdj
4.执行广播接收:
(1)如果当前广播接收器的进程在inFullBackup状态, 且当前为有序广播, 则调用skipReceiverLocked跳过当前广播并处理下一个广播
(2)如果进程为非inFullBackup状态, 则调用performReceiveLocked执行广播接收操作.
(3)如果当前为无序广播,由于无序广播是fire-and-forget处理方式, 因此通过activity-start token方式管理无序广播
5.如果是有序广播, 更新当前广播状态为CALL_DONE_RECEIVE(表示处理完毕)
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser)
throws RemoteException {
// Send the intent to the receiver asynchronously using one-way binder calls.
if (app != null) {
if (app.thread != null) {
// If we have an app thread, do the call through that so it is
// correctly ordered with other one-way calls.
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.getReportedProcState());
}
} else {
// 参考【第8节】
receiver.performReceive(intent, resultCode, data, extras, ordered, sticky, sendingUser);
}
}
BroadcastQueue.performReceiveLocked过程:
1.基本等价于执行ReceiverDispatcher.InnerReceiver.performReceive()方法.
[ -> frameworks/base/core/java/android/app/LoadedApk.java ]
static final class ReceiverDispatcher {
final static class InnerReceiver extends IIntentReceiver.Stub {
final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
final LoadedApk.ReceiverDispatcher mStrongRef;
InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
mStrongRef = strong ? rd : null;
}
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final LoadedApk.ReceiverDispatcher rd;
if (intent == null) {
rd = null;
} else {
rd = mDispatcher.get();
}
if (rd != null) {
rd.performReceive(intent, resultCode, data, extras, ordered, sticky, sendingUser);
} else {
// 结束当前广播
IActivityManager mgr = ActivityManager.getService();
if (extras != null) {
extras.setAllowFds(false);
}
mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
}
}
}
}
ReceiverDispatcher.InnerReceiver.performReceive()过程:
1.若LoadedApk.ReceiverDispatcher对象非空, 则执行LoadedApk.ReceiverDispatcher.performReceive()方法处理广播
2.若LoadedApk.ReceiverDispatcher对象为空, 则调用AMS.finishReceiver结束当前广播
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final Args args = new Args(intent, resultCode, data, extras, ordered, sticky, sendingUser);
if (intent == null || !mActivityThread.post(args.getRunnable())) {
if (mRegistered && ordered) {
IActivityManager mgr = ActivityManager.getService();
args.sendFinished(mgr);
}
}
} **LoadedApk.ReceiverDispatcher.performReceive()过程:** 1.封装Runnable对象Args, 执行Runnable, 若执行失败则调用AMS.finishReceiver 2.Runnable执行过程: (1)若当前为有序广播且BroadcastReceiver或Intent为空, 则调用AMS.finishReceiver结束当前广播和广播接收器并return (2)调用BroadcastReceiver.onReceive接收广播 (3)调用AMS.finishReceiver结束当前广播并继续处理下一个广播接收器操作
[ -> frameworks/base/core/java/android/app/LoadedApk.java ]
public final Runnable getRunnable() {
return () -> {
final BroadcastReceiver receiver = mReceiver;
final boolean ordered = mOrdered;
final IActivityManager mgr = ActivityManager.getService();
final Intent intent = mCurIntent;
mCurIntent = null;
mDispatched = true;
mRunCalled = true;
// 若当前receiver或intent为空, 则直接返回.
// 对于已注册的有序广播, 需要先结束当前广播接收操作然后执行下一个广播接收操作. 参考【第9.2节】
if (receiver == null || intent == null || mForgotten) {
if (mRegistered && ordered) {
sendFinished(mgr);
}
return;
}
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess();
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
// 调用BroadcastReceiver.onReceive方法
receiver.onReceive(mContext, intent);
// finish当前广播
if (receiver.getPendingResult() != null) {
finish();
}
};
}
public final void finish() {
if (mType == TYPE_COMPONENT) {
final IActivityManager mgr = ActivityManager.getService();
if (QueuedWork.hasPendingWork()) {
QueuedWork.queue(new Runnable() {
@Override
public void run() {
sendFinished(mgr);
}
}, false);
} else {
sendFinished(mgr);
}
} else if (mOrderedHint && mType != TYPE_UNREGISTERED) {
final IActivityManager mgr = ActivityManager.getService();
sendFinished(mgr);
}
}
public void sendFinished(IActivityManager am) {
synchronized (this) {
mFinished = true;
if (mResultExtras != null) {
mResultExtras.setAllowFds(false);
}
if (mOrderedHint) {
am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras, mAbortBroadcast, mFlags);
} else {
am.finishReceiver(mToken, 0, null, null, false, mFlags);
}
}
}
public void finishReceiver(IBinder who, int resultCode, String resultData,
Bundle resultExtras, boolean resultAbort, int flags) {
final long origId = Binder.clearCallingIdentity();
try {
boolean doNext = false;
BroadcastRecord r;
BroadcastQueue queue;
synchronized(this) {
// 获取广播队列BroadcastQueue
if (isOnOffloadQueue(flags)) {
queue = mOffloadBroadcastQueue;
} else {
queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0 ? mFgBroadcastQueue : mBgBroadcastQueue;
}
// 从广播队列中查找广播接收器(令牌为who)对应的广播BroadcastRecord
r = queue.getMatchingOrderedReceiver(who);
if (r != null) {
// 结束本次广播接收操作
doNext = r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, true);
}
if (doNext) {
// 执行下一次广播接收操作
r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
}
// 更新oomAdj
trimApplicationsLocked(OomAdjuster.OOM_ADJ_REASON_FINISH_RECEIVER);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
[ -> frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java ]
[ -> frameworks/base/services/core/java/com/android/server/am/BroadcastDispatcher.java ]
public BroadcastRecord getNextBroadcastLocked(final long now) {
if (mCurrentBroadcast != null) {
return mCurrentBroadcast;
}
final boolean someQueued = !mOrderedBroadcasts.isEmpty();
BroadcastRecord next = null;
if (!mAlarmBroadcasts.isEmpty()) {
next = popLocked(mAlarmBroadcasts);
}
if (next == null && !mDeferredBroadcasts.isEmpty()) {
// We're going to deliver either:
// 1. the next "overdue" deferral; or
// 2. the next ordinary ordered broadcast; *or*
// 3. the next not-yet-overdue deferral.
for (int i = 0; i < mDeferredBroadcasts.size(); i++) {
Deferrals d = mDeferredBroadcasts.get(i);
if (now < d.deferUntil && someQueued) {
// stop looking when we haven't hit the next time-out boundary
// but only if we have un-deferred broadcasts waiting,
// otherwise we can deliver whatever deferred broadcast
// is next available.
break;
}
if (d.broadcasts.size() > 0) {
next = d.broadcasts.remove(0);
// apply deferral-interval decay policy and move this uid's
// deferred broadcasts down in the delivery queue accordingly
mDeferredBroadcasts.remove(i); // already 'd'
d.deferredBy = calculateDeferral(d.deferredBy);
d.deferUntil += d.deferredBy;
insertLocked(mDeferredBroadcasts, d);
break;
}
}
}
if (next == null && someQueued) {
next = mOrderedBroadcasts.remove(0);
}
mCurrentBroadcast = next;
return next;
}
getNextBroadcastLocked过程:
目的是获取下一个要处理的广播, 获取顺序一次是:
1.mAlarmBroadcasts(Alarm广播)
2.the next “overdue” deferral(延时广播)
3.the next ordinary ordered broadcast(有序广播)
final void broadcastTimeoutLocked(boolean fromMsg) {
if (fromMsg) {
mPendingBroadcastTimeoutMessage = false;
}
if (mDispatcher.isEmpty() || mDispatcher.getActiveBroadcastLocked() == null) {
return;
}
long now = SystemClock.uptimeMillis();
BroadcastRecord r = mDispatcher.getActiveBroadcastLocked();
if (fromMsg) {
// 忽略mProcessesReady前的广播超时
if (!mService.mProcessesReady) {
return;
}
// 不考虑广播超时时
if (r.timeoutExempt) {
return;
}
// 广播超时时间10秒
long timeoutTime = r.receiverTime + mConstants.TIMEOUT;
// 若当前未超时, 则取消超时处理
if (timeoutTime > now) {
setBroadcastTimeoutLocked(timeoutTime);
return;
}
}
// 若当前广播正在等待后台服务处理, 则设置广播状态为IDLE, 处理下一个广播
if (r.state == BroadcastRecord.WAITING_SERVICES) {
r.curComponent = null;
r.state = BroadcastRecord.IDLE;
processNextBroadcast(false);
return;
}
// 发送ANR信息(忽略debug场景的ANR)
final boolean debugging = (r.curApp != null && r.curApp.isDebugging());
r.receiverTime = now;
if (!debugging) {
r.anrCount++;
}
ProcessRecord app = null;
String anrMessage = null;
Object curReceiver;
if (r.nextReceiver > 0) {
curReceiver = r.receivers.get(r.nextReceiver-1);
r.delivery[r.nextReceiver-1] = BroadcastRecord.DELIVERY_TIMEOUT;
} else {
curReceiver = r.curReceiver;
}
if (curReceiver != null && curReceiver instanceof BroadcastFilter) {
BroadcastFilter bf = (BroadcastFilter)curReceiver;
if (bf.receiverList.pid != 0 && bf.receiverList.pid != ActivityManagerService.MY_PID) {
synchronized (mService.mPidsSelfLocked) {
app = mService.mPidsSelfLocked.get(bf.receiverList.pid);
}
}
} else {
app = r.curApp;
}
if (app != null) {
anrMessage = "Broadcast of " + r.intent.toString();
}
if (mPendingBroadcast == r) {
mPendingBroadcast = null;
}
// Move on to the next receiver.
finishReceiverLocked(r, r.resultCode, r.resultData, r.resultExtras, r.resultAbort, false);
scheduleBroadcastsLocked();
if (!debugging && anrMessage != null) {
// Post the ANR to the handler since we do not want to process ANRs while
// potentially holding our lock.
mHandler.post(new AppNotResponding(app, anrMessage));
}
}
BroadcastQueue.broadcastTimeoutLocked过程:
1.边界条件处理:排除进程还未Ready、timeExempt和等待后台服务处理等场景的超时
2.如果广播从r.receiverTime到现在的时间超过10秒, 则认为超时并弹出ANR弹窗
private final void processCurBroadcastLocked(BroadcastRecord r,
ProcessRecord app, boolean skipOomAdj) throws RemoteException {
if (app.inFullBackup) {
skipReceiverLocked(r);
return;
}
r.receiver = app.thread.asBinder();
r.curApp = app;
app.curReceivers.add(r);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
mService.mProcessList.updateLruProcessLocked(app, false, null);
if (!skipOomAdj) {
mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
}
// Tell the application to launch this receiver.
r.intent.setComponent(r.curComponent);
boolean started = false;
try {
mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
PackageManager.NOTIFY_PACKAGE_USE_BROADCAST_RECEIVER);
app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
mService.compatibilityInfoForPackage(r.curReceiver.applicationInfo),
r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
app.getReportedProcState());
started = true;
} finally {
if (!started) {
r.receiver = null;
r.curApp = null;
app.curReceivers.remove(r);
}
}
}
processCurBroadcastLocked调用链依次是:
ApplicationThread.scheduleReceiver -> H.RECEIVER -> handleReceiver -> BroadcastReceiver.onReceive
[ -> frameworks/base/core/java/android/app/ActivityThread.java ]
private class ApplicationThread extends IApplicationThread.Stub {
...
public final void scheduleReceiver(Intent intent, ActivityInfo info,
CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
boolean sync, int sendingUser, int processState) {
updateProcessState(processState, false);
ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
sync, false, mAppThread.asBinder(), sendingUser);
r.info = info;
r.compatInfo = compatInfo;
sendMessage(H.RECEIVER, r);
}
...
}
class H extends Handler {
...
public void handleMessage(Message msg) {
switch (msg.what) {
...
case RECEIVER:
handleReceiver((ReceiverData)msg.obj);
break;
...
}
}
}
private void handleReceiver(ReceiverData data) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
String component = data.intent.getComponent().getClassName();
LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
IActivityManager mgr = ActivityManager.getService();
Application app = packageInfo.makeApplication(false, mInstrumentation);
ContextImpl context = (ContextImpl) app.getBaseContext();
if (data.info.splitName != null) {
context = (ContextImpl) context.createContextForSplit(data.info.splitName);
}
java.lang.ClassLoader cl = context.getClassLoader();
data.intent.setExtrasClassLoader(cl);
data.intent.prepareToEnterProcess();
data.setExtrasClassLoader(cl);
BroadcastReceiver receiver = packageInfo.getAppFactory().instantiateReceiver(cl, data.info.name, data.intent);
try {
sCurrentBroadcastIntent.set(data.intent);
receiver.setPendingResult(data);
receiver.onReceive(context.getReceiverRestrictedContext(), data.intent);
} catch (Exception e) {
...
} finally {
sCurrentBroadcastIntent.set(null);
}
if (receiver.getPendingResult() != null) {
data.finish();
}
}
public boolean finishReceiverLocked(BroadcastRecord r, int resultCode,
String resultData, Bundle resultExtras, boolean resultAbort, boolean waitForServices) {
final int state = r.state;
final ActivityInfo receiver = r.curReceiver;
final long finishTime = SystemClock.uptimeMillis();
final long elapsed = finishTime - r.receiverTime;
r.state = BroadcastRecord.IDLE;
// 如果广播运行时间超过10秒, 则立即移除该广播, 否则延迟移除该广播
if (r.allowBackgroundActivityStarts && r.curApp != null) {
if (elapsed > mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT) {
r.curApp.removeAllowBackgroundActivityStartsToken(r);
} else {
postActivityStartTokenRemoval(r.curApp, r);
}
}
// 设置duration
if (r.nextReceiver > 0) {
r.duration[r.nextReceiver - 1] = elapsed;
}
// 如果广播运行时间超过SLOW_TIME(5秒),则使用延时策略
if (!r.timeoutExempt) {
if (mConstants.SLOW_TIME > 0 && elapsed > mConstants.SLOW_TIME) {
if (!UserHandle.isCore(r.curApp.uid)) {
if (r.curApp != null) {
mDispatcher.startDeferring(r.curApp.uid);
}
}
}
}
// 广播数据置空处理
r.receiver = null;
r.intent.setComponent(null);
if (r.curApp != null && r.curApp.curReceivers.contains(r)) {
r.curApp.curReceivers.remove(r);
}
if (r.curFilter != null) {
r.curFilter.receiverList.curBroadcast = null;
}
r.curFilter = null;
r.curReceiver = null;
r.curApp = null;
mPendingBroadcast = null;
r.resultCode = resultCode;
r.resultData = resultData;
r.resultExtras = resultExtras;
if (resultAbort && (r.intent.getFlags()&Intent.FLAG_RECEIVER_NO_ABORT) == 0) {
r.resultAbort = resultAbort;
} else {
r.resultAbort = false;
}
// 当前有后台服务且需要等后台服务处理完后才能finishReceiver的情况处理
if (waitForServices && r.curComponent != null && r.queue.mDelayBehindServices
&& r.queue.mDispatcher.getActiveBroadcastLocked() == r) {
ActivityInfo nextReceiver;
if (r.nextReceiver < r.receivers.size()) {
Object obj = r.receivers.get(r.nextReceiver);
nextReceiver = (obj instanceof ActivityInfo) ? (ActivityInfo)obj : null;
} else {
nextReceiver = null;
}
if (receiver == null || nextReceiver == null
|| receiver.applicationInfo.uid != nextReceiver.applicationInfo.uid
|| !receiver.processName.equals(nextReceiver.processName)) {
if (mService.mServices.hasBackgroundServicesLocked(r.userId)) {
r.state = BroadcastRecord.WAITING_SERVICES;
return false;
}
}
}
r.curComponent = null;
// 返回值表示是否执行下一个广播接收操作, 只有当前广播完成接收操作时才会开始下一次
// 即当前广播状态码为APP_RECEIVE或CALL_DONE_RECEIVE
return state == BroadcastRecord.APP_RECEIVE || state == BroadcastRecord.CALL_DONE_RECEIVE;
}
BroadcastQueue.finishReceiverLocked过程:
入参为BroadcastRecord, 出参为bool值表示是否执行下一个广播接收操作
1.如果当前广播BroadcastRecord运行时间超过10秒, 则移除当前广播; 否则发送消息延迟移除该广播
2.设置当前广播的duration
3.如果当前广播运行时间超过SLOW_TIME(5秒), 则使用延时策略处理该广播
4.当前广播接收器数据置空处理
5.如果要求waitForServices且当前有后台服务, 则先等后台服务处理, 设置广播状态WAITING_SERVICES并return
参考【第6.2节】
ContextImpl.registerReceiver(BroadcastReceiver, IntentFilter)过程:
1.根据BroadcastReceiver获取对应的ReceiverDispatcher
(1)先根据LoadedApk.getReceiverDispatcher, 从ArrayMap<BroadcastReceiver, ReceiverDispatcher>映射表中得到和BroadcastReceiver对应的ReceiverDispatcher
(2)如果LoadedApk为空, 则新建LoadedApk.ReceiverDispatcher
2.执行ReceiverDispatcher.getIIntentReceiver()得到InnerReceiver(即IIntentReceiver.Stub)
3.调用AMS.registerReceiver注册广播.
AMS.registerReceiver过程(入参为InnerReceiver和IntentFilter):
1.根据IntentFilter获取List
BroadcastQueue.scheduleBroadcastsLocked过程:
通过BroadcastHandler发送BROADCAST_INTENT_MSG, 在消息接收侧调用processNextBroadcast处理广播
processNextBroadcast过程:
1.无序广播处理:
(1)遍历无序广播列表mParallelBroadcasts
(2)获取每个广播对象BroadcastRecord的全部广播接收者列表BroadcastFilter
(3)调用BroadcastQueue.deliverToRegisteredReceiverLocked, 依次将当前广播发送给步骤1的广播接收者处理
(4)将已处理的广播加入历史广播列表
2.检查当前是否有进程正在处理广播mPendingBroadcast. 如有则不往下继续执行, 先等广播处理完; 若无则继续往下执行, 处理下一个广播
3.获取有序或延时广播处理:执行do while循环, 直到查找到下一个广播r:
(1)获取下一个广播r
(2)若当前广播为空, 则做一些扫尾工作包括: 延迟广播检查和执行, GC, oomAdj更新等并return
(3)若当前广播非空, 则判断广播处理是否超时, 若超时则调用broadcastTimeoutLocked超时处理并弹出ANR提示(超时时间是10秒), finish当前广播并设置广播状态为IDLE
(4)若当前广播的所有广播接收器列表已完成处理:
(4.1)更新cross-BroadcastRecord refcount计数,并调用performReceiveLocked执行BroadcastReceiver.onReceive广播接收操作和执行广播finish操作
(4.2)取消超时广播
(4.3)将当前广播添加到历史广播列表
(4.4)若当前广播为隐式广播, 则记录隐式广播
(4.5)当前广播处理完, mCurrentBroadcast置空, continue并执行下一轮do while循环
(5)如果下一个广播是延迟广播, 则针对mSplitRefcounts做相关处理, 同时将延迟广播添加到延迟广播列表
4.将步骤3的有序或延时广播r发送给当前索引nextReceiver的广播接收器处理(filter非空):
(1)获取广播r的当前广播接收器BroadcastFilter的索引nextReceiver. 并通过Handler超时机制发送消息, 便于杀死超时广播
(2)获取索引nextReceiver的广播接收器BroadcastFilter:
(2.1)调用deliverToRegisteredReceiverLocked将当前广播发送给广播接收器BroadcastFilter执行
(2.2)若当前广播处理完, 设置广播状态为IDLE, 并调用scheduleBroadcastsLocked继续处理下一个广播并return
5.若filter为空, 根据nextReceiver得到ResolveInfo且非空:
(1)先执行各种检查包括:targetSdkVersion, Appop操作权限, 防火墙, 权限review, 用户运行状态, 后台执行检查等.
(2)如果上述条件不符合, 则设置广播接收器状态为DELIVERY_SKIPPED, 设置广播状态为IDLE, 调用scheduleBroadcastsLocked处理下一个广播并return
(3)根据ResolveInfo构造ComponentName对象设置给当前广播, 设置广播接收器状态为DELIVERY_DELIVERED, 设置广播状态为APP_RECEIVE
(4)若当前进程活着, 则处理当前广播
(5)若当前进程未启动, 则先启动进程, 若进程启动失败, 则finishReceiverLocked结束当前广播接收操作, 设置广播状态为IDLE, 并调用scheduleBroadcastsLocked执行下一个广播接收操作
广播处理过程总结:
1.无序广播处理逻辑:一次性将所有无序广播BroadcastRecord发给他们的所有广播接收器BroadcastFilter处理
2.延时或有序广播处理:每次取一个广播BroadcastRecord及当前索引nextReceiver的广播接收器BroadcastFilter处理, 到下一次调用processNextBroadcast再获取下一个索引的广播接收器, 是串行执行的.
基于Android 10.0的源码剖析, 站在Luoshengyang/Innost/Gityuan肩膀上.
本文分析bindService过程.
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java
frameworks/base/services/core/java/com/android/server/am/ServiceRecord.java
frameworks/base/core/java/android/app/LoadedApk.java
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/core/java/android/app/Service.java
TODO
[ -> frameworks/base/core/java/android/app/ContextImpl.java ]
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null, getUser());
}
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
String instanceName, Handler handler, Executor executor, UserHandle user) {
// 获取ServiceConnection对象
IServiceConnection sd;
if (mPackageInfo != null) {
if (executor != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
} else {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
}
}
// 获取Activity令牌
IBinder token = getActivityToken();
if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
&& mPackageInfo.getApplicationInfo().targetSdkVersion
< android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
// 设置flags为不影响Service所在进程的调度和内存管理
flags |= BIND_WAIVE_PRIORITY;
}
service.prepareToLeaveProcess(this);
// 绑定isolated服务. 参考【第3节】
int res = ActivityManager.getService().bindIsolatedService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
return res != 0;
}
[ -> frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java ]
public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String instanceName,
String callingPackage, int userId) throws TransactionTooLargeException {
// isolated进程不能调用
enforceNotIsolatedCaller("bindService");
// instanceName非空的话,进行字符校验. 此处instanceName为空,走不到这里
if (instanceName != null) {
for (int i = 0; i < instanceName.length(); ++i) {
char c = instanceName.charAt(i);
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
|| (c >= '0' && c <= '9') || c == '_' || c == '.')) {
throw new IllegalArgumentException("Illegal instanceName");
}
}
}
synchronized(this) {
// 绑定服务. 参考【第4.1节】
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, instanceName, callingPackage, userId);
}
}
[ -> frameworks/base/services/core/java/com/android/server/am/ActiveServices.java ]
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String instanceName, String callingPackage, final int userId)
throws TransactionTooLargeException {
// 从mProcessList列表中获取调用进程
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
ActivityServiceConnectionsHolder<ConnectionRecord> activity = null;
if (token != null) {
// 获取指定Activity的服务连接持有者ActivityServiceConnectionHolder
activity = mAm.mAtmInternal.getServiceConnectionsHolder(token);
// 如果holder为空, 直接返回
if (activity == null) {
return 0;
}
}
int clientLabel = 0;
PendingIntent clientIntent = null;
final boolean isCallerSystem = callerApp.info.uid == Process.SYSTEM_UID;
// 如果是系统进程调用, 则需要对intent进行标记
if (isCallerSystem) {
// Hacky kind of thing -- allow system stuff to tell us
// what they are, so we can report this elsewhere for
// others to know why certain services are running.
service.setDefusable(true);
clientIntent = service.getParcelableExtra(Intent.EXTRA_CLIENT_INTENT);
if (clientIntent != null) {
clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
if (clientLabel != 0) {
// There are no useful extras in the intent, trash them.
// System code calling with this stuff just needs to know
// this will happen.
service = service.cloneFilter();
}
}
}
// flags检查
...
final boolean callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
final boolean isBindExternal = (flags & Context.BIND_EXTERNAL_SERVICE) != 0;
final boolean allowInstant = (flags & Context.BIND_ALLOW_INSTANT) != 0;
// 各种权限检查,并从ServiceMap中根据ComponentName查找ServiceRecord,并封装成ServiceLookupResult
// 参考【第4.2节】
ServiceLookupResult res =
retrieveServiceLocked(service, instanceName, resolvedType, callingPackage,
Binder.getCallingPid(), Binder.getCallingUid(), userId, true,
callerFg, isBindExternal, allowInstant);
ServiceRecord s = res.record;
// If permissions need a review before any of the app components can run,
// we schedule binding to the service but do not start its process, then
// we launch a review activity to which is passed a callback to invoke
// when done to start the bound service's process to completing the binding.
// 这段代码含义:如果在绑定服务之前需要权限检查,则先调起权限检查Activity,检查结果通过RemoteCallback回调
// 如果权限检查通过,则调用bringUpServiceLocked真正绑定服务, 否则调用unbindServiceLocked解绑服务
// 权限检查需要在前台执行
boolean permissionsReviewRequired = false;
if (mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(
s.packageName, s.userId)) {
permissionsReviewRequired = true;
// Show a permission review UI only for binding from a foreground app
if (!callerFg) {
return 0;
}
final ServiceRecord serviceRecord = s;
final Intent serviceIntent = service;
RemoteCallback callback = new RemoteCallback(
new RemoteCallback.OnResultListener() {
@Override
public void onResult(Bundle result) {
synchronized(mAm) {
final long identity = Binder.clearCallingIdentity();
try {
if (!mPendingServices.contains(serviceRecord)) {
return;
}
// If there is still a pending record, then the service
// binding request is still valid, so hook them up. We
// proceed only if the caller cleared the review requirement
// otherwise we unbind because the user didn't approve.
if (!mAm.getPackageManagerInternalLocked()
.isPermissionsReviewRequired(
serviceRecord.packageName, serviceRecord.userId)) {
try {
bringUpServiceLocked(serviceRecord,
serviceIntent.getFlags(), callerFg, false, false);
} catch (RemoteException e) {
/* ignore - local call */
}
} else {
unbindServiceLocked(connection);
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}
});
final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_MULTIPLE_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
intent.putExtra(Intent.EXTRA_PACKAGE_NAME, s.packageName);
intent.putExtra(Intent.EXTRA_REMOTE_CALLBACK, callback);
mAm.mHandler.post(new Runnable() {
@Override
public void run() {
mAm.mContext.startActivityAsUser(intent, new UserHandle(userId));
}
});
}
final long origId = Binder.clearCallingIdentity();
try {
// 如果当前正在restart过程中调用bind服务, 则从mRestartingServices列表中移除该服务及重置restart相关属性
unscheduleServiceRestartLocked(s, callerApp.info.uid, false);
// 如果flags为BIND_AUTO_CREATE
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
// 如果connections列表中没有flags为BIND_AUTO_CREATE的ConnectionRecord
if (!s.hasAutoCreateConnections()) {
// 设置ServiceState状态为bound
ServiceState stracker = s.getTracker();
if (stracker != null) {
stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(), s.lastActivity);
}
}
}
// Ensures that the given package name has an explicit set of allowed associations.
if ((flags & Context.BIND_RESTRICT_ASSOCIATIONS) != 0) {
mAm.requireAllowedAssociationsLocked(s.appInfo.packageName);
}
// 根据入参从映射表中查找或创建Association对象,并更新各相关属性
// 参考【第4.3节】
mAm.startAssociationLocked(callerApp.uid, callerApp.processName,
callerApp.getCurProcState(), s.appInfo.uid, s.appInfo.longVersionCode,
s.instanceName, s.processName);
// Once the apps have become associated, if one of them is caller is ephemeral
// the target app should now be able to see the calling app
mAm.grantEphemeralAccessLocked(callerApp.userId, service,
UserHandle.getAppId(s.appInfo.uid), UserHandle.getAppId(callerApp.uid));
// 从bindings映射表中查找或新建AppBindRecord. 参考【第4.4节】
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
// 创建ConnectionRecord
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent,
callerApp.uid, callerApp.processName, callingPackage);
// 建立binder和ConnectionRecord列表的映射关系
IBinder binder = connection.asBinder();
s.addConnection(binder, c);
b.connections.add(c);
if (activity != null) {
activity.addConnection(c);
}
b.client.connections.add(c);
c.startAssociationIfNeeded();
if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
b.client.hasAboveClient = true;
}
if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
s.whitelistManager = true;
}
if ((flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) {
s.setHasBindingWhitelistingBgActivityStarts(true);
}
// 从当前进程的services服务列表的ConnectionRecord列表中, 查找和其建立连接的Client, 看是否Client有Activity
// 并更新该进程状态信息和lru进程列表. 参考【第4.5节】
if (s.app != null) {
updateServiceClientActivitiesLocked(s.app, c, true);
}
ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
if (clist == null) {
clist = new ArrayList<>();
mServiceConnections.put(binder, clist);
}
clist.add(c);
// 如果flags为BIND_AUTO_CREATE, 真正执行绑定服务并返回. 参考【第4.6节】
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false, permissionsReviewRequired) != null) {
return 0;
}
}
// 若为其他flags, 且Service所在的进程非空, 则更新lru进程列表和oomAdj. 这个可能会提高所在进程优先级
if (s.app != null) {
if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
s.app.treatLikeActivity = true;
}
if (s.whitelistManager) {
s.app.whitelistManager = true;
}
// This could have made the service more important.
mAm.updateLruProcessLocked(s.app,
(callerApp.hasActivitiesOrRecentTasks() && s.app.hasClientActivities())
|| (callerApp.getCurProcState() <= ActivityManager.PROCESS_STATE_TOP
&& (flags & Context.BIND_TREAT_LIKE_ACTIVITY) != 0), b.client);
mAm.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_BIND_SERVICE);
}
if (s.app != null && b.intent.received) {
// Service is already running, so we can immediately publish the connection.
// 如果服务正在运行, 则先建立连接
c.conn.connected(s.name, b.intent.binder, false);
// If this is the first app connected back to this binding,
// and the service had previously asked to be told when rebound, then do so.
// rebind服务
if (b.intent.apps.size() == 1 && b.intent.doRebind) {
requestServiceBindingLocked(s, b.intent, callerFg, true);
}
} else if (!b.intent.requested) {
// bind服务
requestServiceBindingLocked(s, b.intent, callerFg, false);
}
// 从mStartingBackground后台服务列表中移除当前Service, 取消后台启动
getServiceMapLocked(s.userId).ensureNotStartingBackgroundLocked(s);
} finally {
Binder.restoreCallingIdentity(origId);
}
return 1;
}
参考文章: startService过程
[ -> frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java ]
// 映射关系Mapping is target uid -> target component -> source uid -> source process name -> association data.
Association startAssociationLocked(int sourceUid, String sourceProcess,
int sourceState, int targetUid, long targetVersionCode,
ComponentName targetComponent, String targetProcess) {
if (!mTrackingAssociations) {
return null;
}
ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
= mAssociations.get(targetUid);
if (components == null) {
components = new ArrayMap<>();
mAssociations.put(targetUid, components);
}
SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
if (sourceUids == null) {
sourceUids = new SparseArray<>();
components.put(targetComponent, sourceUids);
}
ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
if (sourceProcesses == null) {
sourceProcesses = new ArrayMap<>();
sourceUids.put(sourceUid, sourceProcesses);
}
Association ass = sourceProcesses.get(sourceProcess);
if (ass == null) {
ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent, targetProcess);
sourceProcesses.put(sourceProcess, ass);
}
ass.mCount++;
ass.mNesting++;
if (ass.mNesting == 1) {
ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
ass.mLastState = sourceState;
}
return ass;
}
[ -> frameworks/base/services/core/java/com/android/server/am/ServiceRecord.java ]
// 根据intent和app, 从bindings列表中匹配AppBindRecord, 没匹配到的话则新建一个
public AppBindRecord retrieveAppBindingLocked(Intent intent, ProcessRecord app) {
Intent.FilterComparison filter = new Intent.FilterComparison(intent);
IntentBindRecord i = bindings.get(filter);
if (i == null) {
i = new IntentBindRecord(this, filter);
bindings.put(filter, i);
}
AppBindRecord a = i.apps.get(app);
if (a != null) {
return a;
}
a = new AppBindRecord(this, i, app);
i.apps.put(app, a);
return a;
}
private boolean updateServiceClientActivitiesLocked(ProcessRecord proc,
ConnectionRecord modCr, boolean updateLru) {
if (modCr != null && modCr.binding.client != null) {
if (!modCr.binding.client.hasActivities()) {
// This connection is from a client without activities, so adding and removing is not interesting.
// 如果和Service建立连接的Client进程没有Activity, 则直接返回
return false;
}
}
// 从当前进程的services服务列表的ConnectionRecord列表中, 查找和其建立连接的Client, 看是否Client有Activity(即anyClientActivities).
boolean anyClientActivities = false;
for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) {
ServiceRecord sr = proc.services.valueAt(i);
ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = sr.getConnections();
for (int conni = connections.size() - 1; conni >= 0 && !anyClientActivities; conni--) {
ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
for (int cri=clist.size()-1; cri>=0; cri--) {
ConnectionRecord cr = clist.get(cri);
if (cr.binding.client == null || cr.binding.client == proc) {
// Binding to ourself is not interesting.
continue;
}
if (cr.binding.client.hasActivities()) {
anyClientActivities = true;
break;
}
}
}
}
// 更新当前进程状态和lru进程列表
if (anyClientActivities != proc.hasClientActivities()) {
proc.setHasClientActivities(anyClientActivities);
if (updateLru) {
mAm.updateLruProcessLocked(proc, anyClientActivities, null);
}
return true;
}
return false;
}
updateServiceClientActivitiesLocked方法含义:
从当前进程的services服务列表的ConnectionRecord列表中, 查找和其建立连接的Client, 看是否Client有Activity, 并更新该进程状态信息和lru进程列表.
参考文章: startService过程
bringUpServiceLocked方法在上一篇文章 startService过程 讲过. 会调到realStartServiceLocked方法.
(1) 对于startService调用链为: realStartServiceLocked -> ApplicationThread.scheduleCreateService -> sendServiceArgsLocked
(2) 对于bindService调用链为: realStartServiceLocked -> ApplicationThread.scheduleCreateService -> requestServiceBindingsLocked
接下来我们看一下realStartServiceLocked方法的具体代码.
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException {
...
// 服务创建
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
r.postNotification();
created = true;
if (r.whitelistManager) {
app.whitelistManager = true;
}
// 请求绑定服务
requestServiceBindingsLocked(r, execInFg);
// 从当前进程的services服务列表的ConnectionRecord列表中, 查找和其建立连接的Client, 看是否Client有Activity
// 并更新该进程状态信息和lru进程列表
updateServiceClientActivitiesLocked(app, null, true);
// 将所有与Service绑定的Client端的uid添加到mBoundClientUids列表中
// 并将该列表信息更新到WindowProcessController中
if (newService && created) {
app.addBoundClientUidsOfNewService(r);
}
...
}
参考文章: startService过程
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
throws TransactionTooLargeException {
for (int i=r.bindings.size()-1; i>=0; i--) {
IntentBindRecord ibr = r.bindings.valueAt(i);
if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
break;
}
}
}
遍历bindings列表每一项, 执行bind操作.
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
if (r.app == null || r.app.thread == null) {
// If service is not currently running, can't yet bind.
return false;
}
if ((!i.requested || rebind) && i.apps.size() > 0) {
try {
// 更新ServiceRecord bind阶段各属性
bumpServiceExecutingLocked(r, execInFg, "bind");
r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
// 调用ApplicationThread.scheduleBindService
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, r.app.getReportedProcState());
if (!rebind) {
i.requested = true;
}
i.hasBound = true;
i.doRebind = false;
} catch (TransactionTooLargeException e) {
// Keep the executeNesting count accurate.
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
throw e;
} catch (RemoteException e) {
// Keep the executeNesting count accurate.
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
return false;
}
}
return true;
}
[ -> frameworks/base/core/java/android/app/ActivityThread.java ]
private class ApplicationThread extends IApplicationThread.Stub {
...
public final void scheduleBindService(IBinder token, Intent intent, boolean rebind, int processState) {
updateProcessState(processState, false);
BindServiceData s = new BindServiceData();
s.token = token;
s.intent = intent;
s.rebind = rebind;
sendMessage(H.BIND_SERVICE, s);
}
}
class H extends Handler {
...
public void handleMessage(Message msg) {
switch (msg.what) {
case BIND_SERVICE:
handleBindService((BindServiceData)msg.obj);
break;
...
}
}
}
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
if (s != null) {
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
if (!data.rebind) {
// 调用Service.onBind
IBinder binder = s.onBind(data.intent);
// 发布服务
ActivityManager.getService().publishService(data.token, data.intent, binder);
} else {
// 调用Service.onRebind
s.onRebind(data.intent);
// 做一些列表移除工作
ActivityManager.getService().serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
}
}
[ -> frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java ]
public void publishService(IBinder token, Intent intent, IBinder service) {
synchronized(this) {
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}
[ -> frameworks/base/services/core/java/com/android/server/am/ActiveServices.java ]
// 这段代码的含义是: 根据intent封装filter对象并以此作为匹配条件
// 从bindings列表中的所有ConnectionRecord中查找filter匹配的ConnectionRecord, 然后建立连接
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
final long origId = Binder.clearCallingIdentity();
try {
if (r != null) {
Intent.FilterComparison filter = new Intent.FilterComparison(intent);
IntentBindRecord b = r.bindings.get(filter);
if (b != null && !b.received) {
b.binder = service;
b.requested = true;
b.received = true;
ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
for (int conni = connections.size() - 1; conni >= 0; conni--) {
ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
for (int i=0; i<clist.size(); i++) {
ConnectionRecord c = clist.get(i);
if (!filter.equals(c.binding.intent.intent)) {
continue;
}
// 建立连接. 参考【第7.1节】
c.conn.connected(r.name, service, false);
}
}
}
// 发布服务后的收尾工作
serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
[ -> frameworks/base/core/java/android/app/LoadedApk.java ]
private static class InnerConnection extends IServiceConnection.Stub {
final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
InnerConnection(LoadedApk.ServiceDispatcher sd) {
mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
}
public void connected(ComponentName name, IBinder service, boolean dead)
throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
// 建立连接. 参考【第7.2节】
sd.connected(name, service, dead);
}
}
}
// 如果有线程池在Runnable中执行, 否则直接在当前线程执行, 最终都调到doConnected
public void connected(ComponentName name, IBinder service, boolean dead) {
if (mActivityExecutor != null) {
mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
} else if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
doConnected(name, service, dead);
}
}
private final class RunConnection implements Runnable {
RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
mName = name;
mService = service;
mCommand = command;
mDead = dead;
}
public void run() {
if (mCommand == 0) {
// 建立连接. 参考【第7.4节】
doConnected(mName, mService, mDead);
} else if (mCommand == 1) {
doDeath(mName, mService);
}
}
final ComponentName mName;
final IBinder mService;
final int mCommand;
final boolean mDead;
}
// name为要bind的服务对应的ComponentName, service为onBind返回的Binder对象, dead为false表示绑定操作
public void doConnected(ComponentName name, IBinder service, boolean dead) {
ServiceDispatcher.ConnectionInfo old;
ServiceDispatcher.ConnectionInfo info;
synchronized (this) {
if (mForgotten) {
// We unbound before receiving the connection; ignore any connection received.
return;
}
// 如果当前连接中已经含义目标Service的ComponentName, 且binder和onBind方法返回的binder相同
// 则说明已经完成建立连接了, 直接返回
old = mActiveConnections.get(name);
if (old != null && old.binder == service) {
// Huh, already have this one. Oh well!
return;
}
if (service != null) {
// 新建ConnectionInfo对象并设置binder, 将ConnectionInfo对象添加到mActiveConnections列表
// A new service is being connected... set it all up.
info = new ConnectionInfo();
info.binder = service;
info.deathMonitor = new DeathMonitor(name, service);
service.linkToDeath(info.deathMonitor, 0);
mActiveConnections.put(name, info);
} else {
// The named service is being disconnected... clean up.
mActiveConnections.remove(name);
}
if (old != null) {
old.binder.unlinkToDeath(old.deathMonitor, 0);
}
}
// If there was an old service, it is now disconnected.
if (old != null) {
mConnection.onServiceDisconnected(name);
}
if (dead) {
mConnection.onBindingDied(name);
}
// If there is a new viable service, it is now connected.
if (service != null) {
// 回调ServiceConnection.onServiceConnected
mConnection.onServiceConnected(name, service);
} else {
// The binding machinery worked, but the remote returned null from onBind().
mConnection.onNullBinding(name);
}
}
[ -> frameworks/base/core/java/android/content/ServiceConnection.java ]
一般是开发者调用bindService时, 手动传入ServiceConnection的实现类.
bindService和startService过程差不多, 差别主要是在创建Service实例后一个是执行bind操作, 一个是执行start操作.
]]>基于Android 10.0的源码剖析, 站在Luoshengyang/Innost/Gityuan肩膀上.
本文分析startService过程.
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java
frameworks/base/services/core/java/com/android/server/am/ServiceRecord.java
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/core/java/android/app/Service.java
TODO
[ -> frameworks/base/core/java/android/app/ContextImpl.java ]
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
// requireForeground=false表示调用startService启动非前台服务, 区别于startForegroundService
return startServiceCommon(service, false, mUser);
}
private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
return cn;
}
注意:
startService和startForegroundService差别是入参requireForeground的值,其他代码逻辑完全复用.
[ -> frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java ]
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
[ -> frameworks/base/services/core/java/com/android/server/am/ActiveServices.java ]
ComponentName startServiceLocked(IApplicationThread caller, Intent service,
String resolvedType, int callingPid, int callingUid, boolean fgRequired,
String callingPackage, final int userId)
throws TransactionTooLargeException {
// fgRequired为false, 表示startService
// allowBackgroundActivityStarts为false, 表示不允许后台Activity启动Service
return startServiceLocked(caller, service, resolvedType, callingPid, callingUid,
fgRequired, callingPackage, userId, false);
}
继续看该方法实现:
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
final int userId, boolean allowBackgroundActivityStarts)
throws TransactionTooLargeException {
final boolean callerFg;
if (caller != null) {
// 从mLruProcesses列表中找出指定进程
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
} else {
callerFg = true;
}
// 各种权限检查,并从ServiceMap中根据ComponentName查找ServiceRecord,并封装成ServiceLookupResult
// 参考【第4.2节】
ServiceLookupResult res = retrieveServiceLocked(service, null, resolvedType,
callingPackage, callingPid, callingUid, userId, true, callerFg, false, false);
// 获取ServiceRecord
ServiceRecord r = res.record;
// If we're starting indirectly (e.g. from PendingIntent), figure out whether
// we're launching into an app in a background state. This keys off of the same
// idleness state tracking as e.g. O+ background service start policy.
// 是否后台启动, Android 8.0+有后台启动限制
final boolean bgLaunch = !mAm.isUidActiveLocked(r.appInfo.uid);
// If the app has strict background restrictions, we treat any bg service
// start analogously to the legacy-app forced-restrictions case, regardless
// of its target SDK version.
// 如果后台启动Service,且app有后台启动限制,则forcedStandby设置为true
boolean forcedStandby = false;
if (bgLaunch && appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) {
forcedStandby = true;
}
// If this is a direct-to-foreground start, make sure it is allowed as per the app op.
// 如果是startForegroundService启动前台服务,检查前台启动操作权限是否允许
boolean forceSilentAbort = false;
if (fgRequired) {
final int mode = mAm.mAppOpsService.checkOperation(
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName);
switch (mode) {
case AppOpsManager.MODE_ALLOWED:
case AppOpsManager.MODE_DEFAULT:
// All okay.
break;
case AppOpsManager.MODE_IGNORED:
// Not allowed, fall back to normal start service, failing siliently
// if background check restricts that.
fgRequired = false;
forceSilentAbort = true;
break;
}
}
// If this isn't a direct-to-foreground start, check our ability to kick off an
// arbitrary service
// 如果是后台启动或者启动非前台服务,检查是否允许后台启动,如果不能的话返回null
if (forcedStandby || (!r.startRequested && !fgRequired)) {
// Before going further -- if this app is not allowed to start services in the
// background, then at this point we aren't going to let it period.
final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,
r.appInfo.targetSdkVersion, callingPid, false, false, forcedStandby);
if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
if (allowed == ActivityManager.APP_START_MODE_DELAYED || forceSilentAbort) {
// In this case we are silently disabling the app, to disrupt as
// little as possible existing apps.
return null;
}
if (forcedStandby) {
// This is an O+ app, but we might be here because the user has placed
// it under strict background restrictions. Don't punish the app if it's
// trying to do the right thing but we're denying it for that reason.
if (fgRequired) {
return null;
}
}
// This app knows it is in the new model where this operation is not
// allowed, so tell it what has happened.
UidRecord uidRec = mAm.mProcessList.getUidRecordLocked(r.appInfo.uid);
return new ComponentName("?", "app is in background uid " + uidRec);
}
}
// At this point we've applied allowed-to-start policy based on whether this was
// an ordinary startService() or a startForegroundService(). Now, only require that
// the app follow through on the startForegroundService() -> startForeground()
// contract if it actually targets O+.
// Android 8.0以下启动前台服务不需要调用startForegroundService(), 即fgRequired为false
if (r.appInfo.targetSdkVersion < Build.VERSION_CODES.O && fgRequired) {
fgRequired = false;
}
NeededUriGrants neededGrants = mAm.mUgmInternal.checkGrantUriPermissionFromIntent(
callingUid, r.packageName, service, service.getFlags(), null, r.userId);
// 权限检查permission review
if (!requestStartTargetPermissionsReviewIfNeededLocked(r, callingPackage,
callingUid, service, callerFg, userId)) {
return null;
}
if (unscheduleServiceRestartLocked(r, callingUid, false)) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "START SERVICE WHILE RESTART PENDING: " + r);
}
// 设置ServiceRecord启动参数, pendingStarts中添加启动项StartItem
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true;
r.delayedStop = false;
r.fgRequired = fgRequired;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), service, neededGrants, callingUid));
if (fgRequired) {
// 如果是Android 8.0+调用的startForegroundService()启动前台服务的话, 更新ServiceState
// We are now effectively running a foreground service.
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setForeground(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
}
mAm.mAppOpsService.startOperation(AppOpsManager.getToken(mAm.mAppOpsService),
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, true);
}
// 获取ServiceMap. 参考【第4.3节】
final ServiceMap smap = getServiceMapLocked(r.userId);
boolean addToStarting = false;
// 如果是调用startService且Service还没启动,且mStartedUsers列表包含userId
// 则更新addToStarting状态位为true
if (!callerFg && !fgRequired && r.app == null && mAm.mUserController.hasStartedUserState(r.userId)) {
// 从进程列表中获取启动Service所在的进程
ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
if (proc == null || proc.getCurProcState() > ActivityManager.PROCESS_STATE_RECEIVER) {
// If this is not coming from a foreground caller, then we may want
// to delay the start if there are already other background services
// that are starting. This is to avoid process start spam when lots
// of applications are all handling things like connectivity broadcasts.
// We only do this for cached processes, because otherwise an application
// can have assumptions about calling startService() for a service to run
// in its own process, and for that process to not be killed before the
// service is started. This is especially the case for receivers, which
// may start a service in onReceive() to do some additional work and have
// initialized some global state as part of that.
// 如果delayed为true,延迟启动
if (r.delayed) {
// This service is already scheduled for a delayed start; just leave
// it still waiting.
return r.name;
}
// 如果后台启动服务数超过mMaxStartingBackground,则延迟启动
if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
// Something else is starting, delay!
smap.mDelayedStartList.add(r);
r.delayed = true;
return r.name;
}
// addToStarting设置为true
addToStarting = true;
} else if (proc.getCurProcState() >= ActivityManager.PROCESS_STATE_SERVICE) {
// We slightly loosen when we will enqueue this new service as a background
// starting service we are waiting for, to also include processes that are
// currently running other services or receivers.
addToStarting = true;
}
}
// Called when the service is started with allowBackgroundActivityStarts set.
if (allowBackgroundActivityStarts) {
r.whitelistBgActivityStartsOnServiceStart();
}
// 启动服务. 参考【第4.4节】
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}
private ServiceLookupResult retrieveServiceLocked(Intent service,
String instanceName, String resolvedType, String callingPackage,
int callingPid, int callingUid, int userId,
boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
boolean allowInstant) {
ServiceRecord r = null;
// 获取userId
userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE, "service", callingPackage);
// 根据userId获取ServiceMap. 参考【第4.3节】
ServiceMap smap = getServiceMapLocked(userId);
// 获取Component
final ComponentName comp;
if (instanceName == null) {
comp = service.getComponent();
} else {
final ComponentName realComp = service.getComponent();
comp = new ComponentName(realComp.getPackageName(), realComp.getClassName() + ":" + instanceName);
}
// 获取ServiceRecord
if (comp != null) {
r = smap.mServicesByInstanceName.get(comp);
}
if (r == null && !isBindExternal && instanceName == null) {
Intent.FilterComparison filter = new Intent.FilterComparison(service);
r = smap.mServicesByIntent.get(filter);
}
if (r != null && (r.serviceInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0
&& !callingPackage.equals(r.packageName)) {
// If an external service is running within its own package, other packages should not bind to that instance.
r = null;
}
if (r == null) {
try {
int flags = ActivityManagerService.STOCK_PM_FLAGS | PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
if (allowInstant) {
flags |= PackageManager.MATCH_INSTANT;
}
// 获取ResolveInfo
ResolveInfo rInfo = mAm.getPackageManagerInternalLocked().resolveService(service, resolvedType, flags, userId, callingUid);
ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null;
...
ComponentName className = new ComponentName(sInfo.applicationInfo.packageName, sInfo.name);
ComponentName name = comp != null ? comp : className;
// 检查调起方和被调起方, 不同uid下的不同package能否建立联系. 默认情况下只要uid之一是SYSTEM_UID,都是允许建立练习的
if (!mAm.validateAssociationAllowedLocked(callingPackage, callingUid,name.getPackageName(), sInfo.applicationInfo.uid)) {
String msg = "association not allowed between packages " + callingPackage + " and " + name.getPackageName();
// Service查找失败, 返回null
return new ServiceLookupResult(null, msg);
}
// Store the defining packageName and uid, as they might be changed in
// the ApplicationInfo for external services (which run with the package name
// and uid of the caller).
// 这段代码检查是否允许Service运行在调用方的package和uid中
String definingPackageName = sInfo.applicationInfo.packageName;
int definingUid = sInfo.applicationInfo.uid;
if ((sInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0) {
if (isBindExternal) {
// 各种检查:exported和flags & ServiceInfo.FLAG_ISOLATED_PROCESS
...
// Run the service under the calling package's application.
ApplicationInfo aInfo = AppGlobals.getPackageManager().getApplicationInfo(
callingPackage, ActivityManagerService.STOCK_PM_FLAGS, userId);
sInfo = new ServiceInfo(sInfo);
sInfo.applicationInfo = new ApplicationInfo(sInfo.applicationInfo);
sInfo.applicationInfo.packageName = aInfo.packageName;
sInfo.applicationInfo.uid = aInfo.uid;
name = new ComponentName(aInfo.packageName, name.getClassName());
className = new ComponentName(aInfo.packageName,
instanceName == null ? className.getClassName()
: (className.getClassName() + ":" + instanceName));
service.setComponent(name);
} else {
throw new SecurityException("BIND_EXTERNAL_SERVICE required for " + name);
}
}
if (userId > 0) {
// Checks to see if the caller is in the same app as the singleton component, or the component is in a special app.
// 检查调用方和被调用方是否在同一个app中, 或者被调用方为SYSTEM_UID或PHONE_UID
if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo, sInfo.name, sInfo.flags)
&& mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
userId = 0;
smap = getServiceMapLocked(0);
}
sInfo = new ServiceInfo(sInfo);
sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
}
// 从map中查找
r = smap.mServicesByInstanceName.get(name);
if (r == null && createIfNeeded) {
final Intent.FilterComparison filter = new Intent.FilterComparison(service.cloneFilter());
final ServiceRestarter res = new ServiceRestarter();
...
// 创建ServiceRecord,并添加到Map中
r = new ServiceRecord(mAm, ss, className, name, definingPackageName, definingUid, filter, sInfo, callingFromFg, res);
res.setService(r);
smap.mServicesByInstanceName.put(name, r);
smap.mServicesByIntent.put(filter, r);
// 从pending列表移除该ServiceRecord
for (int i=mPendingServices.size()-1; i>=0; i--) {
final ServiceRecord pr = mPendingServices.get(i);
if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid && pr.instanceName.equals(name)) {
mPendingServices.remove(i);
}
}
}
} catch (RemoteException ex) {
// pm is in same process, this will never happen.
}
}
if (r != null) {
// 各种检查: 包括防火墙,权限等
...
return new ServiceLookupResult(r, null);
}
return null;
}
private ServiceMap getServiceMapLocked(int callingUser) {
ServiceMap smap = mServiceMap.get(callingUser);
if (smap == null) {
smap = new ServiceMap(mAm.mHandler.getLooper(), callingUser);
mServiceMap.put(callingUser, smap);
}
return smap;
}
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
// 更新ServiceState状态为started
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
}
r.callStart = false;
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();
}
// 拉起服务. 参考【第4.5节】
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
if (error != null) {
return new ComponentName("!!", error);
}
if (r.startRequested && addToStarting) {
boolean first = smap.mStartingBackground.size() == 0;
smap.mStartingBackground.add(r);
r.startingBgTimeout = SystemClock.uptimeMillis() + mAm.mConstants.BG_START_TIMEOUT;
if (first) {
smap.rescheduleDelayedStartsLocked();
}
} else if (callerFg || r.fgRequired) {
smap.ensureNotStartingBackgroundLocked(r);
}
return r.name;
}
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
if (r.app != null && r.app.thread != null) {
// 如果Service已经创建,则发送启动服务消息
sendServiceArgsLocked(r, execInFg, false);
return null;
}
if (!whileRestarting && mRestartingServices.contains(r)) {
// If waiting for a restart, then do nothing.
return null;
}
// We are now bringing the service up, so no longer in the restarting state.
if (mRestartingServices.remove(r)) {
clearRestartingIfNeededLocked(r);
}
// Make sure this service is no longer considered delayed, we are starting it now.
if (r.delayed) {
getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
// Make sure that the user who owns this service is started. If not,
// we don't want to allow it to run.
if (!mAm.mUserController.hasStartedUserState(r.userId)) {
bringDownServiceLocked(r);
return msg;
}
// Service is now being launched, its package can't be stopped.
AppGlobals.getPackageManager().setPackageStoppedState(r.packageName, false, r.userId);
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);
ProcessRecord app;
if (!isolated) { // 非isolated进程
// 从进程列表获取进程
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (app != null && app.thread != null) {
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
// 真正启动服务. 参考【第4.6节】
realStartServiceLocked(r, app, execInFg);
return null;
// If a dead object exception was thrown -- fall through to restart the application.
}
} else { // isolated进程
// If this service runs in an isolated process, then each time
// we call startProcessLocked() we will get a new isolated
// process, starting another process if we are currently waiting
// for a previous process to come up. To deal with this, we store
// in the service any current isolated process it is running in or
// waiting to have come up.
app = r.isolatedProc;
if (WebViewZygote.isMultiprocessEnabled() && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
hostingRecord = HostingRecord.byWebviewZygote(r.instanceName);
}
if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) {
hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName, r.definingUid);
}
}
// 如果进程为空,则启动进程并将ServiceRecord添加到服务队列中等待执行
if (app == null && !permissionsReviewRequired) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, hostingRecord, false, isolated, false)) == null) {
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
if (r.fgRequired) {
mAm.tempWhitelistUidLocked(r.appInfo.uid, SERVICE_START_FOREGROUND_TIMEOUT, "fg-service-launch");
}
// mPendingServices列表中添加服务
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
if (r.delayedStop) {
// Oh and hey we've already been asked to stop!
r.delayedStop = false;
if (r.startRequested) {
stopServiceLocked(r);
}
}
return null;
}
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException {
// 设置进程
r.setProcess(app);
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
// services列表中添加服务
final boolean newService = app.services.add(r);
// 更新ServiceRecord create阶段各属性. 参考【第4.8节】
bumpServiceExecutingLocked(r, execInFg, "create");
// 更新lru进程信息
mAm.updateLruProcessLocked(app, false, null);
// 更新进程中前台服务状态等信息
updateServiceForegroundLocked(r.app, /* oomAdj= */ false);
// 更新oomAdj
mAm.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
boolean created = false;
synchronized (r.stats.getBatteryStats()) {
r.stats.startLaunchedLocked();
}
// Updates a package last used time.
mAm.notifyPackageUse(r.serviceInfo.packageName, PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
// 强制更新进程状态为PROCESS_STATE_SERVICE
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
// 创建服务. 参考【5.1节】
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
r.postNotification();
created = true;
if (r.whitelistManager) {
app.whitelistManager = true;
}
// 下面这段代码是bindService相关逻辑,此处只分析startService
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);
if (newService && created) {
app.addBoundClientUidsOfNewService(r);
}
// If the service is in the started state, and there are no
// pending arguments, then fake up one so its onStartCommand() will be called.
// 如果pendingStarts列表为空,则将该服务对应的StartItem添加到该列表中
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), null, null, 0));
}
// 发送启动服务消息. 参考【第4.7节】
sendServiceArgsLocked(r, execInFg, true);
if (r.delayed) {
getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
if (r.delayedStop) {
// Oh and hey we've already been asked to stop!
r.delayedStop = false;
if (r.startRequested) {
stopServiceLocked(r);
}
}
}
realStartServiceLocked主要做的事情:
(1) ApplicationThread.scheduleCreateService: 创建Service,并调用onCreate方法
(2) sendServiceArgsLocked: 启动Service,通过ApplicationThread.scheduleServiceArgs最终调用到onStartCommand
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException {
final int N = r.pendingStarts.size();
if (N == 0) {
return;
}
ArrayList<ServiceStartArgs> args = new ArrayList<>();
while (r.pendingStarts.size() > 0) {
// 从pendingStarts列表移除并取出StartItem
ServiceRecord.StartItem si = r.pendingStarts.remove(0);
// 当intent=null且pendingStarts列表存在多个待启动的Service时,直接跳过
if (si.intent == null && N > 1) {
continue;
}
// 更新deliver信息
si.deliveredTime = SystemClock.uptimeMillis();
r.deliveredStarts.add(si);
si.deliveryCount++;
if (si.neededGrants != null) {
mAm.mUgmInternal.grantUriPermissionUncheckedFromIntent(si.neededGrants, si.getUriPermissionsLocked());
}
mAm.grantEphemeralAccessLocked(r.userId, si.intent, UserHandle.getAppId(r.appInfo.uid), UserHandle.getAppId(si.callingId));
// 更新ServiceRecord start阶段各属性. 参考【第4.8节】
bumpServiceExecutingLocked(r, execInFg, "start");
// 更新oomAdj
if (!oomAdjusted) {
oomAdjusted = true;
mAm.updateOomAdjLocked(r.app, true, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
}
if (r.fgRequired && !r.fgWaiting) {
if (!r.isForeground) {
// 如果启动前台服务,在调用了startForegroundService()后若当前还没有调用startForeground()
// 则要检查startForeground()是否在规定时间内调用,超时时间为10s
// 如果超时未调用则stopService,同时抛出ANR异常
scheduleServiceForegroundTransitionTimeoutLocked(r);
} else { // 如果已经调用了startForeground(), 则重置状态
r.fgRequired = false;
}
}
int flags = 0;
if (si.deliveryCount > 1) {
flags |= Service.START_FLAG_RETRY;
}
if (si.doneExecutingCount > 0) {
flags |= Service.START_FLAG_REDELIVERY;
}
// args列表中添加服务启动参数
args.add(new ServiceStartArgs(si.taskRemoved, si.id, flags, si.intent));
}
ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args);
// 设置列表最大数为4
slice.setInlineCountLimit(4);
Exception caughtException = null;
try {
// 启动Service.onStartCommand. 参考【第5.2节】
r.app.thread.scheduleServiceArgs(r, slice);
} catch (TransactionTooLargeException e) {
caughtException = e;
} catch (RemoteException e) {
caughtException = e;
} catch (Exception e) {
caughtException = e;
}
// 异常时,做一些数据清理工作
if (caughtException != null) {
// Keep nesting count correct
final boolean inDestroying = mDestroyingServices.contains(r);
for (int i = 0; i < args.size(); i++) {
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
}
if (caughtException instanceof TransactionTooLargeException) {
throw (TransactionTooLargeException)caughtException;
}
}
}
private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
// Services within the system server won't start until SystemServer
// does Looper.loop(), so we shouldn't try to start/bind to them too early in the boot
// process. However, since there's a little point of showing the ANR dialog in that case,
// let's suppress the timeout until PHASE_THIRD_PARTY_APPS_CAN_START.
// Too early to start/bind service in system_server: Phase < SystemService.PHASE_THIRD_PARTY_APPS_CAN_START
// 在Phase < PHASE_THIRD_PARTY_APPS_CAN_START之前,不检查服务启动超时
boolean timeoutNeeded = true;
if ((mAm.mBootPhase < SystemService.PHASE_THIRD_PARTY_APPS_CAN_START)
&& (r.app != null) && (r.app.pid == android.os.Process.myPid())) {
timeoutNeeded = false;
}
// 设置ServiceRecord各属性
long now = SystemClock.uptimeMillis();
if (r.executeNesting == 0) {
r.executeFg = fg;
// 设置ServiceState状态为executing
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
}
// 添加到executingServices列表
if (r.app != null) {
r.app.executingServices.add(r);
r.app.execServicesFg |= fg;
if (timeoutNeeded && r.app.executingServices.size() == 1) {
// 检查服务执行时间是否超时,超时的话会抛出ANR异常.参考【第7.1节】
scheduleServiceTimeoutLocked(r.app);
}
}
} else if (r.app != null && fg && !r.app.execServicesFg) {
r.app.execServicesFg = true;
if (timeoutNeeded) {
// 检查服务执行时间是否超时,超时的话会抛出ANR异常.参考【第7.1节】
scheduleServiceTimeoutLocked(r.app);
}
}
r.executeFg |= fg;
r.executeNesting++;
r.executingStart = now;
}
[ -> frameworks/base/core/java/android/app/ActivityThread.java ]
public final void scheduleCreateService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}
// 遍历args列表并依次将每一项参数封装到ServiceArgsData,然后向H中发送消息并调用onStartCommand方法
public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
List<ServiceStartArgs> list = args.getList();
for (int i = 0; i < list.size(); i++) {
ServiceStartArgs ssa = list.get(i);
ServiceArgsData s = new ServiceArgsData();
s.token = token;
s.taskRemoved = ssa.taskRemoved;
s.startId = ssa.startId;
s.flags = ssa.flags;
s.args = ssa.args;
sendMessage(H.SERVICE_ARGS, s);
}
}
class H extends Handler {
...
public void handleMessage(Message msg) {
switch (msg.what) {
case CREATE_SERVICE:
handleCreateService((CreateServiceData)msg.obj);
break;
case SERVICE_ARGS:
handleServiceArgs((ServiceArgsData)msg.obj);
break;
...
}
}
}
private void handleCreateService(CreateServiceData data) {
// If we are getting ready to gc after going to the background, well we are back active so skip it.
// 服务创建过程不执行GC操作
unscheduleGcIdler();
// 反射机制创建Service实例
LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
Service service = null;
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);
// 创建ApplicationContext
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
// 返回或新建Application
Application app = packageInfo.makeApplication(false, mInstrumentation);
// attach服务到进程
service.attach(context, this, data.info.name, data.token, app, ActivityManager.getService());
// 调用Service.onCreate
service.onCreate();
// 服务添加到mServices列表
mServices.put(data.token, service);
// 做一些服务创建后的状态更新工作
ActivityManager.getService().serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token);
if (s != null) {
if (data.args != null) {
data.args.setExtrasClassLoader(s.getClassLoader());
data.args.prepareToEnterProcess();
}
int res;
if (!data.taskRemoved) {
// 调用onStartCommand
res = s.onStartCommand(data.args, data.flags, data.startId);
} else {
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
}
// 等待执行完成
QueuedWork.waitToFinish();
// 将服务从deliver列表移除,并设置服务stopIfKilled属性, 以及做一些其他列表移除工作
ActivityManager.getService().serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
}
}
[ -> frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java ]
public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
synchronized(this) {
mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
}
}
[ -> frameworks/base/services/core/java/com/android/server/am/ActiveServices.java ]
这段代码ServiceRecord的stopIfKilled解释:参考【第7.3节】
void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
boolean inDestroying = mDestroyingServices.contains(r);
if (type == ActivityThread.SERVICE_DONE_EXECUTING_START) {
// 若为启动服务,从deliveredStarts中查找指定服务,并设置服务stopIfKilled属性
r.callStart = true;
switch (res) {
case Service.START_STICKY_COMPATIBILITY:
case Service.START_STICKY: {
// We are done with the associated start arguments.
r.findDeliveredStart(startId, false, true);
// Don't stop if killed.
r.stopIfKilled = false;
break;
}
case Service.START_NOT_STICKY: {
// We are done with the associated start arguments.
r.findDeliveredStart(startId, false, true);
if (r.getLastStartId() == startId) {
// There is no more work, and this service doesn't want to hang around if killed.
r.stopIfKilled = true;
}
break;
}
case Service.START_REDELIVER_INTENT: {
// We'll keep this item until they explicitly call stop for it, but keep track of the fact that it was delivered.
ServiceRecord.StartItem si = r.findDeliveredStart(startId, false, false);
if (si != null) {
si.deliveryCount = 0;
si.doneExecutingCount++;
// Don't stop if killed.
r.stopIfKilled = true;
}
break;
}
case Service.START_TASK_REMOVED_COMPLETE: {
// Special processing for onTaskRemoved(). Don't impact normal onStartCommand() processing.
r.findDeliveredStart(startId, true, true);
break;
}
}
if (res == Service.START_STICKY_COMPATIBILITY) {
r.callStart = false;
}
} else if (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) {
// destroy服务
...
}
// 做一些Service清理工作,具体实现看下面代码
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
}
继续看下面代码:
private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying, boolean finishing) {
r.executeNesting--;
if (r.executeNesting <= 0) {
if (r.app != null) {
r.app.execServicesFg = false;
r.app.executingServices.remove(r);
if (r.app.executingServices.size() == 0) {
// 如果当前没有正在执行的服务,则移除SERVICE_TIMEOUT_MSG消息
mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
} else if (r.executeFg) {
// Need to re-evaluate whether the app still needs to be in the foreground.
for (int i=r.app.executingServices.size()-1; i>=0; i--) {
if (r.app.executingServices.valueAt(i).executeFg) {
r.app.execServicesFg = true;
break;
}
}
}
if (inDestroying) { // 从mDestroyingServices列表移除服务
mDestroyingServices.remove(r);
r.bindings.clear();
}
// 更新oomAdj
mAm.updateOomAdjLocked(r.app, true, OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
}
// 重置前台执行标识位为false
r.executeFg = false;
if (r.tracker != null) {
final int memFactor = mAm.mProcessStats.getMemFactorLocked();
final long now = SystemClock.uptimeMillis();
// 更新ServiceState状态为非执行中和非前台
r.tracker.setExecuting(false, memFactor, now);
r.tracker.setForeground(false, memFactor, now);
if (finishing) {
r.tracker.clearCurrentOwner(r, false);
r.tracker = null;
}
}
if (finishing) {
// 从services列表移除服务
if (r.app != null && !r.app.isPersistent()) {
r.app.services.remove(r);
r.app.updateBoundClientUids();
if (r.whitelistManager) {
updateWhitelistManagerLocked(r.app);
}
}
// process置空
r.setProcess(null);
}
}
}
[ -> frameworks/base/services/core/java/com/android/server/am/ServiceRecord.java ]
// 根据属性id和taskRemoved从deliveredStarts列表中匹配Service, 并根据remove标识决定要不要从列表移除
public StartItem findDeliveredStart(int id, boolean taskRemoved, boolean remove) {
final int N = deliveredStarts.size();
for (int i=0; i<N; i++) {
StartItem si = deliveredStarts.get(i);
if (si.id == id && si.taskRemoved == taskRemoved) {
if (remove) deliveredStarts.remove(i);
return si;
}
}
return null;
}
前台服务执行时间限制是20秒,后台服务执行时间限制是200秒,否则超时会报ANR异常. 具体代码体现如下:
(1) ActiveServices.scheduleServiceTimeoutLocked
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
if (proc.executingServices.size() == 0 || proc.thread == null) {
return;
}
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
mAm.mHandler.sendMessageDelayed(msg,
proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
}
// How long we wait for a service to finish executing.
static final int SERVICE_TIMEOUT = 20*1000;
static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
(2) MainHandler.SERVICE_TIMEOUT_MSG
final class MainHandler extends Handler {
public MainHandler(Looper looper) {
super(looper, null, true);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
...
case SERVICE_TIMEOUT_MSG: {
mServices.serviceTimeout((ProcessRecord)msg.obj);
} break;
case SERVICE_FOREGROUND_TIMEOUT_MSG: {
mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
} break;
...
}
}
(3) ActiveServices.serviceTimeout
void serviceTimeout(ProcessRecord proc) {
String anrMessage = null;
synchronized(mAm) {
if (proc.isDebugging()) {
// The app's being debugged, ignore timeout.
return;
}
if (proc.executingServices.size() == 0 || proc.thread == null) {
return;
}
final long now = SystemClock.uptimeMillis();
final long maxTime = now -
(proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
ServiceRecord timeout = null;
long nextTime = 0;
for (int i=proc.executingServices.size()-1; i>=0; i--) {
ServiceRecord sr = proc.executingServices.valueAt(i);
if (sr.executingStart < maxTime) {
timeout = sr;
break;
}
if (sr.executingStart > nextTime) {
nextTime = sr.executingStart;
}
}
if (timeout != null && mAm.mProcessList.mLruProcesses.contains(proc)) {
StringWriter sw = new StringWriter();
PrintWriter pw = new FastPrintWriter(sw, false, 1024);
pw.println(timeout);
timeout.dump(pw, " ");
pw.close();
mLastAnrDump = sw.toString();
mAm.mHandler.removeCallbacks(mLastAnrDumpClearer);
mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS);
anrMessage = "executing service " + timeout.shortInstanceName;
} else {
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
}
}
if (anrMessage != null) {
proc.appNotResponding(null, null, null, null, false, anrMessage);
}
}
https://developer.android.com/about/versions/oreo/android-8.0-changes
(1) Android 8.0之前一般通过startService启动后台服务, 当系统内存紧张情况下后台Service可能会被杀死.
如果希望Service能够长时间运行而不被杀死, 可以在通过startService启动服务后, 在Service的onStartCommand方法中调用startForeground(id, notification)将服务设置为前台服务. 比如一般的音乐播放器都是这种做法.
(2) Android 8.0之后出于资源考虑对Service做了一些限制. 比如不允许后台调用startService, 否则会报错. 启动前台服务方式变成调用startForegroundService, 之后再在Service的onStartCommand方法中调用startForeground(id, notification)将服务设置为前台服务.
(3) startService和startForegroundService共有一套代码实现, 都是调用startServiceCommon, 差别就是入参requireForeground前者为false后者为true.
// frameworks/base/core/java/android/app/ContextImpl.java
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
@Override
public ComponentName startForegroundService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, true, mUser);
}
(4) Android 8.0之后启动前台服务, 会检查调用startForegroundService方法后, 是否在规定时间内调用了startForeground. 这个超时时间是10秒, 如果超时未调用则会stopService,同时抛出ANR异常. 具体代码体现如下:
4.1 ActiveServices.scheduleServiceForegroundTransitionTimeoutLocked
[ -> frameworks/base/services/core/java/com/android/server/am/ActiveServices.java ]
void scheduleServiceForegroundTransitionTimeoutLocked(ServiceRecord r) {
...
Message msg = mAm.mHandler.obtainMessage(ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG);
msg.obj = r;
r.fgWaiting = true;
mAm.mHandler.sendMessageDelayed(msg, SERVICE_START_FOREGROUND_TIMEOUT);
}
4.2 MainHandler.SERVICE_FOREGROUND_TIMEOUT_MSG
[ -> frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java ]
final class MainHandler extends Handler {
public MainHandler(Looper looper) {
super(looper, null, true);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
...
case SERVICE_TIMEOUT_MSG: {
mServices.serviceTimeout((ProcessRecord)msg.obj);
} break;
case SERVICE_FOREGROUND_TIMEOUT_MSG: {
mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
} break;
...
}
}
4.3 ActiveServices.serviceForegroundTimeout
[ -> frameworks/base/services/core/java/com/android/server/am/ActiveServices.java ]
void serviceForegroundTimeout(ServiceRecord r) {
ProcessRecord app;
synchronized (mAm) {
if (!r.fgRequired || r.destroying) {
return;
}
app = r.app;
if (app != null && app.isDebugging()) {
// The app's being debugged; let it ride
return;
}
// startForeground()超时,stopService
r.fgWaiting = false;
stopServiceLocked(r);
}
// ANR调用
if (app != null) {
app.appNotResponding(null, null, null, null, false,
"Context.startForegroundService() did not then call Service.startForeground(): " + r);
}
}
运行于主线程
[ -> frameworks/base/core/java/android/app/Service.java ]
public @StartResult int onStartCommand(Intent intent, @StartArgFlags int flags, int startId) {
onStart(intent, startId);
return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY;
}
(1) 入参:
intent: 通过startService传进来的意图. 如果Service重启时为null
flags: Additional data about this start request
startId: A unique integer representing this specific request to start
(2) 返回值:
描述了Service被杀后,应该怎么继续启动Service.
具体体现在源码里,会影响ServiceRecord的stopIfKilled属性.
// 掩码
public static final int START_CONTINUATION_MASK = 0xf;
// 进程被杀后,不保证一定调用onStartCommand方法
public static final int START_STICKY_COMPATIBILITY = 0;
// Service启动后若所在进程被杀,则服务保留started状态但intent不保留
// 等进程启动后会自动重建Service实例并调用onStartCommand, 且此时intent为null
// 一般适用于音乐播放器等后台长时间运行场景
public static final int START_STICKY = 1;
// Service启动后若所在进程被杀,则不会自动重建Service, 需要外部主动调用startService才会新建Service实例
// 适用场景:适用于当存在内存压力时允许所在进程被杀死,且有机制主动调用startService拉起服务的场景.
// 如通过Alarm机制每隔N分钟启动一次服务这种场景.
public static final int START_NOT_STICKY = 2;
// Service启动后若所在进程被杀,则等进程启动后Service会被重建且intent会被继续转发
// 除非手动调用stopService或intent为null
public static final int START_REDELIVER_INTENT = 3;
基于Android 10.0的源码剖析, 站在Luoshengyang/Innost/Gityuan肩膀上.
本文分析Activity销毁过程.
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java
frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/core/java/android/app/Instrumentation.java
frameworks/base/core/java/android/app/Activity.java
frameworks/base/core/java/android/app/FragmentController.java
TODO
[ -> frameworks/base/core/java/android/app/Activity.java ]
public void finish() {
// finish当前Activity,但不finish所在的Task
finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}
private void finish(int finishTask) {
if (mParent == null) { // 父Activity为空
int resultCode;
Intent resultData;
synchronized (this) {
resultCode = mResultCode;
resultData = mResultData;
}
if (resultData != null) {
resultData.prepareToLeaveProcess(this);
}
// 调用ATMS.finishActivity
if (ActivityTaskManager.getService().finishActivity(mToken, resultCode, resultData, finishTask)) {
mFinished = true;
}
} else { // 如果父Activity非空,直接finish整个Activity group
mParent.finishFromChild(this);
}
...
}
以下为finishTask:
// 当finish Activity时,其所在的Task不finish
public static final int DONT_FINISH_TASK_WITH_ACTIVITY = 0;
// 当finish root Activity时,其所在的Task也finish, 且Task从最近任务列表移除
public static final int FINISH_TASK_WITH_ROOT_ACTIVITY = 1;
// 当finish Activity时,其所在的Task也finish, 但Task不从最近任务列表移除
public static final int FINISH_TASK_WITH_ACTIVITY = 2;
[ -> frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java ]
@Override
public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, int finishTask) {
synchronized (mGlobalLock) {
// 获取当前ActivityRecord
ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r == null) {
return true;
}
// 获取当前task
final TaskRecord tr = r.getTaskRecord();
// 获取当前task的根Activity
ActivityRecord rootR = tr.getRootActivity();
...
boolean res;
// 若当前Activity为根Activity,判断是否finish根Activity所在的task
final boolean finishWithRootActivity = finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY || (finishWithRootActivity && r == rootR)) {
// finish当前task
res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity, "finish-activity");
} else {
// finish当前Activity
res = tr.getStack().requestFinishActivityLocked(token, resultCode, resultData, "app-request", true);
}
return res;
}
}
[ -> frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java ]
final boolean requestFinishActivityLocked(IBinder token, int resultCode, Intent resultData, String reason, boolean oomAdj) {
// 先根据token获取ActivityRecord,然后判断该ActivityRecord是否在其所属Task的Activity列表并返回.
ActivityRecord r = isInStackLocked(token);
if (r == null) {
return false;
}
finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
return true;
}
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData, String reason, boolean oomAdj) {
// pauseImmediately为false
return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
}
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
String reason, boolean oomAdj, boolean pauseImmediately) {
mWindowManager.deferSurfaceLayout();
try {
// 设置Activity的属性finishing=true
r.makeFinishingLocked();
// 获取当前task
final TaskRecord task = r.getTaskRecord();
// 获取当前task中所有Activity
final ArrayList<ActivityRecord> activities = task.mActivities;
// 获取当前Activity的索引
final int index = activities.indexOf(r);
if (index < (activities.size() - 1)) { // 如果当前不是最后一个Activity
task.setFrontOfTask();
if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
// If the caller asked that this activity (and all above it)
// be cleared when the task is reset, don't lose that information,
// but propagate it up to the next activity.
// 如果当前Activity的flags为FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
// 则将该flags传递给下一个Activity
ActivityRecord next = activities.get(index+1);
next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
}
}
// 暂停Key分发事件
r.pauseKeyDispatchingLocked();
// Move activity with its stack to front and make the stack focused
// 将当前Activity及其所在Task调整到最前面,使其focused
adjustFocusedActivityStack(r, "finishActivity");
// 创建ActivityResult, 并将其添加到启动当前Activity的那个Activity的ActivityResult列表results
// 见【第4.3节】
finishActivityResultsLocked(r, resultCode, resultData);
// 判断是否清除当前task: 当前Activity位于栈底且Task不复用时,则结束Task
final boolean endTask = index <= 0 && !task.isClearingToReuseTask();
// 设置转换模式
final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
if (mResumedActivity == r) { // 当前Activity为Resumed状态
if (endTask) {
// 通知listeners当前Task即将被移除
mService.getTaskChangeNotificationController().notifyTaskRemovalStarted(task.getTaskInfo());
}
getDisplay().mDisplayContent.prepareAppTransition(transit, false);
// 设置Activity不可见,告诉WindowManager当前Activity即将被移除
r.setVisibility(false);
if (mPausingActivity == null) {
// 执行pause操作. 见【第4.5节】
startPausingLocked(false, false, null, pauseImmediately);
}
if (endTask) {
// 清除当前Task
mService.getLockTaskController().clearLockedTask(task);
}
} else if (!r.isState(PAUSING)) { // 当前Activity非Pausing状态
// If the activity is PAUSING, we will complete the finish once
// it is done pausing; else we can just directly finish it here.
if (r.visible) {
// 设置Activity为不可见
prepareActivityHideTransitionAnimation(r, transit);
}
// 设置finishMode
final int finishMode = (r.visible || r.nowVisible) ? FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE;
// finish当前Activity
final boolean removedActivity = finishCurrentActivityLocked(r, finishMode, oomAdj, "finishActivityLocked") == null;
// The following code is an optimization. When the last non-task overlay activity
// is removed from the task, we remove the entire task from the stack. However,
// since that is done after the scheduled destroy callback from the activity, that
// call to change the visibility of the task overlay activities would be out of
// sync with the activitiy visibility being set for this finishing activity above.
// In this case, we can set the visibility of all the task overlay activities when
// we detect the last one is finishing to keep them in sync.
if (task.onlyHasTaskOverlayActivities(true /* excludeFinishing */)) {
for (ActivityRecord taskOverlay : task.mActivities) {
if (!taskOverlay.mTaskOverlay) {
continue;
}
prepareActivityHideTransitionAnimation(taskOverlay, transit);
}
}
return removedActivity;
}
return false;
} finally {
mWindowManager.continueSurfaceLayout();
}
}
private void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
// resultTo为startActivity时启动当前Activity的那个Activity(当前Activity的结果发给这个Activity)
ActivityRecord resultTo = r.resultTo;
if (resultTo != null) {
if (resultTo.mUserId != r.mUserId) {
if (resultData != null) {
resultData.prepareToLeaveUser(r.mUserId);
}
}
if (r.info.applicationInfo.uid > 0) {
// 授予Uri权限
mService.mUgmInternal.grantUriPermissionFromIntent(r.info.applicationInfo.uid,
resultTo.packageName, resultData,
resultTo.getUriPermissionsLocked(), resultTo.mUserId);
}
// 创建ActivityResult, 并添加到resultTo的ActivityResult列表results. 见【第4.4节】
resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode, resultData);
r.resultTo = null;
}
// 当前Activity属性置空
r.results = null;
r.pendingResults = null;
r.newIntents = null;
r.icicle = null;
}
[ -> frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java ]
void addResultLocked(ActivityRecord from, String resultWho,
int requestCode, int resultCode, Intent resultData) {
ActivityResult r = new ActivityResult(from, resultWho,
requestCode, resultCode, resultData);
if (results == null) {
results = new ArrayList<ResultInfo>();
}
results.add(r);
}
// resuming参数含义:
// The activity we are currently trying to resume or null if this is not being called as part
// of resuming the top activity, so we shouldn't try to instigate a resume here if not null.
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
// 如果当前有pausing状态的Activity(即mPausingActivity非空), 则完成Pause过程
if (mPausingActivity != null) {
if (!shouldSleepActivities()) {
completePauseLocked(false, resuming);
}
}
ActivityRecord prev = mResumedActivity;
// Trying to pause when nothing is resumed
// 我理解这段代码含义: 当前没有resume状态的Activity, 说明这是一个resume过程
// 因此resume top activity, 然后直接return false. 正常的Pause走不到这里
if (prev == null && resuming == null) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
return false;
}
// Trying to pause activity that is in process of being resumed
if (prev == resuming) {
return false;
}
// 将之前Resumed Activity设置为当前Paused Activity
mPausingActivity = prev;
mLastPausedActivity = prev;
mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
// 设置Activity状态为Pausing
prev.setState(PAUSING, "startPausingLocked");
...
if (prev.attachedToProcess()) { // 进程非空
// 执行PauseActivityItem事务
mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} else { // 进程为空
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
// If we are not going to sleep, we want to ensure the device is
// awake until the next activity is started.
if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
mStackSupervisor.acquireLaunchWakelock();
}
if (mPausingActivity != null) {
// Have the window manager pause its key dispatching until the new
// activity has started. If we're pausing the activity just because
// the screen is being turned off and the UI is sleeping, don't interrupt
// key dispatch; the same activity will pick it up again on wakeup.
if (!uiSleeping) {
prev.pauseKeyDispatchingLocked();
}
if (pauseImmediately) { // 立即pause
// If the caller said they don't want to wait for the pause, then complete the pause now.
completePauseLocked(false, resuming);
return false;
} else { // 500ms延时再pause
schedulePauseTimeout(prev);
return true;
}
} else { // Pause失败
// This activity failed to schedule the pause, so just treat it as being paused now.
if (resuming == null) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
return false;
}
}
[ -> frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java ]
public class PauseActivityItem extends ActivityLifecycleItem {
@Override
public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
// 参考【第7.1节】
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions, "PAUSE_ACTIVITY_ITEM");
}
@Override
public int getTargetState() {
return ON_PAUSE;
}
@Override
public void postExecute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
ActivityTaskManager.getService().activityPaused(token);
}
}
handlePauseActivity. 参考【第7.1节】
ActivityTaskManager.getService().activityPaused(token);
[ -> frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java ]
@Override
public final void activityPaused(IBinder token) {
synchronized (mGlobalLock) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
}
[ -> frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java ]
final void activityPausedLocked(IBinder token, boolean timeout) {
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) { // 继续完成pause操作
completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
return;
} else {
if (r.isState(PAUSING)) { // pause失败的Activity,直接finish掉
r.setState(PAUSED, "activityPausedLocked");
if (r.finishing) {
finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false, "activityPausedLocked");
}
}
}
}
mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
}
private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;
if (prev != null) {
prev.setWillCloseOrEnterPip(false);
// wasStopping为false
final boolean wasStopping = prev.isState(STOPPING);
// 设置Activity状态为PAUSED
prev.setState(PAUSED, "completePausedLocked");
if (prev.finishing) { // 会走到这里
// finish Activity
prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false, "completePausedLocked");
} else if (prev.hasProcess()) {
if (prev.deferRelaunchUntilPaused) { // Re-launching after pause
// Complete the deferred relaunch that was waiting for pause to complete.
prev.relaunchActivityLocked(false /* andResume */, prev.preserveWindowOnDeferredRelaunch);
} else if (wasStopping) {
// We are also stopping, the stop request must have gone soon after the pause.
// We can't clobber it, because the stop confirmation will not be handled.
// We don't need to schedule another stop, we only need to let it happen.
prev.setState(STOPPING, "completePausedLocked");
} else if (!prev.visible || shouldSleepOrShutDownActivities()) {
// Clear out any deferred client hide we might currently have.
prev.setDeferHidingClient(false);
// If we were visible then resumeTopActivities will release resources before
// stopping.
addToStopping(prev, true /* scheduleIdle */, false /* idleDelayed */, "completePauseLocked");
}
} else { // App died during pause, not stopping
prev = null;
}
// It is possible the activity was freezing the screen before it was paused.
// In that case go ahead and remove the freeze this activity has on the screen
// since it is no longer visible.
if (prev != null) {
prev.stopFreezingScreenLocked(true /*force*/);
}
mPausingActivity = null;
}
if (resumeNext) { // 是否恢复下一个Activity
final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
if (!topStack.shouldSleepOrShutDownActivities()) {
// 如果没有 休眠和关机时,恢复顶层Activity
mRootActivityContainer.resumeFocusedStacksTopActivities(topStack, prev, null);
} else {
// 等待休眠完成,再恢复顶层Activity
checkReadyForSleep();
ActivityRecord top = topStack.topRunningActivityLocked();
if (top == null || (prev != null && top != prev)) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
}
}
if (prev != null) {
// 恢复Activity的Key事件分发
prev.resumeKeyDispatchingLocked();
// 更新进程在前台运行的时间
if (prev.hasProcess() && prev.cpuTimeAtResume > 0) {
final long diff = prev.app.getCpuTime() - prev.cpuTimeAtResume;
if (diff > 0) {
final Runnable r = PooledLambda.obtainRunnable(
ActivityManagerInternal::updateForegroundTimeIfOnBattery,
mService.mAmInternal, prev.info.packageName,
prev.info.applicationInfo.uid,
diff);
mService.mH.post(r);
}
}
// 重置resume时间
prev.cpuTimeAtResume = 0; // reset it
}
// 通知Task栈发生变化
if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause || (getDisplay() != null && getDisplay().hasPinnedStack())) {
mService.getTaskChangeNotificationController().notifyTaskStackChanged();
mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
}
mRootActivityContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
}
final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj, String reason) {
// First things first: if this activity is currently visible,
// and the resumed activity is not yet visible, then hold off on
// finishing until the resumed one becomes visible.
// The activity that we are finishing may be over the lock screen. In this case, we do not
// want to consider activities that cannot be shown on the lock screen as running and should
// proceed with finishing the activity if there is no valid next top running activity.
// Note that if this finishing activity is floating task, we don't need to wait the
// next activity resume and can destroy it directly.
final ActivityDisplay display = getDisplay();
// 获取下一个Activity
final ActivityRecord next = display.topRunningActivity(true /* considerKeyguardState */);
final boolean isFloating = r.getConfiguration().windowConfiguration.tasksAreFloating();
// 如果mode为FINISH_AFTER_VISIBLE且下一个Activity不可见(默认即为此),
// 则先将当前Activity添加到stopping列表,并将其状态设置为STOPPING
// 等下一个Activity可见后再finish当前Activity
if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
&& next != null && !next.nowVisible && !isFloating) {
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
// 添加到stopping列表. 参考【第5.4.4节】
addToStopping(r, false /* scheduleIdle */, false /* idleDelayed */, "finishCurrentActivityLocked");
}
// Activity状态设置为STOPPING
r.setState(STOPPING, "finishCurrentActivityLocked");
if (oomAdj) {
mService.updateOomAdj();
}
return r;
}
// make sure the record is cleaned out of other places.
mStackSupervisor.mStoppingActivities.remove(r);
mStackSupervisor.mGoingToSleepActivities.remove(r);
// 获取当前状态
final ActivityState prevState = r.getState();
// Activity状态设置为FINISHING
r.setState(FINISHING, "finishCurrentActivityLocked");
// Don't destroy activity immediately if the display contains home stack, although there is
// no next activity at the moment but another home activity should be started later. Keep
// this activity alive until next home activity is resumed then user won't see a temporary
// black screen.
// 如果没有要显示的下一个Activity且当前显示的栈中包含Home栈,则先等HomeActivity恢复之后再销毁当前Activity
// 这样做的目的是避免出现临时黑屏
final boolean noRunningStack = next == null && display.topRunningActivity() == null && display.getHomeStack() == null;
final boolean noFocusedStack = r.getActivityStack() != display.getFocusedStack();
final boolean finishingInNonFocusedStackOrNoRunning = mode == FINISH_AFTER_VISIBLE && prevState == PAUSED && (noFocusedStack || noRunningStack);
if (mode == FINISH_IMMEDIATELY
|| (prevState == PAUSED && (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))
|| finishingInNonFocusedStackOrNoRunning
|| prevState == STOPPING
|| prevState == STOPPED
|| prevState == ActivityState.INITIALIZING) { // 满足立即销毁的条件
// 设置finishing=true
r.makeFinishingLocked();
// 销毁当前Activity
boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm:" + reason);
if (finishingInNonFocusedStackOrNoRunning) {
// Finishing activity that was in paused state and it was in not currently focused
// stack, need to make something visible in its place. Also if the display does not
// have running activity, the configuration may need to be updated for restoring
// original orientation of the display.
mRootActivityContainer.ensureVisibilityAndConfig(next, mDisplayId, false /* markFrozenIfConfigChanged */, true /* deferResume */);
}
if (activityRemoved) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
return activityRemoved ? null : r;
}
// Need to go through the full pause cycle to get this
// activity into the stopped state and then finish it.
if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r);
mStackSupervisor.mFinishingActivities.add(r);
r.resumeKeyDispatchingLocked();
mRootActivityContainer.resumeFocusedStacksTopActivities();
// If activity was not paused at this point - explicitly pause it to start finishing
// process. Finishing will be completed once it reports pause back.
if (r.isState(RESUMED) && mPausingActivity != null) {
startPausingLocked(false /* userLeaving */, false /* uiSleeping */, next /* resuming */, false /* dontWait */);
}
return r;
}
以下为finishMode:
// 立刻finish当前Activity
static final int FINISH_IMMEDIATELY = 0;
// 当前Activity pause后finish
static final int FINISH_AFTER_PAUSE = 1;
// 下一个要显示的Activity可见后再finish当前Activity
static final int FINISH_AFTER_VISIBLE = 2;
一般面试会问的一个问题:
为啥A -> B进行Activity切换的时候,生命周期是: A.onPause -> B.onCreate -> B.onStart -> B.onResume -> A.onStop -> A.onDestroy. 而不是先A.onPause -> A.onStop -> A.onDestroy -> B.onCreate -> B.onStart -> B.onResume.
这段代码给出了解释:
First things first: if this activity is currently visible, and the resumed activity is not yet visible,
then hold off on finishing until the resumed one becomes visible.
The activity that we are finishing may be over the lock screen. In this case, we do not
want to consider activities that cannot be shown on the lock screen as running and should
proceed with finishing the activity if there is no valid next top running activity.
Note that if this finishing activity is floating task, we don’t need to wait the
next activity resume and can destroy it directly.
Don’t destroy activity immediately if the display contains home stack, although there is
no next activity at the moment but another home activity should be started later. Keep
this activity alive until next home activity is resumed then user won’t see a temporary black screen.
private void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed,
String reason) {
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
// 将当前Activity添加到stopping列表
mStackSupervisor.mStoppingActivities.add(r);
}
// If we already have a few activities waiting to stop, then give up
// on things going idle and start clearing them out. Or if r is the
// last of activity of the last task the stack will be empty and must
// be cleared immediately.
// 如果stopping列表超出最大值,或者当前Activity为所在Task的根Activity且任务历史列表只剩这一个Task
// 则先保持idle,暂时不做什么
boolean forceIdle = mStackSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE
|| (r.frontOfTask && mTaskHistory.size() <= 1);
if (scheduleIdle || forceIdle) {
if (!idleDelayed) {
mStackSupervisor.scheduleIdleLocked();
} else {
mStackSupervisor.scheduleIdleTimeoutLocked(r);
}
} else { // sleep
checkReadyForSleep();
}
}
void checkReadyForSleep() {
if (shouldSleepActivities() && goToSleepIfPossible(false /* shuttingDown */)) {
mStackSupervisor.checkReadyForSleepLocked(true /* allowDelay */);
}
}
boolean goToSleepIfPossible(boolean shuttingDown) {
boolean shouldSleep = true;
if (mResumedActivity != null) {
// Still have something resumed; can't sleep until it is paused.
startPausingLocked(false, true, null, false);
shouldSleep = false ;
} else if (mPausingActivity != null) {
// Still waiting for something to pause; can't sleep yet.
shouldSleep = false;
}
if (!shuttingDown) {
// 如果包含要stopping的Activity,则先做stop操作
if (containsActivityFromStack(mStackSupervisor.mStoppingActivities)) {
// Still need to tell some activities to stop; can't sleep yet.
mStackSupervisor.scheduleIdleLocked();
shouldSleep = false;
}
if (containsActivityFromStack(mStackSupervisor.mGoingToSleepActivities)) {
// Still need to tell some activities to sleep; can't sleep yet.
shouldSleep = false;
}
}
if (shouldSleep) {
goToSleep();
}
return shouldSleep;
}
final void scheduleIdleLocked() {
mHandler.sendEmptyMessage(IDLE_NOW_MSG);
}
private final class ActivityStackSupervisorHandler extends Handler {
public ActivityStackSupervisorHandler(Looper looper) {
super(looper);
}
void activityIdleInternal(ActivityRecord r, boolean processPausingActivities) {
synchronized (mService.mGlobalLock) {
activityIdleInternalLocked(r != null ? r.appToken : null, true /* fromTimeout */,
processPausingActivities, null);
}
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
...
case IDLE_TIMEOUT_MSG: {
// We don't at this point know if the activity is fullscreen,
// so we need to be conservative and assume it isn't.
activityIdleInternal((ActivityRecord) msg.obj,
true /* processPausingActivities */);
} break;
case IDLE_NOW_MSG: {
activityIdleInternal((ActivityRecord) msg.obj,
false /* processPausingActivities */);
} break;
...
}
}
TODO:
这里比较复杂,我的理解是:
这里有个线程机制,当线程空闲时会执行stopping Activity操作,最终又会走到ActivityStack#finishCurrentActivityLocked
参考【第5.4.3节】 之后在执行这段代码过程中又会执行到destroyActivityLocked
final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, String reason) {
if (r.isState(DESTROYING, DESTROYED)) {
return false;
}
boolean removedFromHistory = false;
cleanUpActivityLocked(r, false, false);
final boolean hadApp = r.hasProcess();
if (hadApp) {
if (removeFromApp) {
r.app.removeActivity(r);
if (!r.app.hasActivities()) {
mService.clearHeavyWeightProcessIfEquals(r.app);
}
if (!r.app.hasActivities()) {
// Update any services we are bound to that might care about whether
// their client may have activities.
// No longer have activities, so update LRU list and oom adj.
r.app.updateProcessInfo(true /* updateServiceConnectionActivities */,
false /* activityChange */, true /* updateOomAdj */);
}
}
boolean skipDestroy = false;
// 将最终状态设置为DestroyActivityItem, 并执行ON_PAUSE~ON_DESTROY的过程
mService.getLifecycleManager().scheduleTransaction(r.app.getThread(), r.appToken,
DestroyActivityItem.obtain(r.finishing, r.configChangeFlags));
r.nowVisible = false;
// If the activity is finishing, we need to wait on removing it
// from the list to give it a chance to do its cleanup. During
// that time it may make calls back with its token so we need to
// be able to find it on the list and so we don't want to remove
// it from the list yet. Otherwise, we can just immediately put
// it in the destroyed state since we are not removing it from the
// list.
if (r.finishing && !skipDestroy) {
// Activity状态设置为DESTROYING
r.setState(DESTROYING, "destroyActivityLocked. finishing and not skipping destroy");
Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r);
mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
} else {
r.setState(DESTROYED, "destroyActivityLocked. not finishing or skipping destroy");
r.app = null;
}
} else {
// remove this record from the history.
if (r.finishing) {
removeActivityFromHistoryLocked(r, reason + " hadNoApp");
removedFromHistory = true;
} else {
r.setState(DESTROYED, "destroyActivityLocked. not finishing and had no app");
r.app = null;
}
}
r.configChangeFlags = 0;
return removedFromHistory;
}
接下来就是执行Stop和Destroy过程了.
[ -> frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java ]
private void performLifecycleSequence(ActivityClientRecord r, IntArray path, ClientTransaction transaction) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
switch (state) {
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(r, mPendingActions, null /* customIntent */);
break;
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */, r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
// 参考【第7.1节】
mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
false /* userLeaving */, 0 /* configChanges */, mPendingActions, "LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
// 参考【第7.2节】
mTransactionHandler.handleStopActivity(r.token, false /* show */,
0 /* configChanges */, mPendingActions, false /* finalStateRequest */, "LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
// 参考【第7.3节】
mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
0 /* configChanges */, false /* getNonConfigInstance */, "performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(r.token, false /* start */);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
}
[ -> frameworks/base/core/java/android/app/ActivityThread.java ]
@Override
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
int configChanges, PendingTransactionActions pendingActions, String reason) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(r, finished, reason, pendingActions);
// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
mSomeActivitiesChanged = true;
}
}
private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason, PendingTransactionActions pendingActions) {
...
if (finished) {
r.activity.mFinished = true;
}
final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
if (shouldSaveState) {
// Android API版本<11, 在onPause之前先调用Activity.OnSaveInstanceState
callActivityOnSaveInstanceState(r);
}
performPauseActivityIfNeeded(r, reason);
// 通知外部注册的listeners
ArrayList<OnActivityPausedListener> listeners;
synchronized (mOnPauseListeners) {
listeners = mOnPauseListeners.remove(r.activity);
}
int size = (listeners != null ? listeners.size() : 0);
for (int i = 0; i < size; i++) {
listeners.get(i).onPaused(r.activity);
}
final Bundle oldState = pendingActions != null ? pendingActions.getOldState() : null;
if (oldState != null) {
// We need to keep around the original state, in case we need to be created again.
// But we only do this for pre-Honeycomb apps, which always save their state when
// pausing, so we can not have them save their state when restarting from a paused
// state. For HC and later, we want to (and can) let the state be saved as the
// normal part of stopping the activity.
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
return shouldSaveState ? r.state : null;
}
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
if (r.paused) {
// You are already paused silly...
return;
}
// Always reporting top resumed position loss when pausing an activity. If necessary, it
// will be restored in performResumeActivity().
reportTopResumedActivityChanged(r, false /* onTop */, "pausing");
r.activity.mCalled = false;
// 参考【第8.1节】
mInstrumentation.callActivityOnPause(r.activity);
// 设置ActivityClientRecord状态为ON_PAUSE
r.setState(ON_PAUSE);
}
@Override
public void handleStopActivity(IBinder token, boolean show, int configChanges,
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
// 获取当前Activity
final ActivityClientRecord r = mActivities.get(token);
r.activity.mConfigChangeFlags |= configChanges;
final StopInfo stopInfo = new StopInfo();
// 执行stop操作. 参考【第7.2.1节】
performStopActivityInner(r, stopInfo, show, true /* saveState */, finalStateRequest, reason);
// 设置当前Activity的mDecor可见性为INVISIBLE
updateVisibility(r, show);
// Make sure any pending writes are now committed.
if (!r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
// 设置和保存stopInfo
stopInfo.setActivity(r);
stopInfo.setState(r.state);
stopInfo.setPersistentState(r.persistentState);
pendingActions.setStopInfo(stopInfo);
mSomeActivitiesChanged = true;
}
private void performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean keepShown, boolean saveState, boolean finalStateRequest, String reason) {
if (r != null) {
...
// 先确保已经pause了
performPauseActivityIfNeeded(r, reason);
if (!keepShown) {
// 调用Activity.OnStop
callActivityOnStop(r, saveState, reason);
}
}
}
private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) {
// Before P onSaveInstanceState was called before onStop, starting with P it's
// called after. Before Honeycomb state was always saved before onPause.
final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null && !r.isPreHoneycomb();
final boolean isPreP = r.isPreP();
if (shouldSaveState && isPreP) {
// Android P以前版本, 调用Activity.OnSaveInstanceState
callActivityOnSaveInstanceState(r);
}
// 执行stop操作. 参考【第9.2节】
r.activity.performStop(r.mPreserveWindow, reason);
// 设置ActivityClientRecord状态为ON_STOP
r.setState(ON_STOP);
if (shouldSaveState && !isPreP) {
// Android P及以后版本, 调用Activity.OnSaveInstanceState
callActivityOnSaveInstanceState(r);
}
}
@Override
public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
boolean getNonConfigInstance, String reason) {
ActivityClientRecord r = performDestroyActivity(token, finishing,
configChanges, getNonConfigInstance, reason);
if (r != null) {
// 清除Window列表
cleanUpPendingRemoveWindows(r, finishing);
WindowManager wm = r.activity.getWindowManager();
View v = r.activity.mDecor;
if (v != null) {
if (r.activity.mVisibleFromServer) {
// 可见Activity数减1
mNumVisibleActivities--;
}
IBinder wtoken = v.getWindowToken();
if (r.activity.mWindowAdded) {
if (r.mPreserveWindow) {
// 保存当前Window,直到新启动的Activity的Window added
r.mPendingRemoveWindow = r.window;
r.mPendingRemoveWindowManager = wm;
// 清除ContentView
r.window.clearContentView();
} else {
// 清除View
wm.removeViewImmediate(v);
}
}
// 清除View
if (wtoken != null && r.mPendingRemoveWindow == null) {
WindowManagerGlobal.getInstance().closeAll(wtoken,
r.activity.getClass().getName(), "Activity");
} else if (r.mPendingRemoveWindow != null) {
WindowManagerGlobal.getInstance().closeAllExceptView(token, v,
r.activity.getClass().getName(), "Activity");
}
// DecorView置空
r.activity.mDecor = null;
}
if (r.mPendingRemoveWindow == null) {
WindowManagerGlobal.getInstance().closeAll(token,
r.activity.getClass().getName(), "Activity");
}
Context c = r.activity.getBaseContext();
if (c instanceof ContextImpl) {
((ContextImpl) c).scheduleFinalCleanup(
r.activity.getClass().getName(), "Activity");
}
}
if (finishing) {
ActivityTaskManager.getService().activityDestroyed(token);
}
mSomeActivitiesChanged = true;
}
ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance, String reason) {
ActivityClientRecord r = mActivities.get(token);
Class<? extends Activity> activityClass = null;
if (r != null) {
activityClass = r.activity.getClass();
r.activity.mConfigChangeFlags |= configChanges;
if (finishing) {
r.activity.mFinished = true;
}
// 先确保已经Pause了
performPauseActivityIfNeeded(r, "destroy");
if (!r.stopped) {
// 如果没有stop,先调用Activity.onStop
callActivityOnStop(r, false /* saveState */, "destroy");
}
if (getNonConfigInstance) {
r.lastNonConfigurationInstances = r.activity.retainNonConfigurationInstances();
}
r.activity.mCalled = false;
// 参考【第8.3节】
mInstrumentation.callActivityOnDestroy(r.activity);
if (r.window != null) {
r.window.closeAllPanels();
}
r.setState(ON_DESTROY);
}
schedulePurgeIdler();
synchronized (mResourcesManager) {
// 移除token
mActivities.remove(token);
}
StrictMode.decrementExpectedActivityCount(activityClass);
return r;
}
@Override
public final void activityDestroyed(IBinder token) {
synchronized (mGlobalLock) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityDestroyedLocked(token, "activityDestroyed");
}
}
}
final void activityDestroyedLocked(IBinder token, String reason) {
final long origId = Binder.clearCallingIdentity();
try {
activityDestroyedLocked(ActivityRecord.forTokenLocked(token), reason);
} finally {
Binder.restoreCallingIdentity(origId);
}
}
final void activityDestroyedLocked(ActivityRecord record, String reason) {
if (record != null) {
mHandler.removeMessages(DESTROY_TIMEOUT_MSG, record);
}
// 从栈中清除Activity
if (isInStackLocked(record) != null) {
if (record.isState(DESTROYING, DESTROYED)) {
cleanUpActivityLocked(record, true, false);
removeActivityFromHistoryLocked(record, reason);
}
}
// resume栈中位于顶部的Activity
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
[ -> frameworks/base/core/java/android/app/Instrumentation.java ]
public void callActivityOnPause(Activity activity) {
// 参考【第9.1节】
activity.performPause();
}
public void callActivityOnStop(Activity activity) {
// 参考【第9.2节】
activity.onStop();
}
public void callActivityOnDestroy(Activity activity) {
// 参考【第9.3节】
activity.performDestroy();
}
[ -> frameworks/base/core/java/android/app/Activity.java ]
final void performPause() {
dispatchActivityPrePaused();
mFragments.dispatchPause();
mCalled = false;
onPause();
mResumed = false;
dispatchActivityPostPaused();
}
private void dispatchActivityPrePaused() {
getApplication().dispatchActivityPrePaused(this);
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = callbacks.length - 1; i >= 0; i--) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPrePaused(this);
}
}
}
参考【第10节】
protected void onPause() {
dispatchActivityPaused();
...
mCalled = true;
}
private void dispatchActivityPaused() {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = callbacks.length - 1; i >= 0; i--) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPaused(this);
}
}
getApplication().dispatchActivityPaused(this);
}
private void dispatchActivityPostPaused() {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = callbacks.length - 1; i >= 0; i--) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPostPaused(this);
}
}
getApplication().dispatchActivityPostPaused(this);
}
final void performStop(boolean preserveWindow, String reason) {
...
if (!mStopped) {
dispatchActivityPreStopped();
if (mWindow != null) {
mWindow.closeAllPanels();
}
...
mFragments.dispatchStop();
mCalled = false;
mInstrumentation.callActivityOnStop(this);
...
mStopped = true;
dispatchActivityPostStopped();
}
mResumed = false;
}
private void dispatchActivityPreStopped() {
getApplication().dispatchActivityPreStopped(this);
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = callbacks.length - 1; i >= 0; i--) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPreStopped(this);
}
}
}
参考【第10节】
参考【第8.2节】
private void dispatchActivityPostStopped() {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = callbacks.length - 1; i >= 0; i--) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPostStopped(this);
}
}
getApplication().dispatchActivityPostStopped(this);
}
final void performDestroy() {
dispatchActivityPreDestroyed();
mDestroyed = true;
mWindow.destroy();
mFragments.dispatchDestroy();
onDestroy();
...
dispatchActivityPostDestroyed();
}
private void dispatchActivityPreDestroyed() {
getApplication().dispatchActivityPreDestroyed(this);
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = callbacks.length - 1; i >= 0; i--) {
((Application.ActivityLifecycleCallbacks) callbacks[i])
.onActivityPreDestroyed(this);
}
}
}
参考【第10节】
protected void onDestroy() {
mCalled = true;
// dismiss any dialogs we are managing.
if (mManagedDialogs != null) {
final int numDialogs = mManagedDialogs.size();
for (int i = 0; i < numDialogs; i++) {
final ManagedDialog md = mManagedDialogs.valueAt(i);
if (md.mDialog.isShowing()) {
md.mDialog.dismiss();
}
}
mManagedDialogs = null;
}
// close any cursors we are managing.
synchronized (mManagedCursors) {
int numCursors = mManagedCursors.size();
for (int i = 0; i < numCursors; i++) {
ManagedCursor c = mManagedCursors.get(i);
if (c != null) {
c.mCursor.close();
}
}
mManagedCursors.clear();
}
// Close any open search dialog
if (mSearchManager != null) {
mSearchManager.stopSearch();
}
if (mActionBar != null) {
mActionBar.onDestroy();
}
dispatchActivityDestroyed();
...
}
private void dispatchActivityDestroyed() {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = callbacks.length - 1; i >= 0; i--) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityDestroyed(this);
}
}
getApplication().dispatchActivityDestroyed(this);
}
private void dispatchActivityPostDestroyed() {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = callbacks.length - 1; i >= 0; i--) {
((Application.ActivityLifecycleCallbacks) callbacks[i])
.onActivityPostDestroyed(this);
}
}
getApplication().dispatchActivityPostDestroyed(this);
}
[ -> frameworks/base/core/java/android/app/FragmentController.java ]
public void dispatchPause() {
mHost.mFragmentManager.dispatchPause();
}
public void dispatchStop() {
mHost.mFragmentManager.dispatchStop();
}
public void dispatchDestroyView() {
mHost.mFragmentManager.dispatchDestroyView();
}
public void dispatchDestroy() {
mHost.mFragmentManager.dispatchDestroy();
}
[ -> frameworks/base/core/java/android/app/FragmentManager.java ]
public void dispatchPause() {
dispatchMoveToState(Fragment.STARTED);
}
public void dispatchStop() {
dispatchMoveToState(Fragment.STOPPED);
}
public void dispatchDestroyView() {
dispatchMoveToState(Fragment.CREATED);
}
public void dispatchDestroy() {
mDestroyed = true;
execPendingActions();
dispatchMoveToState(Fragment.INITIALIZING);
mHost = null;
mContainer = null;
mParent = null;
}
[ -> frameworks/base/core/java/android/app/Application.java ]
public interface ActivityLifecycleCallbacks {
default void onActivityPreCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
}
void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState);
default void onActivityPostCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
}
default void onActivityPreStarted(@NonNull Activity activity) {
}
void onActivityStarted(@NonNull Activity activity);
default void onActivityPostStarted(@NonNull Activity activity) {
}
default void onActivityPreResumed(@NonNull Activity activity) {
}
void onActivityResumed(@NonNull Activity activity);
default void onActivityPostResumed(@NonNull Activity activity) {
}
default void onActivityPrePaused(@NonNull Activity activity) {
}
void onActivityPaused(@NonNull Activity activity);
default void onActivityPostPaused(@NonNull Activity activity) {
}
default void onActivityPreStopped(@NonNull Activity activity) {
}
void onActivityStopped(@NonNull Activity activity);
default void onActivityPostStopped(@NonNull Activity activity) {
}
default void onActivityPreSaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
}
void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState);
default void onActivityPostSaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
}
default void onActivityPreDestroyed(@NonNull Activity activity) {
}
void onActivityDestroyed(@NonNull Activity activity);
default void onActivityPostDestroyed(@NonNull Activity activity) {
}
}
[ -> frameworks/base/core/java/android/app/servertransaction/ActivityLifecycleItem.java ]
public abstract class ActivityLifecycleItem extends ClientTransactionItem {
public static final int UNDEFINED = -1;
public static final int PRE_ON_CREATE = 0;
public static final int ON_CREATE = 1;
public static final int ON_START = 2;
public static final int ON_RESUME = 3;
public static final int ON_PAUSE = 4;
public static final int ON_STOP = 5;
public static final int ON_DESTROY = 6;
public static final int ON_RESTART = 7;
}
基于Android 10.0的源码剖析, 站在Luoshengyang/Innost/Gityuan肩膀上.
Activity之间的启动分为不同进程间
和相同进程
的启动.
由于进程间Activity启动流程包括了相同进程间Activity启动的流程. 因此本文只分析不同进程间, 即点击Launcher桌面图标启动Activity的这整个过程.
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
packages/apps/Launcher3/src/com/android/launcher3/touch/ItemClickHandler.java
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
frameworks/base/services/core/java/com/android/server/wm/ActivityDisplay.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
frameworks/base/core/java/android/app/Activity.java
frameworks/base/core/java/android/app/Instrumentation.java
frameworks/base/core/java/android/app/ActivityTaskManager.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/core/java/android/app/AppComponentFactory.java
frameworks/base/core/java/android/app/FragmentController.java
frameworks/base/core/java/android/app/ClientTransactionHandler.java
frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
frameworks/base/core/java/android/app/servertransaction/TransactionExecutorHelper.java
frameworks/base/core/java/android/app/servertransaction/ActivityLifecycleItem.java
frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
TODO
[ -> packages/apps/Launcher3/src/com/android/launcher3/Launcher.java ]
public class Launcher extends BaseDraggingActivity implements LauncherExterns,
LauncherModel.Callbacks, LauncherProviderChangeListener, UserEventDelegate,
InvariantDeviceProfile.OnIDPChangeListener {
...
public View createShortcut(ViewGroup parent, WorkspaceItemInfo info) {
BubbleTextView favorite = (BubbleTextView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.app_icon, parent, false);
favorite.applyFromWorkspaceItem(info);
favorite.setOnClickListener(ItemClickHandler.INSTANCE);
favorite.setOnFocusChangeListener(mFocusHandler);
return favorite;
}
}
[ -> packages/apps/Launcher3/src/com/android/launcher3/touch/ItemClickHandler.java ]
public class ItemClickHandler {
public static final OnClickListener INSTANCE = getInstance(null);
public static final OnClickListener getInstance(String sourceContainer) {
return v -> onClick(v, sourceContainer);
}
private static void onClick(View v, String sourceContainer) {
Launcher launcher = Launcher.getLauncher(v.getContext());
Object tag = v.getTag();
if (tag instanceof WorkspaceItemInfo) {
onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher, sourceContainer);
} else if (tag instanceof FolderInfo) {
...
} else if (tag instanceof AppInfo) {
...
} else if (tag instanceof LauncherAppWidgetInfo) {
...
}
}
public static void onClickAppShortcut(View v, WorkspaceItemInfo shortcut,
Launcher launcher, @Nullable String sourceContainer) {
startAppShortcutOrInfoActivity(v, shortcut, launcher, sourceContainer);
}
private static void startAppShortcutOrInfoActivity(View v, ItemInfo item,
Launcher launcher, @Nullable String sourceContainer) {
Intent intent = item.getIntent();
launcher.startActivitySafely(v, intent, item, sourceContainer);
}
}
public boolean startActivitySafely(View v, Intent intent, ItemInfo item, @Nullable String sourceContainer) {
boolean success = super.startActivitySafely(v, intent, item, sourceContainer);
return success;
}
public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item, @Nullable String sourceContainer) {
...
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
...
if (isShortcut) {
startShortcutIntentSafely(intent, optsBundle, item, sourceContainer);
} else if (user == null || user.equals(Process.myUserHandle())) {
startActivity(intent, optsBundle);
} else {
LauncherAppsCompat.getInstance(this).startActivityForProfile(
intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
}
return true;
} catch (ActivityNotFoundException|SecurityException e) {
...
}
return false;
}
[ -> frameworks/base/core/java/android/app/Activity.java ]
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
// 执行启动Activity,见【第4.1节】
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
if (ar != null) {
// 发送启动结果,见【第28节】
mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
} else {
...
}
}
[ -> frameworks/base/core/java/android/app/Instrumentation.java ]
Instrumentation#execStartActivity
(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options)
各参数含义:
代码实现如下:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
// 遍历ActivityMonitor列表,匹配ActivityResult
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
ActivityResult result = null;
// 如果ignoreMatchingSpecificIntents为true
if (am.ignoreMatchingSpecificIntents()) {
// 返空
result = am.onStartActivity(intent);
}
if (result != null) { // 命中结果,直接返回结果
am.mHits++;
return result;
} else if (am.match(who, null, intent)) {
am.mHits++;
// 当ActivityMonitor阻塞Activity启动时,直接返回结果
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
// 否则跳出循环,走后面startActivity流程
break;
}
}
}
}
// ActivityTaskManagerService.startActivity
int result = ActivityTaskManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),token,
target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
// 检查result, 判断Activity是否启动成功.
checkStartActivityResult(result, intent);
return null;
}
[ -> frameworks/base/core/java/android/app/ActivityTaskManager.java ]
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
// 拿到BinderProxy对象
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
// 拿到new IActivityTaskManager.Stub.Proxy(new BinderProxy(handle))对象
return IActivityTaskManager.Stub.asInterface(b);
}
};
// 拿到new IActivityTaskManager.Stub.Proxy(new BinderProxy(handle))对象
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
上面代码的含义:
ActivityTaskManager.getService()得到IActivityTaskManager.Stub.Proxy对象
ActivityTaskManager.getService().startActivity()等价于IActivityTaskManager.Stub.Proxy.startActivity()
再根据AIDL分析过程可知,最终会走到ActivityTaskManagerService.startActivity()
至此ActivityTaskManager.getService()拿到服务的代理对象new IActivityTaskManager.Stub.Proxy(new BinderProxy(handle))
IActivityTaskManager.Stub.Proxy#startActivity通过AIDL最终调用到ActivityTaskManagerService#startActivity
[ -> frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java ]
ActivityTaskManagerService#startActivity
(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions)
各参数含义:
代码实现如下:
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho,
int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
// 指定启动Activity的userId
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
@Override
public int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho,
int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions,
int userId) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true /*validateIncomingUser*/);
}
int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho,
int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions,
int userId, boolean validateIncomingUser) {
// 确保调用进程不是isolated
enforceNotIsolatedCaller("startActivityAsUser");
// 检查userId的有效性, 并返回有效的userId
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// ActivityStartController#obtainStarter(),拿到ActivityStarter
// ActivityStarter#execute(),启动Activity
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId) // mRequest.mayWait = true
.execute();
}
[ -> frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java ]
int execute() {
try {
if (mRequest.mayWait) { // 需要等待请求返回结果
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
} else {
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
}
} finally {
// 执行完成
onExecutionComplete();
}
}
private int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
Intent intent, String resolvedType, IVoiceInteractionSession voiceSession,
IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
int userId, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
...
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
computeResolveFilterUid(callingUid, realCallingUid, mRequest.filterCallingUid));
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
...
final ActivityRecord[] outRecord = new ActivityRecord[1];
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
allowBackgroundActivityStart);
return res;
}
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
...
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid,startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
allowBackgroundActivityStart);
return getExternalResult(mLastStartActivityResult);
}
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options,
boolean ignoreTargetSecurity, boolean componentSpecified,ActivityRecord[] outActivity,
TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
...
// 下面这段代码是确定源Activity和目的Activity, 通常sourceRecord和resultRecord是同一个
// 源Activity, 启动Activity的那个Activity
ActivityRecord sourceRecord = null;
// 目的Activity, 将启动结果返回给它
ActivityRecord resultRecord = null;
// 根据启动Activity的页面token, 判断Activity Stack中是否有对应的源Activity
// 如果requestCode>=0且源Activity非空且非finish, 则目的Activity即为源Activity
if (resultTo != null) {
sourceRecord = mRootActivityContainer.isInAnyStack(resultTo);
if (sourceRecord != null) {
if (requestCode >= 0 && !sourceRecord.finishing) {
resultRecord = sourceRecord;
}
}
}
...
// 拦截器处理
if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid, checkedOptions)) {
...
}
// 创建ActivityRecord
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, checkedOptions, sourceRecord);
// 启动Activity
final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
return res;
}
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
int result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
postStartActivityProcessing(r, result, startedActivityStack);
return result;
}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
...
// 将要启动的Activity(即mStartActivity)添加到task里, 同时将该task移到task列表的最前面
// 这个task可能是新建的task, 也可能是启动Activity的当前Activity所在的task
int result = START_SUCCESS;
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
// 复用task或创建新的task
newTask = true;
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
} else if (mSourceRecord != null) {
// 从mSourceRecord中获取task
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
// 从mInTask中获取task
result = setTaskFromInTask();
} else {
// 从mHistoryTasks栈顶获取task或创建新的task
result = setTaskToCurrentTopOrCreateNewTask();
}
...
// 启动Activity的准备工作.见【第8.1节】
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition, mOptions);
if (mDoResume) { // resume操作, 此处为true
// 获取当前正在运行的位于栈顶的Activity
final ActivityRecord topTaskActivity = mStartActivity.getTaskRecord().topRunningActivityLocked();
if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) {
// 设置启动的Activity(即mStartActivity)可见, 并通知WindowManager更新
mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
} else {
// 若mTargetStack栈当前没有显示在最上层并获取焦点, 则先将mTargetStack移到栈顶
if (mTargetStack.isFocusable() && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
// resume mStartActivity. 见【第8.2节】
mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, mStartActivity, mOptions);
}
} else if (mStartActivity != null) {
// 将启动的Activity所在的task添加到最近任务列表mRecentTasks里
mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
}
return START_SUCCESS;
}
setTaskFromXXX主要做的事情就是:
(1) addOrReparentStartingActivity
将要启动的Activity添加到Task的Activity列表栈顶
(2) mTargetStack.moveToFront
将Task移动到任务列表最上面
各方法含义:
setTaskFromReuseOrCreateNewTask
复用mReuseTask或新建TaskRecordsetTaskFromSourceRecord
复用源Activity(mSourceRecord)所在的TasksetTaskFromInTask
复用mInTasksetTaskToCurrentTopOrCreateNewTask
新建TaskRecord具体代码如下:
private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
if (mReuseTask == null) {
final TaskRecord task = mTargetStack.createTaskRecord(
mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId),
mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
mVoiceInteractor, !mLaunchTaskBehind, mStartActivity, mSourceRecord,
mOptions);
addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask-mReuseTask");
} else {
addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
}
if (taskToAffiliate != null) {
mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
}
if (mDoResume) {
mTargetStack.moveToFront("reuseOrNewTask");
}
return START_SUCCESS;
}
private int setTaskFromSourceRecord() {
final TaskRecord sourceTask = mSourceRecord.getTaskRecord();
final ActivityStack sourceStack = mSourceRecord.getActivityStack();
if (mTargetStack == null) {
mTargetStack = sourceStack;
} else if (mTargetStack != sourceStack) {
sourceTask.reparent(mTargetStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE, DEFER_RESUME, "launchToSide");
}
final TaskRecord topTask = mTargetStack.topTask();
if (topTask != sourceTask && !mAvoidMoveToFront) {
mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "sourceTaskToFront");
} else if (mDoResume) {
mTargetStack.moveToFront("sourceStackToFront");
}
addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
return START_SUCCESS;
}
private int setTaskFromInTask() {
mTargetStack = mInTask.getStack();
...
mTargetStack.moveTaskToFrontLocked(mInTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "inTaskToFront");
addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
return START_SUCCESS;
}
private int setTaskToCurrentTopOrCreateNewTask() {
...
if (mDoResume) {
mTargetStack.moveToFront("addingToTopTask");
}
final ActivityRecord prev = mTargetStack.getTopActivity();
final TaskRecord task = (prev != null)
? prev.getTaskRecord() : mTargetStack.createTaskRecord(
mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId),
mStartActivity.info,
mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions);
addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
...
return START_SUCCESS;
}
[ -> frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java ]
void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity, boolean newTask, boolean keepCurTransition, ActivityOptions options) {
TaskRecord rTask = r.getTaskRecord();
final int taskId = rTask.taskId;
if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
// 将task添加到mTaskHistory任务列表栈顶
insertTaskAtTop(rTask, r);
}
TaskRecord task = null;
// 这段代码的含义: 如果是已有的task, 从mTaskHistory中查找目标task
// 并判断目标task中是否已经启动了Activity, 如果发现未启动则调用createAppWindowToken, 等待后续启动
if (!newTask) {
// If starting in an existing task, find where that is...
boolean startIt = true;
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
task = mTaskHistory.get(taskNdx);
if (task.getTopActivity() == null) {
// All activities in task are finishing.
continue;
}
if (task == rTask) {
// Here it is! Now, if this is not yet visible to the
// user, then just add it without starting; it will
// get started when the user navigates back to it.
if (!startIt) {
r.createAppWindowToken();
ActivityOptions.abort(options);
return;
}
break;
} else if (task.numFullscreen > 0) {
startIt = false;
}
}
}
final TaskRecord activityTask = r.getTaskRecord();
task = activityTask;
task.setFrontOfTask();
...
// 下面这段代码的含义: 做一些启动Activity的过渡工作, 比如动画之类的.
if (!isHomeOrRecentsStack() || numActivities() > 0) {
final DisplayContent dc = getDisplay().mDisplayContent;
if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
dc.prepareAppTransition(TRANSIT_NONE, keepCurTransition);
mStackSupervisor.mNoAnimActivities.add(r);
} else {
int transit = TRANSIT_ACTIVITY_OPEN;
if (newTask) {
if (r.mLaunchTaskBehind) {
transit = TRANSIT_TASK_OPEN_BEHIND;
} else {
if (canEnterPipOnTaskSwitch(focusedTopActivity, null, r, options)) {
focusedTopActivity.supportsEnterPipOnTaskSwitch = true;
}
transit = TRANSIT_TASK_OPEN;
}
}
dc.prepareAppTransition(transit, keepCurTransition);
mStackSupervisor.mNoAnimActivities.remove(r);
}
boolean doShow = true;
if (newTask) {
if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
resetTaskIfNeededLocked(r, r);
doShow = topRunningNonDelayedActivityLocked(null) == r;
}
} else if (options != null && options.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
doShow = false;
}
if (r.mLaunchTaskBehind) {
// Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
// tell WindowManager that r is visible even though it is at the back of the stack.
r.setVisibility(true);
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
} else if (SHOW_APP_STARTING_PREVIEW && doShow) {
// Figure out if we are transitioning from another activity that is
// "has the same starting icon" as the next one. This allows the
// window manager to keep the previous window it had previously
// created, if it still had one.
TaskRecord prevTask = r.getTaskRecord();
ActivityRecord prev = prevTask.topRunningActivityWithStartingWindowLocked();
if (prev != null) {
// We don't want to reuse the previous starting preview if:
// (1) The current activity is in a different task.
if (prev.getTaskRecord() != prevTask) {
prev = null;
}
// (2) The current activity is already displayed.
else if (prev.nowVisible) {
prev = null;
}
}
r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity));
}
} else {
// If this is the first activity, don't do any fancy animations,
// because there is nothing for it to animate on top of.
ActivityOptions.abort(options);
}
}
[ -> frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java ]
boolean resumeFocusedStacksTopActivities(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
...
boolean result = false;
if (targetStack != null && (targetStack.isTopStackOnDisplay() || getTopDisplayFocusedStack() == targetStack)) {
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
boolean resumedOnDisplay = false;
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = display.getChildAt(stackNdx);
final ActivityRecord topRunningActivity = stack.topRunningActivityLocked();
if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
continue;
}
if (stack == targetStack) {
// Simply update the result for targetStack because the targetStack had
// already resumed in above. We don't want to resume it again, especially in
// some cases, it would cause a second launch failure if app process was dead.
resumedOnDisplay |= result;
continue;
}
if (display.isTopStack(stack) && topRunningActivity.isState(RESUMED)) {
// Kick off any lingering app transitions form the MoveTaskToFront operation,
// but only consider the top task and stack on that display.
stack.executeAppTransition(targetOptions);
} else {
resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);
}
}
if (!resumedOnDisplay) {
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
}
}
return result;
}
这段代码的目的是resumeTopActivity:
先判断如果是顶层Task, 则直接调用resumeTopActivity方法.
接着从mActivityDisplays列表从上往下依次遍历Task, 如果发现之前没有resume(即resumedOnDisplay为false), 则调用resumeTopActivity方法.
最终都会走到resumeTopActivityUncheckedLocked
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mInResumeTopActivity) {
return false;
}
boolean result = false;
try {
// Protect against recursion.
mInResumeTopActivity = true;
// 见【第8.4节】
result = resumeTopActivityInnerLocked(prev, options);
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
//从任务历史列表mTaskHistory里, 获取最上面运行的Activity
ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
final boolean hasRunningActivity = next != null;
if (!hasRunningActivity) {
// 如果没有运行的Activity, 则从其他task堆栈中查找Activity并resume
return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
}
// 如果topRunningActivity已经是resume状态, 则do nothing
if (mResumedActivity == next && next.isState(RESUMED) && display.allResumedActivitiesComplete()) {
executeAppTransition(options);
return false;
}
...
// 如果没有获取到topRunningActivity,则先暂停所有Stack中的Activity. 见【第8.5节】
boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
// 暂停当前恢复态的Activity(mResumedActivity)
// 注意prev/next为要启动的目的Activity, 而mResumedActivity为当前Activity, 两者不是同一个
if (mResumedActivity != null) {
// 见【第8.6节】
pausing |= startPausingLocked(userLeaving, false, next, false);
}
if (pausing && !resumeWhilePausing) {
// 如果Activity正在Pausing状态,且不允许pausing过程中执行resume, 则先不执行resume
// 只是将即将启动的Activity所在的进程添加到mLruProcesses最前面, 避免被杀
if (next.attachedToProcess()) {
next.app.updateProcessInfo(false, true, false);
}
if (lastResumed != null) {
lastResumed.setWillCloseOrEnterPip(true);
}
return true;
} else if (mResumedActivity == next && next.isState(RESUMED) && display.allResumedActivitiesComplete()) {
// 如果要启动的Activity已经Resume了
// 则不需要做什么, 调一下executeAppTransition执行一下pending transitions即可.
executeAppTransition(options);
return true;
}
...
// 如果下一个Activity已经可见了, 上一个Activity当前正处于finishing状态, 则直接让上一个Activity不可见
// 当上一个Activity不是finishing状态(比如当下一个Activity不是全屏状态时的场景), 上一个Activity还应该是可见的
if (prev != null && prev != next && next.nowVisible) {
if (prev.finishing) {
prev.setVisibility(false);
}
}
...
if (next.attachedToProcess()) {
// Activity所在进程已启动, 和ActivityStackSupervisor.realStartActivityLocked做的事情类似.
// 上一个Activity是否半透明
final boolean lastActivityTranslucent = lastFocusedStack != null
&& (lastFocusedStack.inMultiWindowMode()
|| (lastFocusedStack.mLastPausedActivity != null
&& !lastFocusedStack.mLastPausedActivity.fullscreen));
// 如果将要启动的Activity不可见, 则让该Activity可见
if (!next.visible || next.stopped || lastActivityTranslucent) {
next.setVisibility(true);
}
...
// 设置Activity状态为RESUMED
next.setState(RESUMED, "resumeTopActivityInnerLocked");
// 更新进程信息
next.app.updateProcessInfo(false, true, true);
...
final ClientTransaction transaction = ClientTransaction.obtain(next.app.getThread(), next.appToken);
// 分发所有pending结果
ArrayList<ResultInfo> a = next.results;
if (a != null) {
final int N = a.size();
if (!next.finishing && N > 0) {
transaction.addCallback(ActivityResultItem.obtain(a));
}
}
// 分发new intent
if (next.newIntents != null) {
transaction.addCallback(NewIntentItem.obtain(next.newIntents, true /* resume */));
}
// Well the app will no longer be stopped.
// Clear app token stopped state in window manager if needed.
next.notifyAppResumed(next.stopped);
next.sleeping = false;
mService.getAppWarningsLocked().onResumeActivity(next);
next.app.setPendingUiCleanAndForceProcessStateUpTo(mService.mTopProcessState);
next.clearOptionsLocked();
// 触发onResume
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.getReportedProcState(),
getDisplay().mDisplayContent.isNextTransitionForward()));
mService.getLifecycleManager().scheduleTransaction(transaction);
// From this point on, if something goes wrong there is no way
// to recover the activity.
next.completeResumeLocked();
} else { // 进程没启动
// Whoops, need to restart this activity!
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW) {
next.showStartingWindow(null, false, false);
}
}
// 创建App进程并启动Activity. 见【第9.1节】
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
[ -> frameworks/base/services/core/java/com/android/server/wm/ActivityDisplay.java ]
boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {
boolean someActivityPaused = false;
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = mStacks.get(stackNdx);
final ActivityRecord resumedActivity = stack.getResumedActivity();
if (resumedActivity != null && (stack.getVisibility(resuming) != STACK_VISIBILITY_VISIBLE || !stack.isFocusable())) {
// 见【第8.6节】
someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming, dontWait);
}
}
return someActivityPaused;
}
源码解释:
Pause all activities in either all of the stacks or just the back stacks. This is done before
resuming a new activity and to make sure that previously active activities are
paused in stacks that are no longer visible or in pinned windowing mode. This does not
pause activities in visible stacks, so if an activity is launched within the same stack/task,
then we should explicitly pause that stack’s top activity.
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean pauseImmediately) {
if (mPausingActivity != null) {
if (!shouldSleepActivities()) {
// Avoid recursion among check for sleep and complete pause during sleeping.
// Because activity will be paused immediately after resume, just let pause
// be completed by the order of activity paused from clients.
completePauseLocked(false, resuming);
}
}
ActivityRecord prev = mResumedActivity;
// Trying to pause when nothing is resumed
if (prev == null && resuming == null) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
return false;
}
// Trying to pause activity that is in process of being resumed
if (prev == resuming) {
return false;
}
mPausingActivity = prev;
mLastPausedActivity = prev;
mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
prev.setState(PAUSING, "startPausingLocked");
prev.getTaskRecord().touchActiveTime();
clearLaunchTime(prev);
mService.updateCpuStats();
if (prev.attachedToProcess()) {
mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} else {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
// If we are not going to sleep, we want to ensure the device is
// awake until the next activity is started.
if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
mStackSupervisor.acquireLaunchWakelock();
}
if (mPausingActivity != null) {
// Have the window manager pause its key dispatching until the new
// activity has started. If we're pausing the activity just because
// the screen is being turned off and the UI is sleeping, don't interrupt
// key dispatch; the same activity will pick it up again on wakeup.
if (!uiSleeping) {
prev.pauseKeyDispatchingLocked();
}
if (pauseImmediately) {
// If the caller said they don't want to wait for the pause, then complete
// the pause now.
completePauseLocked(false, resuming);
return false;
} else {
schedulePauseTimeout(prev);
return true;
}
} else {
// This activity failed to schedule the
// pause, so just treat it as being paused now.
// Activity not running, resuming next.
if (resuming == null) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
return false;
}
}
[ -> frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java ]
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// 获取Activity所在的进程
final WindowProcessController wpc = mService.getProcessController(r.processName, r.info.applicationInfo.uid);
// 如果Activity所在的进程已启动,则直接启动Activity. 见【第15节】
if (wpc != null && wpc.hasThread()) {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
}
// 如果Activity所在的进程未启动,则先启动进程. 见【第10.1节】
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
}
[ -> frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java ]
public final class LocalService extends ActivityManagerInternal {
@Override
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead, String hostingType, ComponentName hostingName) {
synchronized (ActivityManagerService.this) {
// HostingRecord描述启动一个进程所需的信息
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName),
false /* allowWhileBooting */, false /* isolated */,
true /* keepIfLarge */);
}
}
}
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
[ -> frameworks/base/services/core/java/com/android/server/am/ProcessList.java ]
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
ProcessRecord app;
if (!isolated) { // isolated=false
// 获取进程对象ProcessRecord
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
} else {
// If this is an isolated process, it can't re-use an existing process.
app = null;
}
...
if (app == null) { // 若进程为空,创建新进程
app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
app.crashHandler = crashHandler;
app.isolatedEntryPoint = entryPoint;
app.isolatedEntryPointArgs = entryPointArgs;
} else {
// If this is a new package in the process, add the package to the list
app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
}
...
// 启动进程
final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
return success ? app : null;
}
final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, String abiOverride) {
return startProcessLocked(app, hostingRecord, false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
}
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
boolean disableHiddenApiChecks, boolean mountExtStorageFull, String abiOverride) {
...
// 进程参数设置,包括uid/gids/mountMode等
int uid = app.uid;
int[] gids = null;
int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
if (!app.isolated) {
int[] permGids = null;
// 对于非isolated进程, 需要设置gids, 便于应用程序之间共享资源
if (ArrayUtils.isEmpty(permGids)) {
gids = new int[3];
} else {
gids = new int[permGids.length + 3];
System.arraycopy(permGids, 0, gids, 3, permGids.length);
}
gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
// Replace any invalid GIDs
if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
}
app.mountMode = mountExternal;
app.gids = gids;
app.setRequiredAbi(requiredAbi);
app.instructionSet = instructionSet;
...
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
final String entryPoint = "android.app.ActivityThread";
return startProcessLocked(hostingRecord, entryPoint, app, uid, gids, runtimeFlags,
mountExternal, seInfo, requiredAbi, instructionSet, invokeWith, startTime);
}
boolean startProcessLocked(HostingRecord hostingRecord,
String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
// 设置进程参数, 并将进程添加到待启动进程列表mPendingStarts
app.pendingStart = true;
app.killedByAm = false;
app.removed = false;
app.killed = false;
final long startSeq = app.startSeq = ++mProcStartSeqCounter;
app.setStartParams(uid, hostingRecord, seInfo, startTime);
app.setUsingWrapper(invokeWith != null || SystemProperties.get("wrap." + app.processName) != null);
mPendingStarts.put(startSeq, app);
...
if (mService.mConstants.FLAG_PROCESS_START_ASYNC) { // true 异步启动进程
mService.mProcStartHandler.post(() -> {
final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
synchronized (mService) {
handleProcessStartedLocked(app, startResult, startSeq);
}
});
return true;
} else { // 同步启动进程
final Process.ProcessStartResult startResult = startProcess(hostingRecord,
entryPoint, app, uid, gids, runtimeFlags, mountExternal, seInfo,
requiredAbi, instructionSet, invokeWith, startTime);
handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper, startSeq, false);
return app.pid > 0;
}
}
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord,
String entryPoint, ProcessRecord app, int uid, int[] gids, int runtimeFlags,
int mountExternal, String seInfo, String requiredAbi, String instructionSet,
String invokeWith, long startTime) {
final Process.ProcessStartResult startResult;
if (hostingRecord.usesWebviewZygote()) {
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
} else if (hostingRecord.usesAppZygote()) {
final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
startResult = appZygote.getProcess().start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, app.info.packageName,
/*useUsapPool=*/ false,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
} else { // 默认是REGULAR_ZYGOTE
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}
return startResult;
}
[ -> frameworks/base/core/java/android/os/Process.java ]
Process#start各参数含义:
具体代码如下:
public static ProcessStartResult start(@NonNull final String processClass,
@Nullable final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags,
int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
@Nullable String[] zygoteArgs) {
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, packageName,
/*useUsapPool=*/ true, zygoteArgs);
}
[ -> frameworks/base/core/java/android/os/ZygoteProcess.java ]
public final Process.ProcessStartResult start(@NonNull final String processClass,
final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
boolean useUsapPool,
@Nullable String[] zygoteArgs) {
// 通过Zygote启动新进程
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
packageName, useUsapPool, zygoteArgs);
}
private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
@Nullable final String niceName,
final int uid, final int gid,
@Nullable final int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
boolean startChildZygote,
@Nullable String packageName,
boolean useUsapPool,
@Nullable String[] extraArgs)
throws ZygoteStartFailedEx {
// Zygote进程参数设置argsForZygote
ArrayList<String> argsForZygote = new ArrayList<>();
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
argsForZygote.add("--runtime-flags=" + runtimeFlags);
if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
argsForZygote.add("--mount-external-default");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
argsForZygote.add("--mount-external-read");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
argsForZygote.add("--mount-external-write");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) {
argsForZygote.add("--mount-external-full");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
argsForZygote.add("--mount-external-installer");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) {
argsForZygote.add("--mount-external-legacy");
}
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
if (gids != null && gids.length > 0) {
StringBuilder sb = new StringBuilder();
sb.append("--setgroups=");
int sz = gids.length;
for (int i = 0; i < sz; i++) {
if (i != 0) {
sb.append(',');
}
sb.append(gids[i]);
}
argsForZygote.add(sb.toString());
}
argsForZygote.add("--nice-name=" + niceName);
argsForZygote.add("--seinfo=" + seInfo);
argsForZygote.add("--instruction-set=" + instructionSet);
argsForZygote.add("--app-data-dir=" + appDataDir);
argsForZygote.add("--invoke-with");
argsForZygote.add(invokeWith);
argsForZygote.add("--start-child-zygote");
argsForZygote.add("--package-name=" + packageName);
argsForZygote.add(processClass);
Collections.addAll(argsForZygote, extraArgs);
synchronized(mLock) {
// 先和Zygote进程通过socket通道建立连接, 然后将参数argsForZygote写入Zygote进程, 并等待结果返回
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), useUsapPool, argsForZygote);
}
}
// 主Zygote进程zygote和从Zygote进程zygote_secondary. 优先和主Zygote进程建立连接.
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
attemptConnectionToPrimaryZygote();
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
if (mZygoteSecondarySocketAddress != null) {
attemptConnectionToSecondaryZygote();
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
}
}
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
// 向Zygote进程输出流中写入参数信息
zygoteWriter.write(msgStr);
zygoteWriter.flush();
// 从Zygote进程输入流读取进程创建信息
Process.ProcessStartResult result = new Process.ProcessStartResult();
result.pid = zygoteInputStream.readInt();
result.usingWrapper = zygoteInputStream.readBoolean();
return result;
}
参考文章 App进程创建过程
[ -> frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java ]
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
// 先等所有的暂停Activity操作完成
if (!mRootActivityContainer.allPausedActivitiesComplete()) {
return false;
}
...
final TaskRecord task = r.getTaskRecord();
final ActivityStack stack = task.getStack();
proc.addActivityIfNeeded(r);
List<ResultInfo> results = null;
List<ReferrerIntent> newIntents = null;
if (andResume) {
// We don't need to deliver new intents and/or set results if activity is going to pause immediately after launch.
results = r.results;
newIntents = r.newIntents;
}
if (r.isActivityTypeHome()) { // 如果Activity为Home或Launcher
// 将task的第一个Activity所属进程设置为Home进程
updateHomeProcess(task.mActivities.get(0).app);
}
r.sleeping = false;
r.forceNewConfig = false;
r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.appToken);
// 添加LaunchActivityItem消息到callback队列
final DisplayContent dc = r.getDisplay().mDisplayContent;
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.icicle, r.persistentState, results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(), r.assistToken));
// 设置执行完transaction操作后的最终生命周期状态, 可能是ResumeActivityItem或PauseActivityItem
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// 执行transaction操作. 见【第16节】
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
if (andResume && readyToResume()) {
// As part of the process of launching, ActivityThread also performs a resume.
stack.minimalResumeActivityLocked(r);
} else {
// This activity is not starting in the resumed state... which should look like we asked
// it to pause+stop (but remain visible), and it has done so and reported back the
// current icicle and other state.
r.setState(PAUSED, "realStartActivityLocked");
}
// Launch the new version setup screen if needed. We do this -after-
// launching the initial activity (that is, home), so that it can have
// a chance to initialize itself while in the background, making the
// switch back to it faster and look better.
if (mRootActivityContainer.isTopDisplayFocusedStack(stack)) {
mService.getActivityStartController().startSetupActivity();
}
// Update any services we are bound to that might care about whether
// their client may have activities.
if (r.app != null) {
r.app.updateServiceConnectionActivities();
}
return true;
}
[ -> frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java ]
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
// If client is not an instance of Binder - it's a remote call and at this point it is
// safe to recycle the object. All objects used for local calls will be recycled after
// the transaction is executed on client in ActivityThread.
transaction.recycle();
}
}
[ -> frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java ]
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
[ -> frameworks/base/core/java/android/app/ActivityThread.java ]
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
}
[ -> frameworks/base/core/java/android/app/ClientTransactionHandler.java ]
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
// 预处理
transaction.preExecute(this);
// 执行操作
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
[ -> frameworks/base/core/java/android/app/ActivityThread.java ]
class H extends Handler {
public static final int EXECUTE_TRANSACTION = 159;
public void handleMessage(Message msg) {
switch (msg.what) {
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
break;
}
}
}
[ -> frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java ]
public void execute(ClientTransaction transaction) {
// 检查当前事务的Activity是不是要destroy, 如果是则将其从activitiesToBeDestroyed列表移除
// 因为后面即将执行这个Activity的destroy操作.
final IBinder token = transaction.getActivityToken();
if (token != null) {
final Map<IBinder, ClientTransactionItem> activitiesToBeDestroyed = mTransactionHandler.getActivitiesToBeDestroyed();
final ClientTransactionItem destroyItem = activitiesToBeDestroyed.get(token);
if (destroyItem != null) {
if (transaction.getLifecycleStateRequest() == destroyItem) {
// It is going to execute the transaction that will destroy activity with the
// token, so the corresponding to-be-destroyed record can be removed.
activitiesToBeDestroyed.remove(token);
}
if (mTransactionHandler.getActivityClient(token) == null) {
// The activity has not been created but has been requested to destroy, so all
// transactions for the token are just like being cancelled.
return;
}
}
}
// 执行callbacks列表中所有状态(startActivity过程执行ON_CREATE)
executeCallbacks(transaction);
// 执行到最终目标状态(startActivity过程执行ON_START和ON_RESUME)
executeLifecycleState(transaction);
}
executeCallbacks
执行handleLaunchActivity (即LaunchActivityItem)
executeLifecycleState
执行handleStartActivity -> handleResumeActivity
生命周期的遍历过程参考【第27节】ActivityLifecycleItem
// 遍历并执行callbacks请求的所有状态
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
if (callbacks == null || callbacks.isEmpty()) {
return;
}
// 获取Activity令牌
final IBinder token = transaction.getActivityToken();
// 获取ActivityClientRecord
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
// 获取最终的目标状态
final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState() : UNDEFINED;
// Index of the last callback that requests some post-execution state.
final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
// 获取当前状态
final ClientTransactionItem item = callbacks.get(i);
// 获取下一个状态(只有NewIntentItem的getPostExecutionState为ON_RESUME, 其他都是UNDEFINED)
final int postExecutionState = item.getPostExecutionState();
// 获取离下一个状态最短路线的上一个状态(基本都是UNDEFINED,ON_RESUME除外)
final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r, item.getPostExecutionState());
// 若最短路线的上一个状态非空,则执行从当前状态到最短路线的上一个状态中间的所有状态
// 只有当前为NewIntentItem时才会走到这里,其他情况都走不到
if (closestPreExecutionState != UNDEFINED) {
cycleToPath(r, closestPreExecutionState, transaction);
}
// 执行当前状态
item.execute(mTransactionHandler, token, mPendingActions);
// 当前状态postExecute
item.postExecute(mTransactionHandler, token, mPendingActions);
if (r == null) {
// Launch activity request will create an activity record.
r = mTransactionHandler.getActivityClient(token);
}
if (postExecutionState != UNDEFINED && r != null) {
// Skip the very last transition and perform it by explicit state request instead.
final boolean shouldExcludeLastTransition = i == lastCallbackRequestingState && finalState == postExecutionState;
cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
}
}
}
[ -> frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java ]
@Override
public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState,
mPersistentState, mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client, mAssistToken);
// 执行launch操作. 见【第21.1节】
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}
@Override
public void postExecute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
// launching Activity减1
client.countLaunchingActivities(-1);
}
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
// 获取到最终状态
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
return;
}
final IBinder token = transaction.getActivityToken();
final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
if (r == null) {
// Ignore requests for non-existent client records for now.
return;
}
// Cycle to the state right before the final requested state.
// 执行从当前状态到最终状态前一个状态之间的所有状态
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
// Execute the final transition with proper parameters.
// 执行最终状态
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState, ClientTransaction transaction) {
// 获取起始状态
final int start = r.getLifecycleState();
// 获取start~end之间的所有状态
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
// 执行所有状态
performLifecycleSequence(r, path, transaction);
}
[ -> frameworks/base/core/java/android/app/servertransaction/TransactionExecutorHelper.java ]
public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
mLifecycleSequence.clear();
if (finish >= start) {
// just go there
for (int i = start + 1; i <= finish; i++) {
mLifecycleSequence.add(i);
}
} else { // finish < start, can't just cycle down
if (start == ON_PAUSE && finish == ON_RESUME) {
// Special case when we can just directly go to resumed state.
mLifecycleSequence.add(ON_RESUME);
} else if (start <= ON_STOP && finish >= ON_START) {
// Restart and go to required state.
// Go to stopped state first.
for (int i = start + 1; i <= ON_STOP; i++) {
mLifecycleSequence.add(i);
}
// Restart
mLifecycleSequence.add(ON_RESTART);
// Go to required state
for (int i = ON_START; i <= finish; i++) {
mLifecycleSequence.add(i);
}
} else { // Relaunch and go to required state
// Go to destroyed state first.
for (int i = start + 1; i <= ON_DESTROY; i++) {
mLifecycleSequence.add(i);
}
// Go to required state
for (int i = ON_CREATE; i <= finish; i++) {
mLifecycleSequence.add(i);
}
}
}
// Remove last transition in case we want to perform it with some specific params.
if (excludeLastState && mLifecycleSequence.size() != 0) {
mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
}
return mLifecycleSequence;
}
执行ON_START
和ON_RESUME
private void performLifecycleSequence(ActivityClientRecord r, IntArray path, ClientTransaction transaction) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
switch (state) {
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(r, mPendingActions, null);
break;
case ON_START:
// 见【第21.2节】
mTransactionHandler.handleStartActivity(r, mPendingActions);
break;
case ON_RESUME:
// 见【第21.3节】
mTransactionHandler.handleResumeActivity(r.token, false, r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(r.token, false,
false, 0, mPendingActions, "LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
mTransactionHandler.handleStopActivity(r.token, false,
0, mPendingActions, false, "LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r.token, false,
0, false, "performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(r.token, false /* start */);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
}
此处 start = 1, end = 3. 因此接下来会执行ON_START和ON_RESUME.
[ -> frameworks/base/core/java/android/app/ActivityThread.java ]
@Override
public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) {
...
final Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
// 更新Configuration
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
// 更新pendingActions
if (!r.activity.mFinished && pendingActions != null) {
pendingActions.setOldState(r.state);
pendingActions.setRestoreInstanceState(true);
pendingActions.setCallOnPostCreate(true);
}
} else { // 错误处理
ActivityTaskManager.getService().finishActivity(r.token, Activity.RESULT_CANCELED, null, Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
}
return a;
}
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
// 设置packageInfo
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE);
}
// 设置component
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity);
}
// 创建ContextImpl
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
// 反射创建Activity
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
...
}
try {
// 创建并启动Application实例, 如果mApplcation非空则直接返回
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
// 设置Activity各属性
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
appContext.setOuterContext(activity);
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,
r.assistToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
// 调用Activity.onCreate(...)方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
r.activity = activity;
}
// 设置Activity状态为ON_CREATE
r.setState(ON_CREATE);
synchronized (mResourcesManager) {
mActivities.put(r.token, r);
}
} catch (SuperNotCalledException e) {
...
}
return activity;
}
// 创建Activity的上下文
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
final int displayId;
displayId = ActivityTaskManager.getService().getActivityDisplayId(r.token);
ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
// For debugging purposes, if the activity's package name contains the value of
// the "debug.use-second-display" system property as a substring, then show
// its content on a secondary display if there is one.
String pkgName = SystemProperties.get("debug.second-display.pkg");
if (pkgName != null && !pkgName.isEmpty()&&r.packageInfo.mPackageName.contains(pkgName)) {
for (int id : dm.getDisplayIds()) {
if (id != Display.DEFAULT_DISPLAY) {
Display display = dm.getCompatibleDisplay(id, appContext.getResources());
appContext = (ContextImpl) appContext.createDisplayContext(display);
break;
}
}
}
return appContext;
}
static ContextImpl createActivityContext(ActivityThread mainThread,
LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken,
int displayId, Configuration overrideConfiguration) {
String[] splitDirs = packageInfo.getSplitResDirs();
ClassLoader classLoader = packageInfo.getClassLoader();
if (packageInfo.getApplicationInfo().requestsIsolatedSplitLoading()) {
classLoader = packageInfo.getSplitClassLoader(activityInfo.splitName);
splitDirs = packageInfo.getSplitPaths(activityInfo.splitName);
}
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName, activityToken, null, 0, classLoader, null);
// Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY;
final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
? packageInfo.getCompatibilityInfo()
: CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
final ResourcesManager resourcesManager = ResourcesManager.getInstance();
// Create the base resources for which all configuration contexts for this Activity
// will be rebased upon.
context.setResources(resourcesManager.createBaseActivityResources(activityToken,
packageInfo.getResDir(),
splitDirs,
packageInfo.getOverlayDirs(),
packageInfo.getApplicationInfo().sharedLibraryFiles,
displayId,
overrideConfiguration,
compatInfo,
classLoader));
context.mDisplay = resourcesManager.getAdjustedDisplay(displayId, context.getResources());
return context;
}
@Override
public void handleStartActivity(ActivityClientRecord r, PendingTransactionActions pendingActions) {
final Activity activity = r.activity;
// 执行Start操作
activity.performStart("handleStartActivity");
// 设置Activity状态为ON_START
r.setState(ON_START);
if (pendingActions == null) {
// No more work to do.
return;
}
// Restore instance state
// 调用RestoreInstanceState恢复状态
if (pendingActions.shouldRestoreInstanceState()) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
// Call postOnCreate()
// 调用postOnCreate
if (pendingActions.shouldCallOnPostCreate()) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
}
}
见【第23.2节】
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward, String reason) {
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
if (mActivitiesToBeDestroyed.containsKey(token)) {
return;
}
final Activity a = r.activity;
final int forwardBit = isForward ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
// 判断是否willActivityBeVisible
boolean willBeVisible = !a.mStartedActivity;
if (!willBeVisible) {
willBeVisible = ActivityTaskManager.getService().willActivityBeVisible(a.getActivityToken());
}
// 如果Window还没添加到WindowManager,且要求Activity将要可见,则将Window添加到WindowManager
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
} else {
a.onWindowAttributesChanged(l);
}
}
} else if (!willBeVisible) {
// 如果Window已经添加到WindowManager,但要求Activity将不可见,则设置隐藏
r.hideForNow = true;
}
// Get rid of anything left hanging around.
// 清空将要移除的Windows
cleanUpPendingRemoveWindows(r, false /* force */);
// The window is now visible if it has been added, we are not
// simply finishing, and we are not starting another activity.
// 设置Activity可见
if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
if (r.newConfig != null) {
performConfigurationChangedForActivity(r, r.newConfig);
r.newConfig = null;
}
WindowManager.LayoutParams l = r.window.getAttributes();
if ((l.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != forwardBit) {
l.softInputMode = (l.softInputMode & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) | forwardBit;
if (r.activity.mVisibleFromClient) {
ViewManager wm = a.getWindowManager();
View decor = r.window.getDecorView();
wm.updateViewLayout(decor, l);
}
}
r.activity.mVisibleFromServer = true;
mNumVisibleActivities++;
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();
}
}
r.nextIdle = mNewActivities;
mNewActivities = r;
Looper.myQueue().addIdleHandler(new Idler());
}
public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest, String reason) {
// 获取ActivityClientRecord
final ActivityClientRecord r = mActivities.get(token);
if (r == null || r.activity.mFinished) {
return null;
}
if (finalStateRequest) {
r.hideForNow = false;
r.activity.mStartedActivity = false;
}
...
// 调用Activity.onNewIntent
if (r.pendingIntents != null) {
deliverNewIntents(r, r.pendingIntents);
r.pendingIntents = null;
}
// 调用Activity.onActivityResult
if (r.pendingResults != null) {
deliverResults(r, r.pendingResults, reason);
r.pendingResults = null;
}
// 调用Activity.onResume
r.activity.performResume(r.startsNotResumed, reason);
r.state = null;
r.persistentState = null;
// 设置Activity的状态为ON_RESUME
r.setState(ON_RESUME);
return r;
}
private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) {
final int N = intents.size();
for (int i=0; i<N; i++) {
ReferrerIntent intent = intents.get(i);
intent.setExtrasClassLoader(r.activity.getClassLoader());
intent.prepareToEnterProcess();
r.activity.mFragments.noteStateNotSaved();
mInstrumentation.callActivityOnNewIntent(r.activity, intent);
}
}
private void deliverResults(ActivityClientRecord r, List<ResultInfo> results, String reason) {
final int N = results.size();
for (int i=0; i<N; i++) {
ResultInfo ri = results.get(i);
if (ri.mData != null) {
ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
ri.mData.prepareToEnterProcess();
}
r.activity.dispatchActivityResult(ri.mResultWho, ri.mRequestCode, ri.mResultCode, ri.mData, reason);
}
}
见【第23.3节】
[ -> frameworks/base/core/java/android/app/Instrumentation.java ]
public Activity newActivity(ClassLoader cl, String className, Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
String pkg = intent != null && intent.getComponent() != null ? intent.getComponent().getPackageName() : null;
return getFactory(pkg).instantiateActivity(cl, className, intent);
}
private AppComponentFactory getFactory(String pkg) {
if (pkg == null) {
return AppComponentFactory.DEFAULT;
}
if (mThread == null) {
return AppComponentFactory.DEFAULT;
}
LoadedApk apk = mThread.peekPackageInfo(pkg, true);
if (apk == null) apk = mThread.getSystemContext().mPackageInfo;
return apk.getAppFactory();
}
[ -> frameworks/base/core/java/android/app/AppComponentFactory.java ]
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className, @Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Activity) cl.loadClass(className).newInstance();
}
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
// 更新mWaitingActivities列表状态
private void prePerformCreate(Activity activity) {
if (mWaitingActivities != null) {
synchronized (mSync) {
final int N = mWaitingActivities.size();
for (int i=0; i<N; i++) {
final ActivityWaiter aw = mWaitingActivities.get(i);
final Intent intent = aw.intent;
if (intent.filterEquals(activity.getIntent())) {
aw.activity = activity;
mMessageQueue.addIdleHandler(new ActivityGoing(aw));
}
}
}
}
}
见【第23.1节】
// 遍历mActivityMonitors, 并通知与Activity匹配的ActivityMonitor
private void postPerformCreate(Activity activity) {
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
am.match(activity, activity, activity.getIntent());
}
}
}
}
public void callActivityOnStart(Activity activity) {
activity.onStart();
}
见【第23.2节】
public void callActivityOnResume(Activity activity) {
activity.mResumed = true;
activity.onResume();
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
am.match(activity, activity, activity.getIntent());
}
}
}
}
见【第23.3节】
[ -> frameworks/base/core/java/android/app/Activity.java ]
final void performCreate(Bundle icicle) {
performCreate(icicle, null);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
// 调用Application生命周期ActivityLifecycleCallbacks方法onActivityPreCreated
dispatchActivityPreCreated(icicle);
...
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
...
// 告诉所有子fragments, 父Activity已经创建
mFragments.dispatchActivityCreated();
// 调用Application生命周期ActivityLifecycleCallbacks方法onActivityPostCreated
dispatchActivityPostCreated(icicle);
}
private void dispatchActivityPreCreated(@Nullable Bundle savedInstanceState) {
getApplication().dispatchActivityPreCreated(this, savedInstanceState);
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPreCreated(this, savedInstanceState);
}
}
}
protected void onCreate(@Nullable Bundle savedInstanceState) {
...
if (savedInstanceState != null) {
...
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
// 恢复子fragments的状态
mFragments.restoreAllState(p, mLastNonConfigurationInstances != null ? mLastNonConfigurationInstances.fragments : null);
}
// 通知子fragments执行Create方法
mFragments.dispatchCreate();
// 执行Application生命周期回调ActivityLifecycleCallbacks.onActivityCreated
dispatchActivityCreated(savedInstanceState);
...
mRestoredFromBundle = savedInstanceState != null;
mCalled = true;
}
见【第24节】
private void dispatchActivityCreated(@Nullable Bundle savedInstanceState) {
getApplication().dispatchActivityCreated(this, savedInstanceState);
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityCreated(this,
savedInstanceState);
}
}
}
见【第24节】
private void dispatchActivityPostCreated(@Nullable Bundle savedInstanceState) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPostCreated(this,
savedInstanceState);
}
}
getApplication().dispatchActivityPostCreated(this, savedInstanceState);
}
final void performStart(String reason) {
// Application生命周期函数回调ActivityLifecycleCallbacks.onActivityPreStarted
dispatchActivityPreStarted();
...
mInstrumentation.callActivityOnStart(this);
// 通知子fragments, 父Activity已经start
mFragments.dispatchStart();
...
// Application生命周期函数回调ActivityLifecycleCallbacks.onActivityPostStarted
dispatchActivityPostStarted();
}
private void dispatchActivityPreStarted() {
getApplication().dispatchActivityPreStarted(this);
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((Application.ActivityLifecycleCallbacks)callbacks[i]).onActivityPreStarted(this);
}
}
}
见【第22.3节】
protected void onStart() {
mFragments.doLoaderStart();
dispatchActivityStarted();
}
private void dispatchActivityStarted() {
getApplication().dispatchActivityStarted(this);
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityStarted(this);
}
}
}
见【第24节】
private void dispatchActivityPostStarted() {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPostStarted(this);
}
}
getApplication().dispatchActivityPostStarted(this);
}
final void performResume(boolean followedByPause, String reason) {
// Application生命周期函数回调ActivityLifecycleCallbacks.onActivityPreResumed
dispatchActivityPreResumed();
...
// 调用Activity.onResume
mInstrumentation.callActivityOnResume(this);
// 通知子fragments, 父Activity已经resume
mFragments.dispatchResume();
...
onPostResume();
// Application生命周期函数回调ActivityLifecycleCallbacks.onActivityPostResumed
dispatchActivityPostResumed();
}
private void dispatchActivityPreResumed() {
getApplication().dispatchActivityPreResumed(this);
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPreResumed(this);
}
}
}
见【第22.4节】
protected void onResume() {
dispatchActivityResumed();
...
mCalled = true;
}
private void dispatchActivityResumed() {
getApplication().dispatchActivityResumed(this);
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityResumed(this);
}
}
}
见【第24节】
protected void onPostResume() {
final Window win = getWindow();
if (win != null) win.makeActive();
if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(true);
mCalled = true;
}
private void dispatchActivityPostResumed() {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPostResumed(this);
}
}
getApplication().dispatchActivityPostResumed(this);
}
[ -> frameworks/base/core/java/android/app/FragmentController.java ]
public void dispatchCreate() {
mHost.mFragmentManager.dispatchCreate();
}
public void dispatchActivityCreated() {
mHost.mFragmentManager.dispatchActivityCreated();
}
public void dispatchStart() {
mHost.mFragmentManager.dispatchStart();
}
public void dispatchResume() {
mHost.mFragmentManager.dispatchResume();
}
[ -> frameworks/base/core/java/android/app/FragmentManager.java ]
public void dispatchCreate() {
mStateSaved = false;
dispatchMoveToState(Fragment.CREATED);
}
public void dispatchActivityCreated() {
mStateSaved = false;
dispatchMoveToState(Fragment.ACTIVITY_CREATED);
}
public void dispatchStart() {
mStateSaved = false;
dispatchMoveToState(Fragment.STARTED);
}
public void dispatchResume() {
mStateSaved = false;
dispatchMoveToState(Fragment.RESUMED);
}
[ -> frameworks/base/core/java/android/app/Application.java ]
public interface ActivityLifecycleCallbacks {
default void onActivityPreCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
}
void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState);
default void onActivityPostCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
}
default void onActivityPreStarted(@NonNull Activity activity) {
}
void onActivityStarted(@NonNull Activity activity);
default void onActivityPostStarted(@NonNull Activity activity) {
}
default void onActivityPreResumed(@NonNull Activity activity) {
}
void onActivityResumed(@NonNull Activity activity);
default void onActivityPostResumed(@NonNull Activity activity) {
}
default void onActivityPrePaused(@NonNull Activity activity) {
}
void onActivityPaused(@NonNull Activity activity);
default void onActivityPostPaused(@NonNull Activity activity) {
}
default void onActivityPreStopped(@NonNull Activity activity) {
}
void onActivityStopped(@NonNull Activity activity);
default void onActivityPostStopped(@NonNull Activity activity) {
}
default void onActivityPreSaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
}
void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState);
default void onActivityPostSaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
}
default void onActivityPreDestroyed(@NonNull Activity activity) {
}
void onActivityDestroyed(@NonNull Activity activity);
default void onActivityPostDestroyed(@NonNull Activity activity) {
}
}
[ -> frameworks/base/core/java/android/app/servertransaction/ActivityLifecycleItem.java ]
public abstract class ActivityLifecycleItem extends ClientTransactionItem {
public static final int UNDEFINED = -1;
public static final int PRE_ON_CREATE = 0;
public static final int ON_CREATE = 1;
public static final int ON_START = 2;
public static final int ON_RESUME = 3;
public static final int ON_PAUSE = 4;
public static final int ON_STOP = 5;
public static final int ON_DESTROY = 6;
public static final int ON_RESTART = 7;
}
[ -> frameworks/base/core/java/android/app/ActivityThread.java ]
启动状态分为下面3种.
ActivityThread.sendActivityResult最终会调到Fragment的onActivityResult.
App开发过程中,一般都不对startActivity或startActivityForResult的启动结果做处理, 一般只在setResult之后才会处理.
/** Standard activity result: operation canceled. */
public static final int RESULT_CANCELED = 0;
/** Standard activity result: operation succeeded. */
public static final int RESULT_OK = -1;
/** Start of user-defined activity results. */
public static final int RESULT_FIRST_USER = 1;
public final void sendActivityResult(IBinder token, String id, int requestCode, int resultCode, Intent data) {
// 封装返回结果
ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
list.add(new ResultInfo(id, requestCode, resultCode, data));
final ClientTransaction clientTransaction = ClientTransaction.obtain(mAppThread, token);
// 添加ActivityResultItem事务
clientTransaction.addCallback(ActivityResultItem.obtain(list));
try {
mAppThread.scheduleTransaction(clientTransaction);
} catch (RemoteException e) {
// Local scheduling
}
}
[ -> frameworks/base/core/java/android/app/servertransaction/ActivityResultItem.java ]
public class ActivityResultItem extends ClientTransactionItem {
private List<ResultInfo> mResultInfoList;
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
client.handleSendResult(token, mResultInfoList, "ACTIVITY_RESULT");
}
...
}
// token为目标Activity的令牌
public void handleSendResult(IBinder token, List<ResultInfo> results, String reason) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
final boolean resumed = !r.paused;
if (!r.activity.mFinished && r.activity.mDecor != null && r.hideForNow && resumed) {
// 如果目标Activity为resumed状态,设置目标Activity可见
updateVisibility(r, true);
}
if (resumed) {
// 设置目标Activity状态为ON_PAUSE
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
}
checkAndBlockForNetworkAccess();
// 发送返回结果
deliverResults(r, results, reason);
// 目标Activity执行OnResume操作
if (resumed) {
r.activity.performResume(false, reason);
}
}
}
发送启动Activity结果这个过程, 目标Activity一般都是pause状态,因此resumed为false.
private void deliverResults(ActivityClientRecord r, List<ResultInfo> results, String reason) {
final int N = results.size();
for (int i=0; i<N; i++) {
ResultInfo ri = results.get(i);
if (ri.mData != null) {
ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
ri.mData.prepareToEnterProcess();
}
r.activity.dispatchActivityResult(ri.mResultWho, ri.mRequestCode, ri.mResultCode, ri.mData, reason);
}
}
void dispatchActivityResult(String who, int requestCode, int resultCode, Intent data,
String reason) {
mFragments.noteStateNotSaved();
if (who == null) {
onActivityResult(requestCode, resultCode, data);
} else if (who.startsWith(REQUEST_PERMISSIONS_WHO_PREFIX)) {
who = who.substring(REQUEST_PERMISSIONS_WHO_PREFIX.length());
if (TextUtils.isEmpty(who)) {
dispatchRequestPermissionsResult(requestCode, data);
} else {
Fragment frag = mFragments.findFragmentByWho(who);
if (frag != null) {
dispatchRequestPermissionsResultToFragment(requestCode, data, frag);
}
}
} else if (who.startsWith("@android:view:")) {
ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
getActivityToken());
for (ViewRootImpl viewRoot : views) {
if (viewRoot.getView() != null && viewRoot.getView().dispatchActivityResult(
who, requestCode, resultCode, data)) {
return;
}
}
} else if (who.startsWith(AUTO_FILL_AUTH_WHO_PREFIX)) {
Intent resultData = (resultCode == Activity.RESULT_OK) ? data : null;
getAutofillManager().onAuthenticationResult(requestCode, resultData, getCurrentFocus());
} else {
Fragment frag = mFragments.findFragmentByWho(who);
if (frag != null) {
frag.onActivityResult(requestCode, resultCode, data);
}
}
}
基于Android 10.0的源码剖析, 站在Luoshengyang/Innost/Gityuan肩膀上.
本文只着重分析Zygote进程fork并启动App进程的过程. 暂不介绍Zygote进程的其他进程启动过程.
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
frameworks/base/core/java/com/android/internal/os/Zygote.java
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/core/java/android/app/LoadedApk.java
frameworks/base/core/java/android/app/Instrumentation.java
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
TODO
[ -> frameworks/base/core/java/com/android/internal/os/ZygoteInit.java ]
public static void main(String argv[]) {
ZygoteServer zygoteServer = null;
Runnable caller;
try {
// 从argv中读取各参数信息
boolean startSystemServer = false;
String zygoteSocketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
// 是否主Zygote进程
final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
if (!enableLazyPreload) {
// 预加载资源和类
preload(bootTimingsTraceLog);
} else {
// 线程优先级设置为normal
Zygote.resetNicePriority();
}
// 启动之后做一次初始GC
gcAndFinalize();
// 初始化Zygote Native状态
Zygote.initNativeState(isPrimaryZygote);
// 创建Socket Server
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
// fork SystemServer进程
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// 启动SystemServer进程
if (r != null) {
r.run();
return;
}
}
// while(true)循环监听并处理Socket连接,如果有fork子进程请求则fork子进程,并封装到Runnable中返回
// 否则一直循环下去
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
...
} finally {
// 关闭Socket Server
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
// 执行Runnable, 根据下文分析可知会调用ActivityThread.main()方法
if (caller != null) {
caller.run();
}
}
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
// 初始化
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
// 见【第6.1节】
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
[ -> frameworks/base/core/java/com/android/internal/os/ZygoteServer.java ]
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();
// Server Socket保存到socketFDs[0]
socketFDs.add(mZygoteSocket.getFileDescriptor());
// 填充null占位
peers.add(null);
while (true) {
StructPollfd[] pollFDs = null;
// 为poll struct数组分组分配空间.Zygote可能包含regular Zygote,WebView Zygote,AppZygote
if (mUsapPoolEnabled) {
usapPipeFDs = Zygote.getUsapPipeFDs();
pollFDs = new StructPollfd[socketFDs.size() + 1 + usapPipeFDs.length];
} else {
pollFDs = new StructPollfd[socketFDs.size()];
}
int pollIndex = 0;
// 将socketFDs数组元素依次设置到pollFDs数组, 且pollIndex累加
for (FileDescriptor socketFD : socketFDs) {
pollFDs[pollIndex] = new StructPollfd();
pollFDs[pollIndex].fd = socketFD;
pollFDs[pollIndex].events = (short) POLLIN;
++pollIndex;
}
// 关于mUsapPoolEventFD的解释: File descriptor used for communication
// between the signal handler and the ZygoteServer poll loop.
final int usapPoolEventFDIndex = pollIndex;
// 将usapPipeFDs数组元素依次设置到pollFDs数组, pollIndex累加
if (mUsapPoolEnabled) {
pollFDs[pollIndex] = new StructPollfd();
pollFDs[pollIndex].fd = mUsapPoolEventFD;
pollFDs[pollIndex].events = (short) POLLIN;
++pollIndex;
for (int usapPipeFD : usapPipeFDs) {
FileDescriptor managedFd = new FileDescriptor();
managedFd.setInt$(usapPipeFD);
pollFDs[pollIndex] = new StructPollfd();
pollFDs[pollIndex].fd = managedFd;
pollFDs[pollIndex].events = (short) POLLIN;
++pollIndex;
}
}
// 轮询pollFDs文件描述符列表的状态,当pollFds有事件到来则往下执行,否则阻塞在这里
// 这里用到了IO多路复用机制
Os.poll(pollFDs, -1);
...
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
peers.add(null);
while (--pollIndex >= 0) {
// 过滤非POLLIN的文件描述符
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}
if (pollIndex == 0) { // 处理socketFDs[0],即ServerSocket
// 监听Socket连接, 并创建一个ZygoteConnection
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
} else if (pollIndex < usapPoolEventFDIndex) { // 处理socketFDs数组除index=0的元素
// Session socket accepted from the Zygote server socket
ZygoteConnection connection = peers.get(pollIndex);
// 处理指令. 见【第4.1节】
final Runnable command = connection.processOneCommand(this);
if (mIsForkChild) { // fork子进程, 返回Runnable并跳出循环
return command;
} else {
...
}
mIsForkChild = false;
} else { // 处理usapPipeFDs数组的元素
long messagePayload = -1;
byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES];
int readBytes = Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length);
if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) {
DataInputStream inputStream =
new DataInputStream(new ByteArrayInputStream(buffer));
messagePayload = inputStream.readLong();
} else {
continue;
}
if (pollIndex > usapPoolEventFDIndex) {
Zygote.removeUsapTableEntry((int) messagePayload);
}
usapPoolFDRead = true;
}
}
}
}
解释下这段代码:
第一次while(true)时, socketFDs只有一个元素即ServerSocket, 因此会走到if (pollIndex == 0)分支, 结束时socketFDs有2个元素: ServerSocket和newPeer对应的Socket. peers也有2个元素: null和newPeer
第一次while(true)时, socketFDs有2个元素, 当走到if (pollIndex < usapPoolEventFDIndex)分支时, 此时pollIndex=1, peers取出的元素为newPeer, 然后就会执行到connection.processOneCommand(…)
// 监听Socket连接, 并创建一个ZygoteConnection
private ZygoteConnection acceptCommandPeer(String abiList) {
return createNewConnection(mZygoteSocket.accept(), abiList);
}
protected ZygoteConnection createNewConnection(LocalSocket socket, String abiList) {
return new ZygoteConnection(socket, abiList);
}
[ -> frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java ]
Runnable processOneCommand(ZygoteServer zygoteServer) {
// 从ServerSocket的输入流读取指令参数
String[] args = Zygote.readArgumentList(mSocketReader);
ZygoteArguments parsedArgs = new ZygoteArguments(args);
// 处理args指令, 如果是处理fork进程外的其他指令则返回值为null
...
// fork进程, 返回值为0表示是子进程, -1表示错误. 见【第5.1节】
pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
try {
if (pid == 0) { // 成功创建子进程
// 设置标志位, 关闭ServerSocket连接
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
// 处理子进程
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.mStartChildZygote);
} else { // 错误处理
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
// isZygote表示创建的子进程也是Zygote进程
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
if (!isZygote) { // 非Zygote进程
// 见【第2.2节】
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
}
}
[ -> frameworks/base/core/java/com/android/internal/os/Zygote.java ]
public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
int targetSdkVersion) {
ZygoteHooks.preFork();
// 重置线程优先级为NORM_PRIORITY.
resetNicePriority();
// native调用
int pid = nativeForkAndSpecialize(uid, gid, gids, runtimeFlags,
rlimits, mountExternal, seInfo, niceName, fdsToClose,
fdsToIgnore, startChildZygote, instructionSet, appDataDir);
if (pid == 0) {
// targetSdkVersion<Q时, 设置library文件可读可执行
Zygote.disableExecuteOnly(targetSdkVersion);
}
ZygoteHooks.postForkCommon();
return pid;
}
[ -> frameworks/base/core/java/com/android/internal/os/RuntimeInit.java ]
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
final Arguments args = new Arguments(argv);
// 查找进程入口类的静态main方法, 并封装成Runnable返回, 此处进程入口类是ActivityThread
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl = Class.forName(className, true, classLoader);
Method m = cl.getMethod("main", new Class[] { String[].class });
return new MethodAndArgsCaller(m, argv);
}
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
...
}
}
}
接下来会执行Runnable#run()方法, 开始ActivityThread.main()方法的调用.
[ -> frameworks/base/core/java/android/app/ActivityThread.java ]
public static void main(String[] args) {
Looper.prepareMainLooper();
// 从args参数中获取startSeq
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// 在主线程中循环
Looper.loop();
}
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) { // 非系统进程
// 设置app name
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
// AMS attach应用程序. 见【第8节】
final IActivityManager mgr = ActivityManager.getService();
mgr.attachApplication(mAppThread, startSeq);
// GC监听
BinderInternal.addGcWatcher(new Runnable() {
@Override public void run() {
// 是否有Activity生命周期发生变化
if (!mSomeActivitiesChanged) {
return;
}
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.maxMemory();
long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
// 当虚拟机使用的内存超出最大内存的3/4时, 释放一些Activity
if (dalvikUsed > ((3*dalvikMax)/4)) {
mSomeActivitiesChanged = false;
ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
}
}
});
} else { // 系统进程
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId());
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
ContextImpl context = ContextImpl.createAppContext(this,
getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
}
// 设置全局配置变化回调
ViewRootImpl.ConfigChangedCallback configChangedCallback =
(Configuration globalConfig) -> {
synchronized (mResourcesManager) {
// We need to apply this change to the resources immediately,
// because upon returning the view hierarchy will be informed about it.
if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,null)) {
updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
mResourcesManager.getConfiguration().getLocales());
// This actually changed the resources! Tell everyone about it.
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(globalConfig)) {
mPendingConfiguration = globalConfig;
sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
}
}
}
};
ViewRootImpl.addConfigCallback(configChangedCallback);
}
[ -> frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java ]
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread, int pid,
int callingUid, long startSeq) {
ProcessRecord app;
// 从mPidsSelfLocked列表根据pid查找进程
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
}
// 若上述查找app为空,则从mPendingStarts列表根据startSeq查找进程
if (app == null && startSeq > 0) {
final ProcessRecord pending = mProcessList.mPendingStarts.get(startSeq);
if (pending != null && pending.startUid == callingUid && pending.startSeq == startSeq
&& mProcessList.handleProcessStartedLocked(pending, pid,
pending.isUsingWrapper(), startSeq, true)) {
app = pending;
}
}
...
// 进程是否处于正常模式
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
if (app.isolatedEntryPoint != null) { // isolated进程
// This is an isolated process which should just call an entry point instead of
// being bound to an application.
thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
} else if (instr2 != null) {
// 绑定App进程. 见【第9.1节】
thread.bindApplication(processName, appInfo, providers,
instr2.mClass,
profilerInfo, instr2.mArguments,
instr2.mWatcher,
instr2.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions);
} else {
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions);
}
// 绑定应用程序后, 设置app active, 并更新lru进程信息
app.makeActive(thread, mProcessStats);
mProcessList.updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
// Remove this record from the list of starting applications.
mPersistentStartingProcesses.remove(app);
mProcessesOnHold.remove(app);
boolean didSomething = false;
// See if the top visible activity is waiting to run in this process...
// 启动进程中最上面可见的Activity. 见【第12节】
if (normalMode) {
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
}
// Find any services that should be running in this process...
// 启动进程中的服务. (启动服务过程本文暂不讲解)
didSomething |= mServices.attachApplicationLocked(app, processName);
// Check if a next-broadcast receiver is in this process...
// 发送pending中的广播. (发送广播过程本文暂不讲解)
if (isPendingBroadcastProcessLocked(pid)) {
didSomething |= sendPendingBroadcastsLocked(app);
}
if (!didSomething) {
// 进程启动,更新Adj
updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_BEGIN);
}
return true;
}
[ -> frameworks/base/core/java/android/app/ActivityThread.java ]
private class ApplicationThread extends IApplicationThread.Stub {
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial, AutofillOptions autofillOptions,
ContentCaptureOptions contentCaptureOptions) {
...
// 封装App进程绑定数据AppBindData
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableBinderTracking = enableBinderTracking;
data.trackAllocation = trackAllocation;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
data.buildSerial = buildSerial;
data.autofillOptions = autofillOptions;
data.contentCaptureOptions = contentCaptureOptions;
// 向H发送BIND_APPLICATION广播
sendMessage(H.BIND_APPLICATION, data);
}
}
class H extends Handler {
public static final int BIND_APPLICATION = 110;
public void handleMessage(Message msg) {
switch (msg.what) {
case BIND_APPLICATION: // 处理App进程绑定
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
break;
}
}
}
private void handleBindApplication(AppBindData data) {
// 从AppBindData中取出InstrumentationInfo信息
final InstrumentationInfo ii;
if (data.instrumentationName != null) {
ii = new ApplicationPackageManager(null,
getPackageManager()).getInstrumentationInfo(data.instrumentationName, 0);
mInstrumentationPackageName = ii.packageName;
mInstrumentationAppDir = ii.sourceDir;
mInstrumentationSplitAppDirs = ii.splitSourceDirs;
mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
mInstrumentedAppDir = data.info.getAppDir();
mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
mInstrumentedLibDir = data.info.getLibDir();
}
// 创建Context
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
// InstrumentationInfo对象非空
if (ii != null) { // 从InstrumentationInfo中取出各参数, 基于此创建和初始化Instrumentation
ApplicationInfo instrApp = getPackageManager()
.getApplicationInfo(ii.packageName, 0, UserHandle.myUserId());
if (instrApp == null) {
instrApp = new ApplicationInfo();
}
// 将InstrumentationInfo里的参数拷贝到ApplicationInfo对象
ii.copyTo(instrApp);
instrApp.initForUser(UserHandle.myUserId());
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
final ContextImpl instrContext = ContextImpl.createAppContext(this,
pi, appContext.getOpPackageName());
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation) cl
.loadClass(data.instrumentationName.getClassName()).newInstance();
final ComponentName component = new ComponentName(ii.packageName, ii.name);
mInstrumentation.init(this, instrContext, appContext, component,
data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
} else { // 初始化Instrumentation
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
}
// 创建Application对象. 见【第10节】
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
// 调用Application.onCreate()方法. 见【第11节】
mInstrumentation.onCreate(data.instrumentationArgs);
mInstrumentation.callApplicationOnCreate(app);
...
}
[ -> frameworks/base/core/java/android/app/LoadedApk.java ]
LoadedApk: Local state maintained about a currently loaded .apk.
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
String appClass = mApplicationInfo.className;
// 设置默认Application-"android.app.Application"
if (forceDefaultAppClass || appClass == null) {
appClass = "android.app.Application";
}
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
// 创建AppContext
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// newApplication
Application app = mActivityThread.mInstrumentation
.newApplication(cl, appClass, appContext);
// 将Application设置到AppContext
appContext.setOuterContext(app);
// 将Application添加到应用程序列表
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) { // 此处instrumentation=null
instrumentation.callApplicationOnCreate(app);
}
// Rewrite the R 'constants' for all library apks.
SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
final int N = packageIdentifiers.size();
for (int i = 0; i < N; i++) {
final int id = packageIdentifiers.keyAt(i);
if (id == 0x01 || id == 0x7f) {
continue;
}
rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
}
return app;
}
[ -> frameworks/base/core/java/android/app/Instrumentation.java ]
public void onCreate(Bundle arguments) {
}
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
[ -> frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java ]
// 启动Activity
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
synchronized (mGlobalLockWithoutBoost) {
return mRootActivityContainer.attachApplication(wpc);
}
}
[ -> frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java ]
boolean attachApplication(WindowProcessController app) throws RemoteException {
final String processName = app.mName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
final ActivityStack stack = display.getFocusedStack();
if (stack != null) {
stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
final ActivityRecord top = stack.topRunningActivityLocked();
final int size = mTmpActivityList.size();
for (int i = 0; i < size; i++) {
final ActivityRecord activity = mTmpActivityList.get(i);
if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
&& processName.equals(activity.processName)) {
// 启动Activity
if (mStackSupervisor.realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
}
}
}
}
if (!didSomething) {
ensureActivitiesVisible(null, 0, false /* preserve_windows */);
}
return didSomething;
}
关于ActivityStackSupervisor#realStartActivityLocked 本文暂不分析, 后续放到startActivity部分讲解.