此次分析基于Android 5.0.1源码
onConfigureChanges被调用的流程框架图:
源码分析
1.Android系统启动的时候会通过读取/init.rc文件启动zygote进程
service zygote /system/bin/app_process -Xzygote /system/bin --zygote
socket zygote 666
2.zygote孵化出SystemServer进程,在frameworks\base\core\java\com\android\internal\os\ZygoteInit.java的main()中有如下代码段开启SystemServer进程
public static void main(String argv[]) {
......
// Disable tracing so that forked processes do not inherit stale tracing tags from
// Zygote.
Trace.setTracingEnabled(false);
if (startSystemServer) {
startSystemServer(abiList, socketName);
}
......
}
调用到ZygoteInit.java的startSystemServer()方法
private static boolean startSystemServer(String abiList, String socketName)
......
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
pid = Zygote.forkSystemServe(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
......
}
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
......// Start services.
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} ......
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
private void startOtherServices() {
......
Slog.i(TAG, "Window Manager");
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
mActivityManagerService.setWindowManager(wm);
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
......
}
public void start() {
Slog.i(TAG, "Starting input manager");
nativeStart(mPtr);
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
registerPointerSpeedSettingObserver();
registerShowTouchesSettingObserver();
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updatePointerSpeedFromSettings();
updateShowTouchesFromSettings();
}
}, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
updatePointerSpeedFromSettings();
updateShowTouchesFromSettings();
}
创建了inputManager,inputManager类型为InputManagerService,并且调用了start()方法,接着调用一个jni方法nativeStart(mPtr),看一下mPtr的定义
// Pointer to native input manager service object.
private final long mPtr;
注意注释// Pointer to native input manager service object,
指向了本地的input manager service对象,mPtr底层传上来的NativeInputManager对象的地址,底层通过调用这个对象的一些方法来回调java层的InputManagerSevice中的一些方法,比如notifyANR就调用到了InputManagerSevice的notifyANR。而mPtr是在InputManagerService的构造函数中通过调用nativeInit()获取的,也就是navtive中的input manager service和java层的input manager service是一起创建的,mPtr的初始化如下:
public InputManagerService(Context context) {
this.mContext = context;
this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
mUseDevInputEventForAudioJack =
context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
+ mUseDevInputEventForAudioJack);
mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
LocalServices.addService(InputManagerInternal.class, new LocalService());
}
nativeInit底层实现如下:
static jlong nativeInit(JNIEnv* env, jclass clazz,
jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
messageQueue->getLooper());
im->incStrong(0);
return reinterpret_cast(im);
}
这个函数创建了NativeInputManager对方,并且将地址返回给了mPtr,这个NativeInputManager就是回调java层的对象.
nativeStart()的实现在文件
frameworks\base\services\core\jni\com_android_server_input_InputManagerService.cpp 中
static void nativeStart(JNIEnv* env, jclass clazz, jlong ptr) {
NativeInputManager* im = reinterpret_cast(ptr);
status_t result = im->getInputManager()->start();
if (result) {
jniThrowRuntimeException(env, "Input manager could not be started.");
}
}
这个函数返回的im对象,
然后start方法实现如下:
status_t InputManager::start() {
status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
if (result) {
ALOGE("Could not start InputDispatcher thread due to error %d.", result);
return result;
}
result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
if (result) {
ALOGE("Could not start InputReader thread due to error %d.", result);
mDispatcherThread->requestExit();
return result;
}
return OK;
}
所以跟了这么久最终启动的时候会启动InputDispatcherThread和InputReaderThread两个线程
InputDispatcherThread和InputReaderThread是在InputManager构造方法中创建的
InputManager::InputManager(
const sp& reader,
const sp& dispatcher) :
mReader(reader),
mDispatcher(dispatcher) {
initialize();
}
void InputManager::initialize() {
mReaderThread = new InputReaderThread(mReader);
mDispatcherThread = new InputDispatcherThread(mDispatcher);
}
mReaderThread是InputReaderThread线程,mDispatcherThread是InputDispatcherThread线程
mReaderThread持有一个InputReader对象
mDispatcherThread持有一个InputDispatcher对象
mReaderThread在轮询设备信息的时候,会回调到InputReader的loopOnce()方法,进而调用到InputDispatcher的方法
void InputReader::loopOnce() {
......
// Flush queued events out to the listener.
// This must happen outside of the lock because the listener could potentially call
// back into the InputReader's methods, such as getScanCodeState, or become blocked
// on another thread similarly waiting to acquire the InputReader lock thereby
// resulting in a deadlock. This situation is actually quite plausible because the
// listener is actually the input dispatcher, which calls into the window manager,
// which occasionally calls into the input reader.
mQueuedListener->flush();
}
flush()的实现
void QueuedInputListener::flush() {
size_t count = mArgsQueue.size();
for (size_t i = 0; i < count; i++) {
NotifyArgs* args = mArgsQueue[i];
args->notify(mInnerListener);
delete args;
}
mArgsQueue.clear();
}
呵呵,这个mInnerListener就是InputDispatcher对象,也就inputReader是接收到消息后就通知InputDispatcher
void NotifyKeyArgs::notify(const sp& listener) const {
listener->notifyKey(this);
}
void NotifySwitchArgs::notify(const sp& listener) const {
listener->notifySwitch(this);
}
void NotifyMotionArgs::notify(const sp& listener) const {
listener->notifyMotion(this);
}
void NotifyDeviceResetArgs::notify(const sp& listener) const {
listener->notifyDeviceReset(this);
}
void NotifyConfigurationChangedArgs::notify(const sp& listener) const {
listener->notifyConfigurationChanged(this);
}
几经波折就是为了告诉你消息的走向为InputReaderThread->InputReader->InputDispatcher 不同的消息回掉InputDispatcher 的不同方法。下面介绍一下这两个线程
InputReaderThread:一个独立的循环线程,不断的轮询设备相关设备节点是否有新的事情发生
/* Reads raw events from the event hub and processes them, endlessly. */
class InputReaderThread : public Thread {
public:
InputReaderThread(const sp& reader);
virtual ~InputReaderThread();
private:
sp mReader;
virtual bool threadLoop();
};
注意它上面的注视/* Reads raw events from the event hub and processes them, endlessly. */ 无止境的读取原始设备信息然后处理之
/* Enqueues and dispatches input events, endlessly. */
class InputDispatcherThread : public Thread {
public:
explicit InputDispatcherThread(const sp& dispatcher);
~InputDispatcherThread();
private:
virtual bool threadLoop();
sp mDispatcher;
};
注意它上面的注视 /* Enqueues and dispatches input events, endlessly. */无止境的分发输入消息
notifyConfigurationChanged()
notifyInputChannelBroken()
notifyANR()
......
notifyConfigurationChanged()就是我们要分析的,我们已经分析到notifyConfigurationChanged()被调用的过程
void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
ALOGD("notifyConfigurationChanged - eventTime=%lld", args->eventTime);
#endif
bool needWake;
{ // acquire lock
AutoMutex _l(mLock);
ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(args->eventTime);
needWake = enqueueInboundEventLocked(newEntry);
} // release lock
if (needWake) {
mLooper->wake();
}
}
notifyConfigurationChanged中,构造一个消息实体入队了,当队列有消息入队时thredLoop就会执行,具体thredLoop怎么被调用的还不知道
bool InputDispatcherThread::threadLoop() {
mDispatcher->dispatchOnce();
return true;
}
void InputDispatcher::dispatchOnce() {
......
// Run a dispatch loop if there are no pending commands.
// The dispatch loop might enqueue commands to run afterwards.
if (!haveCommandsLocked()) {
dispatchOnceInnerLocked(&nextWakeupTime);
}
// Run all pending commands if there are any.
// If any commands were run then force the next poll to wake up immediately.
if (runCommandsLockedInterruptible()) {
nextWakeupTime = LONG_LONG_MIN;
}
} // release lock
......
}
void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime)
{
......
switch (mPendingEvent->type) {
case EventEntry::TYPE_CONFIGURATION_CHANGED: {
ConfigurationChangedEntry* typedEntry =
static_cast(mPendingEvent);
done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
break;
}
......
}
如果获取到的消息是TYPE_CONFIGURATION_CHANGED则调用dispatchConfigurationChangedLocked
bool InputDispatcher::dispatchConfigurationChangedLocked(
nsecs_t currentTime, ConfigurationChangedEntry* entry) {
#if DEBUG_OUTBOUND_EVENT_DETAILS
ALOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
#endif
// Reset key repeating in case a keyboard device was added or removed or something.
resetKeyRepeatLocked();
// Enqueue a command to run outside the lock to tell the policy that the configuration changed.
CommandEntry* commandEntry = postCommandLocked(
& InputDispatcher::doNotifyConfigurationChangedInterruptible);
commandEntry->eventTime = entry->eventTime;
return true;
}
void InputDispatcher::doNotifyConfigurationChangedInterruptible(
CommandEntry* commandEntry) {
mLock.unlock();
mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
mLock.lock();
}
mPolicy->notifyConfigurationChanged(commandEntry->eventTime)会回调到InputManagerService.java的notifyConfigurationChanged
// Native callback.
private void notifyConfigurationChanged(long whenNanos) {
mWindowManagerCallbacks.notifyConfigurationChanged();
}
如上源码里面已经注释了这是native的回调
mWindowManagerCallbacks是什么,回到SystemService的main中有这么一句话
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
mActivityManagerService.setWindowManager(wm);
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
mWindowManagerCallbacks是WindowManagerService中的一个InputMonitor成员,所以又进一步调用到了InputMonitor的notifyConfigurationChanged方法
public void notifyConfigurationChanged() {
mService.sendNewConfiguration();
synchronized (mInputDevicesReadyMonitor) {
if (!mInputDevicesReady) {
mInputDevicesReady = true;
mInputDevicesReadyMonitor.notifyAll();
}
}
}
mService为WindowManagerService,sendNewConfiguration实现
void sendNewConfiguration() {
try {
mActivityManager.updateConfiguration(null);
} catch (RemoteException e) {
}
}
mActivityManager为ActivityManagerService,并调用到它的updateConfiguration
public void updateConfiguration(Configuration values) {
enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
"updateConfiguration()");
synchronized(this) {
if (values == null && mWindowManager != null) {
// sentinel: fetch the current configuration from the window manager
values = mWindowManager.computeNewConfiguration();
}
if (mWindowManager != null) {
mProcessList.applyDisplaySize(mWindowManager);
}
final long origId = Binder.clearCallingIdentity();
if (values != null) {
Settings.System.clearConfiguration(values);
}
updateConfigurationLocked(values, null, false, false);
Binder.restoreCallingIdentity(origId);
}
}
boolean updateConfigurationLocked(Configuration values,
ActivityRecord starting, boolean persistent, boolean initLocale)
for (int i=mLruProcesses.size()-1; i>=0; i--) {
ProcessRecord app = mLruProcesses.get(i);
try {
if (app.thread != null) {
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
+ app.processName + " new config " + mConfiguration);
app.thread.scheduleConfigurationChanged(configCopy);
}
} catch (Exception e) {
}
}
}
app.thread.scheduleConfigurationChanged(configCopy);这是一个binder远程调用,会调用到ActivityThread的scheduleConfigurationChanged,这就总算调用到我们的应用程序了
大家跟着标红的函数放下走
public void scheduleConfigurationChanged(Configuration config) {
updatePendingConfiguration(config);
sendMessage(H.CONFIGURATION_CHANGED, config);
}
发了一个CONFIGURATION_CHANGED,处理过程在handle中
case CONFIGURATION_CHANGED:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
handleConfigurationChanged((Configuration)msg.obj, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
......
ArrayList callbacks = collectComponentCallbacks(false, config);
if (callbacks != null) {
final int N = callbacks.size();
for (int i=0; i
对每个callback执行performConfigurationChanged方法
ArrayList
callbacks 是本进程所有的application、activity、service、contentprovider的集合,看它的实现就知道了
ArrayList collectComponentCallbacks(
boolean allActivities, Configuration newConfig) {
ArrayList callbacks
= new ArrayList();
synchronized (mResourcesManager) {
final int NAPP = mAllApplications.size();
for (int i=0; i if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
callbacks.add(a);
} else if (thisConfig != null) {
.
if (DEBUG_CONFIGURATION) {
Slog.v(TAG, "Setting activity "
+ ar.activityInfo.name + " newConfig=" + thisConfig);
}
ar.newConfig = thisConfig;
}
}
}
final int NSVC = mServices.size();
for (int i=0; i
因为application、activity、service、contentprovider都实现了ComponentCallbacks2接口。
根据条件可知
if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
callbacks.add(a);
}
只有没有finish()掉的和没有paused掉的Acitivity才会被加到callbacks当中。
private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) {
......
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb
+ ": shouldChangeConfig=" + shouldChangeConfig);
if (shouldChangeConfig) {
cb.onConfigurationChanged(config);
if (activity != null) {
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + activity.getLocalClassName() +
" did not call through to super.onConfigurationChanged()");
}
activity.mConfigChangeFlags = 0;
activity.mCurrentConfig = new Configuration(config);
}
}
}
这就是整个onConfigureChange回凋流程。
其实不仅仅是onConfigureChange遵循这个流程,像按键消息、触摸消息也是这么一个流程