安卓开发那么多年还是第一次看Android 的main方法
他在ActivityThread这个类里面
public static void main(String[] args) {
//开启追踪 说白了就是写Systrace日志,然后给性能调试使用,调用的是native方法
//使用system/core/include/cutils/trace.h. 和 frameworks/native/cmds/atrace/atrace.cpp.
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
//hook 系统的 CloseGuard 类,该类是用于监测某些类是否正常关闭的,比如 cursor,现在把这个检测先关闭
CloseGuard.setEnabled(false);
//初始化环境变量实际上就是得到一个当前进程的用户id
//实际通过system/core/libcutils/multiuser.c 获取
Environment.initForCurrentUser();
// 往核心库里面写日志
EventLogger.setReporter(new EventLoggingReporter());
//读取ca证书的位置路径是/data/misc/user/($userId) 然后data是通过环境变量获取的,此外Environment.getUserConfigDirectory这是个过时的方法
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
//设置进程名
Process.setArgV0("<pre-initialized>");
//通过ThreadLocal创建一个Looper ,一个线程只能有一个,主线程在这里创建, 主线程的是false即不能通过quit方法退出
Looper.prepareMainLooper();
// 序列号的标识符。 与此进程启动相关联。 它将在进程开始时作为参数之一提供。
// 参数格式"seq=114" ,即startSeq最后可能等于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();
thread.attach(false, startSeq);
//初始化主线程的Handler
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// 完成初始化发送事件结束
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
//主线程进入循环状态
Looper.loop();
//主线程循环意外退出
throw new RuntimeException("Main thread loop unexpectedly exited");
}
thread.attach(false, startSeq);
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {//主线程
//设置首次绘制页面时 开启JIT实时编译
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
//给Track发送应用名称APNM给DDMS使用
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId());
//把ApplicationThread中的Binder交给ART 虚拟机,这东西是预编译的
RuntimeInit.setApplicationObject(mAppThread.asBinder());
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 {
mgr.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);
}
}
// add dropbox logging to libcore
DropBox.setReporter(new DropBoxReporter());
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);
}
网友评论