android6.0开机动画下载,Android6.0 开机动画(二) AMS通知系统启动

本文详细解析了Android系统从Launcher启动到屏幕点亮的过程,涉及ActivityThread的IdleHandler、 AMS的activityIdle方法、WMS的enableScreenAfterBoot函数,以及SurfaceFlinger的bootFinished函数。在系统启动过程中,通过一系列的消息处理和调用,最终完成开机动画的结束和屏幕的显示。
摘要由CSDN通过智能技术生成



在http://www.voidcn.com/article/p-dmvazozc-ev.html博客中我们已经讲了开机动画的大致流程,这里我们就Launcher启动后,Launcher的线程闲的时候在ActivityThread调用AMS的activityIdle方法。

在分析消息机制 空闲消息处理器中http://www.voidcn.com/article/p-esqptbsz-ev.html,我们知道在消息线程空闲时会调用IdleHandler的queueIdle方法,这里我们来看ActivityThread中的IdleHandler,是在ActivityThread的handleResumeActivity函数中有下面一段代码,调用了MessageQueue的addIdleHandler函数。

......

if (!r.onlyLocalRequest) {

r.nextIdle = mNewActivities;

mNewActivities = r;

if (localLOGV) Slog.v(

TAG, "Scheduling idle handler for " + r);

Looper.myQueue().addIdleHandler(new Idler());

}

......

在Idler的queueIdle函数中调用了AMS的activityIdle函数,我们来看下,获取ActivityStack后调用了activityIdleInternalLocked函数。

@Override

public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {

final long origId = Binder.clearCallingIdentity();

synchronized (this) {

ActivityStack stack = ActivityRecord.getStackLocked(token);//得到ActivityStack

if (stack != null) {

ActivityRecord r =

mStackSupervisor.activityIdleInternalLocked(token, false, config);

if (stopProfiling) {

if ((mProfileProc == r.app) && (mProfileFd != null)) {

try {

mProfileFd.close();

} catch (IOException e) {

}

clearProfilerLocked();

}

}

}

}

Binder.restoreCallingIdentity(origId);

}

看如下函数,我们先根据token来得到其ActivityRecord,然后将ActivityRecord的idle置为true。如果是isFrontStack调用checkFinishBootingLocked函数。

final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,

Configuration config) {

if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);

ArrayList stops = null;

ArrayList finishes = null;

ArrayList startingUsers = null;

int NS = 0;

int NF = 0;

boolean booting = false;

boolean activityRemoved = false;

ActivityRecord r = ActivityRecord.forTokenLocked(token);

if (r != null) {

if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternalLocked: Callers="

+ Debug.getCallers(4));

mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);

r.finishLaunchTickingLocked();

if (fromTimeout) {

reportActivityLaunchedLocked(fromTimeout, r, -1, -1);

}

// This is a hack to semi-deal with a race condition

// in the client where it can be constructed with a

// newer configuration from when we asked it to launch.

// We'll update with whatever configuration it now says

// it used to launch.

if (config != null) {

r.configuration = config;

}

// We are now idle. If someone is waiting for a thumbnail from

// us, we can now deliver.

r.idle = true;//idle置为true

//Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);

if (isFrontStack(r.task.stack) || fromTimeout) {

booting = checkFinishBootingLocked();

}

}

......

checkFinishBootingLocked函数,如果AMS正在启动会调用其postFinishBooting函数

private boolean checkFinishBootingLocked() {

final boolean booting = mService.mBooting;

boolean enableScreen = false;

mService.mBooting = false;

if (!mService.mBooted) {

mService.mBooted = true;

enableScreen = true;

}

if (booting || enableScreen) {

mService.postFinishBooting(booting, enableScreen);

}

return booting;

}

AMS的postFinishBooting函数发送FINISH_BOOTING_MSG消息

void postFinishBooting(boolean finishBooting, boolean enableScreen) {

mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,

finishBooting ? 1 : 0, enableScreen ? 1 : 0));

}

我们再来看消息处理,当finishBooting为true,就调用finishBooting函数,这个函数中会发送一些广播,以及将SystemService启动到PHASE_BOOT_COMPLETED阶段。

case FINISH_BOOTING_MSG: {

if (msg.arg1 != 0) {

finishBooting();

}

if (msg.arg2 != 0) {

enableScreenAfterBoot();

}

break;

}

当enableScreen为true会调用enableScreenAfterBoot函数,会在这个函数中调用WMS的enableScreenAfterBoot函数

void enableScreenAfterBoot() {

EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,

SystemClock.uptimeMillis());

mWindowManager.enableScreenAfterBoot();

synchronized (this) {

updateEventDispatchingLocked();

}

}

在WMS的enableScreenAfterBoot方法又会调用performEnableScreen方法,这个方法会调用SurfaceFlinger的Binder

public void performEnableScreen() {

synchronized(mWindowMap) {

if (mDisplayEnabled) {

return;

}

if (!mSystemBooted && !mShowingBootMessages) {

return;

}

// Don't enable the screen until all existing windows have been drawn.

if (!mForceDisplayEnabled && checkWaitingForWindowsLocked()) {

return;

}

if (!mBootAnimationStopped) {

// Do this one time.

try {

IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");

if (surfaceFlinger != null) {

//Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");

Parcel data = Parcel.obtain();

data.writeInterfaceToken("android.ui.ISurfaceComposer");

surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED

data, null, 0);

data.recycle();

}

} catch (RemoteException ex) {

Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");

}

mBootAnimationStopped = true;

}

......FIRST_CALL_TRANSACTION就是BOOT_FINISHED

class BnSurfaceComposer: public BnInterface {

public:

enum {

// Note: BOOT_FINISHED must remain this value, it is called from

// Java by ActivityManagerService.

BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,我们再来看ISurfaceComposer.cpp对BOOT_FINISHED的处理,会调用bootFinished函数。

case BOOT_FINISHED: {

CHECK_INTERFACE(ISurfaceComposer, data, reply);

bootFinished();

return NO_ERROR;

}bootFinished会计算开机的时间,然后将service.bootanim.exit属性设为1,这样bootanim会结束,这样开机动画结束。

void SurfaceFlinger::bootFinished()

{

const nsecs_t now = systemTime();

const nsecs_t duration = now - mBootTime;

ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );

mBootFinished = true;

// wait patiently for the window manager death

const String16 name("window");

sp window(defaultServiceManager()->getService(name));

if (window != 0) {

window->linkToDeath(static_cast<:deathrecipient>(this));

}

// stop boot animation

// formerly we would just kill the process, but we now ask it to exit so it

// can choose where to stop the animation.

property_set("service.bootanim.exit", "1");

char boot_exit_value[32];

property_get("service.bootanim.exit", boot_exit_value, "0");

ALOGD("The service.bootanim.exit property value is %d", atoi(boot_exit_value));

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值