ActivityThread作为应用的主线程,是我们平时android开发中接触最多的一个线程,本文会分析ActivityThread.java这个类里面的一些关键方法和成员变量,通过这些分析,会理清楚,如下问题
分析ActivityThread,我们要关注几个关键词:
熟悉进程启动流程的都知道,ActivityThrad的main函数是在,进程创建完成后有zytegote最终通过反射调用的
/**
* Invokes a static "main(argv[]) method on class "className".
* Converts various failing exceptions into RuntimeExceptions, with
* the assumption that they will then cause the VM instance to exit.
*
* @param className Fully-qualified class name
* @param argv Argument vector for main()
* @param classLoader the classLoader to load {@className} with
*/
private static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
/*
* This throw gets caught in ZygoteInit.main(), which responds
* by invoking the exception's run() method. This arrangement
* clears up all the stack frames that were required in setting
* up the process.
*/
return new MethodAndArgsCaller(m, argv);
}
在main()中调用了attach(), 这个函数将会把应用的代理线程传给system_server,system_server通过这个代理来,通知应用的生命周期状态等等变更
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
// Install selective syscall interception
AndroidOs.install();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("");
Looper.prepareMainLooper();
// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
// It will be in the format "seq=114"
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();
// 调用了attach,这个函数将会把应用的代理线程传给system_server,
// system_server通过这个代理来,通知应用的生命周期状态等等变更
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
在android 最常用的进程间通信的方式就是binder,我们来看一下atttach,这个函数,这个函数,建立了应用进程和system_server进程,双向通信的通道,应用如果要和system_server进程,或者说和AMS这个服务通信,就通过到AMS的代理IActivityManager,同时,应用进程会把,mAppThread(ApplicationThread的对象,ApplicationThread extends IApplicationThread.Stub )这个应用进程的代理,传递给AMS,这样就实现了双向通信,实际上就是通过binder来实现相互通信的
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
android.ddm.DdmHandleAppName.setAppName("",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
// 应用如果要和system_server进程,或者说和AMS这个服务通信,就通过到
// AMS的代理,同时,应用进程会把,mAppThread这个应用进程的代理,传递给
// AMS,这样就实现了双向通信
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
// Watch for getting close to heap limit.
BinderInternal.addGcWatcher(new Runnable() {
@Override public void run() {
if (!mSomeActivitiesChanged) {
return;
}
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.maxMemory();
long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
if (dalvikUsed > ((3*dalvikMax)/4)) {
if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
+ " total=" + (runtime.totalMemory()/1024)
+ " used=" + (dalvikUsed/1024));
mSomeActivitiesChanged = false;
try {
ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
});
} 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());
try {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
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 /* compat */)) {
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);
}
三、H()
线程之间如何通信呢:Handler,handleMessage,sendMessage。H()函数的主要作用就是,把system_server通过应用的代理IApplicationThread,来给应用发送相关消息,最终通过通过在handleMessage中回调到应用的主线程。
在ActivityThread中,应用通过持有AMS的代理IActivityManager,和把自己的代理IApplicationThread通过attach函数传递给system_server,来建立一个进程间的双向通信的渠道。通过,Handler,handleMessage,sendMessage,来实现ApplicationThread和ActivityThread线程间通信,把消息发送给主线程,让主线程完成相关生命周期函数调用。