简介
回顾我们上一次说的一个app进程的启动过程,比如现在是当我们点击桌面上应用的图标,就会通过AMS,也就是system_server进程去和zygoteinit所在进程也就是zygote进程通过socket方式将启动进程所需要的参数传递给zygote,zygote在一个循环中一直在监听,当监有数据到来时候将数据封装之后fork出来子进程,子进程创建完成之后做一些Android环境的初始化,最终通过抛出异常的方式将调用到ActivityThread.main方法中。
我们今天的主题就接着上次说,开始我们可见的app之旅吧。
简介
回顾我们上一次说的一个app进程的启动过程,比如现在是当我们点击桌面上应用的图标,就会通过AMS,也就是system_server进程去和zygoteinit所在进程也就是zygote进程通过socket方式将启动进程所需要的参数传递给zygote,zygote在一个循环中一直在监听,当监有数据到来时候将数据封装之后fork出来子进程,子进程创建完成之后做一些Android环境的初始化,最终通过抛出异常的方式将调用到ActivityThread.main方法中。
我们今天的主题就接着上次说,开始我们可见的app之旅吧。
扫个盲
//ZygoteInit.main()
public static void main(String argv[]) {
try {
runSelectLoop(abiList);
....
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
closeServerSocket();
throw ex;
}
}
我们昨天一开始就执行这段代码,这段代码最终又跑去子进程的这段代码中caller.run();
所以故事发生在主线程
1. ActivityThread.main()
public static void main(String[] args) {
//性能统计默认是关闭的
SamplingProfilerIntegration.start();
//将当前进程所在userId赋值给sCurrentUser
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
AndroidKeyStoreProvider.install();
//确保可信任的CA证书存放在正确的位置
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("");
//创建主线程的Looper对象, 该Looper是不运行退出
Looper.prepareMainLooper();
//创建ActivityThread对象
ActivityThread thread = new ActivityThread();
//建立Binder通道
thread.attach(false);//[2]
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// 当设置为true时,可打开消息队列的debug log信息
if (false) {
Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop(); //消息循环运行
throw new RuntimeException("Main thread loop unexpectedly exited");
}
这里注意事项:
ActivityThread还有一个地方可以创建就是在:
SystemServer.run()
createSystemContext()
ActivityThread.systemMain()
ActivityThread thread = new ActivityThread();
thread.attach(true);//这里是true
小节上面:
- 创建主线程的Looper对象, 该Looper是不运行退出
- 创建ActivityThread对象
我们还要注意,在创建AT中发生了什么:
- 创建了ResourcesManager对象
ActivityThread() {
mResourcesManager = ResourcesManager.getInstance();
}
- 成员变量中创建了
ApplicationThread mAppThread = new ApplicationThread();
-
H mH = new H();
给主线程发送消息的Handler对象
2. ActivityThread.attach()
ActivityThread.java
//这里system=false
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
//开启虚拟机的jit即时编译功能
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("", UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
//创建ActivityManagerProxy对象
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//调用基于IActivityManager接口的Binder通道
mgr.attachApplication(mAppThread);//[3]
} catch (RemoteException ex) {
}
//观察是否快接近heap的上限
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)) {
mSomeActivitiesChanged = false;
try {
//当已用内存超过最大内存的3/4,则请求释放内存空间
mgr.releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
}
}
}
});
} else {
...
}
//添加dropbox日志到libcore
DropBox.setReporter(new DropBoxReporter());
//添加Config回调接口
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mResourcesManager) {
if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(newConfig)) {
mPendingConfiguration = newConfig;
sendMessage(H.CONFIGURATION_CHANGED, newConfig);
}
}
}
}
@Override
public void onLowMemory() {
}
@Override
public void onTrimMemory(int level) {
}
});
}
这里做的事情:
- ensureJitEnabled();具体是啥不知道
-
android.ddm.DdmHandleAppName.setAppName("
设置进程名",UserHandle.myUserId()); - 创建AMP
- 给AMP绑定ApplicationThread对象
- 看app进程内存情况,如果太大则释放内存
- 给ViewRootImpl添加一个config的回调接口
这里需要注意:
final IActivityManager mgr = ActivityManagerNative.getDefault();
static public IActivityManager getDefault() {
return gDefault.get();
}
这里得到的Service是activity,activity是在SystemServer中通过AMS.setSystemProcess()中添加的服务,对应AMS
private static final Singleton gDefault = new Singleton() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
3. AMS.attachApplication()
ActivityManagerService.java
在这里我们把握一个核心,这里子进程已经通过Binder调用到了AMS所在进程,也就是system_server进程了
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {//此pid是调用者的pid
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid); // 根据pid获取ProcessRecord对象
}
} else {
app = null;
}
if (app == null) {
if (pid > 0 && pid != MY_PID) {
//ProcessRecord为空,则杀掉该进程
Process.killProcessQuiet(pid);
} else {
//退出新建进程的Looper
thread.scheduleExit();
}
return false;
}
//还刚进入attach过程,此时thread应该为null,若不为null则表示该app附到上一个进程,则立刻清空
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}
final String processName = app.processName;
try {
//绑定死亡通知,注意这里是ApplicationThread的代理对象要linkToDeath
//也就是如果ApplicationThread(继承Binder)挂掉了在AppDeathRecipient中可以接收到信息
AppDeathRecipient adr = new AppDeathRecipient(app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
startProcessLocked(app, "link fail", processName); //重新启动进程
return false;
}
//重置进程信息
app.makeActive(thread, mProcessStats); //执行完该语句,则app.thread便不再为空
app.curAdj = app.setAdj = -100;
app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
app.forcingToForeground = null;
updateProcessForegroundLocked(app, false, false);
app.hasShownUi = false;
app.debugging = false;
app.cached = false;
app.killedByAm = false;
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); //移除进程启动超时的消息,这里超时是在AMS启动进程时候加上去的,所以这里一旦启动就要移除
//系统处于ready状态或者该app为FLAG_PERSISTENT进程,则为true
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
//app进程存在正在启动中的provider,则超时10s后发送CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息
//这里已经开始provider的操作了
if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
}
try {
...
//获取应用appInfo
ApplicationInfo appInfo = app.instrumentationInfo != null
? app.instrumentationInfo : app.info;
...
// 绑定应用[4]
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
//更新进程LRU队列
updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
app.resetPackageList(mProcessStats);
app.unlinkDeathRecipient();
//每当bind操作失败,则重启启动进程, 此处有可能会导致进程无限重启
startProcessLocked(app, "bind fail", processName);
return false;
}
mPersistentStartingProcesses.remove(app);
mProcessesOnHold.remove(app);
boolean badApp = false;
boolean didSomething = false;
//Activity: 检查最顶层可见的Activity是否等待在该进程中运行
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
badApp = true;
}
}
//Service: 寻找所有需要在该进程中运行的服务
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
badApp = true;
}
}
//Broadcast: 检查是否在这个进程中有下一个广播接收者
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
try {
didSomething |= sendPendingBroadcastsLocked(app);
} catch (Exception e) {
badApp = true;
}
}
//检查是否在这个进程中有下一个backup代理
if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
try {
thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
mBackupTarget.backupMode);
} catch (Exception e) {
badApp = true;
}
}
if (badApp) { //杀掉bad应用
app.kill("error during init", true);
handleAppDiedLocked(app, false, true);
return false;
}
if (!didSomething) {
updateOomAdjLocked(); //更新adj的值
}
return true;
}
我们这里必须小节一下:
- 设置代表该应用进程的ProcessRecord对象的一些成员变量
- 初步设置oo_adj的值,这个是进程优先级核心
- 撤销PROC_START+TIMEOUT_MSG对应操作
- 调用ApplicationThread的binderApplication
- 通知应用进程启动Acivity,Service等组件其中用于启动activity的函数是realStartActivityLocked
4. ApplicationThread.bindApplication()
我们通过APP所在进程,然后通过binder跨到AMS,通过AMS做一些处理之后,然后又调用到APP的进程中保存一些AMS处理过后的信息
public final void bindApplication(String processName, ApplicationInfo appInfo,
List 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) {
if (services != null) {
//保存AMS传递来系统service的信息
ServiceManager.initServiceCache(services);
}
setCoreSettings(coreSettings);//给主线程发消息H.SET_CORE_SETTINGS保存coreSettings的值
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;
sendMessage(H.BIND_APPLICATION, data);//[5]给主线程发送消息BIND_APPLICATION,将data传递过去
}
其中setCoreSettings(coreSettings);
这一句也很重要
private void handleSetCoreSettings(Bundle coreSettings) {
synchronized (mResourcesManager) {
mCoreSettings = coreSettings;
}
onCoreSettingsChange();
}
private void onCoreSettingsChange() {
boolean debugViewAttributes = mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
if (debugViewAttributes != View.mDebugViewAttributes) {
View.mDebugViewAttributes = debugViewAttributes;
// 由于发生改变, 请求所有的activities重启启动
for (Map.Entry entry : mActivities.entrySet()) {
requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false);
}
}
}
5. ActivityThread.handleBindApplication(data);
private void handleBindApplication(AppBindData data) {
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
mCompatConfiguration = new Configuration(data.config);
...
//设置进程名, 也就是说进程名是在进程真正创建以后的BIND_APPLICATION过程中才取名,前面那个名字不算
Process.setArgV0(data.processName);
android.ddm.DdmHandleAppName.setAppName(data.processName, UserHandle.myUserId());
if (data.persistent) {
//低内存设备, persistent进程不采用硬件加速绘制,以节省内存使用量
if (!ActivityManager.isHighEndGfx()) {
HardwareRenderer.disable(false);
}
}
//重置时区
TimeZone.setDefault(null);
Locale.setDefault(data.config.locale);
//更新系统配置
mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
mCurDefaultDisplayDpi = data.config.densityDpi;
applyCompatConfiguration(mCurDefaultDisplayDpi);
//获取LoadedApk对象[5.1]
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
...
// 创建ContextImpl上下文
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
if (!Process.isIsolated()) {
final File cacheDir = appContext.getCacheDir();
if (cacheDir != null) {
System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
}
//用于存储产生/编译的图形代码
final File codeCacheDir = appContext.getCodeCacheDir();
if (codeCacheDir != null) {
setupGraphicsSupport(data.info, codeCacheDir);
}
}
...
//当处于调试模式,则运行应用生成systrace信息
boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;
Trace.setAppTracingAllowed(appTracingAllowed);
//初始化 默认的http代理
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
if (b != null) {
IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
Proxy.setHttpProxySystemProperty(proxyInfo);
}
if (data.instrumentationName != null) {
...
} else {
mInstrumentation = new Instrumentation();
}
//FLAG_LARGE_HEAP则清除内存增长上限
if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
} else {
dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
}
try {
// 此处data.info是指LoadedApk, 通过反射创建目标应用Application对象[5.2]
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
if (!data.restrictedBackupMode) {
List providers = data.providers;
if (providers != null) {
installContentProviders(app, providers);
mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
}
}
mInstrumentation.onCreate(data.instrumentationArgs);
//调用Application.onCreate()回调方法.
mInstrumentation.callApplicationOnCreate(app);
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
小节:
- 创建一个Application对象,该对象是本进程中运行的第一个Application,是通过指LoadedApk
- 如果该Application有ContentProvider则应该安装他们
在这里就开始创建ContentProvider了,所以ContentProvider的创建比其他组件要早。
5.1 ActivityThread.getPackageInfoNoCheck()
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
CompatibilityInfo compatInfo) {
return getPackageInfo(ai, compatInfo, null, false, true, false);
}
private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
boolean registerPackage) {
final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
synchronized (mResourcesManager) {
WeakReference ref;
if (differentUser) {
// Caching not supported across users
ref = null;
} else if (includeCode) {
ref = mPackages.get(aInfo.packageName);
} else {
ref = mResourcePackages.get(aInfo.packageName);
}
LoadedApk packageInfo = ref != null ? ref.get() : null;
if (packageInfo == null || (packageInfo.mResources != null
&& !packageInfo.mResources.getAssets().isUpToDate())) {
packageInfo =
new LoadedApk(this, aInfo, compatInfo, baseLoader,
securityViolation, includeCode &&
(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
if (mSystemThread && "android".equals(aInfo.packageName)) {
packageInfo.installSystemApplicationInfo(aInfo,
getSystemContext().mPackageInfo.getClassLoader());
}
if (differentUser) {
// Caching not supported across users
} else if (includeCode) {
mPackages.put(aInfo.packageName,
new WeakReference(packageInfo));
} else {
mResourcePackages.put(aInfo.packageName,
new WeakReference(packageInfo));
}
}
return packageInfo;
}
}
5.1做的事情主要就是创建了LoadedApk然后返回
5.2 LoadedApk.makeApplication()
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";//默认在这里
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"initializeJavaContextClassLoader");
initializeJavaContextClassLoader();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);//创建ContextImpl对象
//创建Application对象, 该对象名来自于mApplicationInfo.className.
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
...
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
}
}
// Rewrite the R 'constants' for all library apks.
SparseArray packageIdentifiers = getAssets(mActivityThread)
.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;
}
//写R常量
rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
}
return app;
}
主要做了三件事
- 创建ContextImpl对象
- 创建Application对象, 该对象名来自于mApplicationInfo.className.
- 重写了R常量
扫个盲
//ZygoteInit.main()
public static void main(String argv[]) {
try {
runSelectLoop(abiList);
....
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
closeServerSocket();
throw ex;
}
}
我们昨天一开始就执行这段代码,这段代码最终又跑去子进程的这段代码中caller.run();
所以故事发生在主线程
1. ActivityThread.main()
public static void main(String[] args) {
//性能统计默认是关闭的
SamplingProfilerIntegration.start();
//将当前进程所在userId赋值给sCurrentUser
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
AndroidKeyStoreProvider.install();
//确保可信任的CA证书存放在正确的位置
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("");
//创建主线程的Looper对象, 该Looper是不运行退出
Looper.prepareMainLooper();
//创建ActivityThread对象
ActivityThread thread = new ActivityThread();
//建立Binder通道
thread.attach(false);//[2]
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// 当设置为true时,可打开消息队列的debug log信息
if (false) {
Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop(); //消息循环运行
throw new RuntimeException("Main thread loop unexpectedly exited");
}
这里注意事项:
ActivityThread还有一个地方可以创建就是在:
SystemServer.run()
createSystemContext()
ActivityThread.systemMain()
ActivityThread thread = new ActivityThread();
thread.attach(true);//这里是true
小节上面:
- 创建主线程的Looper对象, 该Looper是不运行退出
- 创建ActivityThread对象
我们还要注意,在创建AT中发生了什么:
- 创建了ResourcesManager对象
ActivityThread() {
mResourcesManager = ResourcesManager.getInstance();
}
- 成员变量中创建了
ApplicationThread mAppThread = new ApplicationThread();
-
H mH = new H();
给主线程发送消息的Handler对象
2. ActivityThread.attach()
ActivityThread.java
//这里system=false
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
//开启虚拟机的jit即时编译功能
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("", UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
//创建ActivityManagerProxy对象
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//调用基于IActivityManager接口的Binder通道
mgr.attachApplication(mAppThread);//[3]
} catch (RemoteException ex) {
}
//观察是否快接近heap的上限
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)) {
mSomeActivitiesChanged = false;
try {
//当已用内存超过最大内存的3/4,则请求释放内存空间
mgr.releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
}
}
}
});
} else {
...
}
//添加dropbox日志到libcore
DropBox.setReporter(new DropBoxReporter());
//添加Config回调接口
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mResourcesManager) {
if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(newConfig)) {
mPendingConfiguration = newConfig;
sendMessage(H.CONFIGURATION_CHANGED, newConfig);
}
}
}
}
@Override
public void onLowMemory() {
}
@Override
public void onTrimMemory(int level) {
}
});
}
这里做的事情:
- ensureJitEnabled();具体是啥不知道
-
android.ddm.DdmHandleAppName.setAppName("
设置进程名",UserHandle.myUserId()); - 创建AMP
- 给AMP绑定ApplicationThread对象
- 看app进程内存情况,如果太大则释放内存
- 给ViewRootImpl添加一个config的回调接口
这里需要注意:
final IActivityManager mgr = ActivityManagerNative.getDefault();
static public IActivityManager getDefault() {
return gDefault.get();
}
这里得到的Service是activity,activity是在SystemServer中通过AMS.setSystemProcess()中添加的服务,对应AMS
private static final Singleton gDefault = new Singleton() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
3. AMS.attachApplication()
ActivityManagerService.java
在这里我们把握一个核心,这里子进程已经通过Binder调用到了AMS所在进程,也就是system_server进程了
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {//此pid是调用者的pid
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid); // 根据pid获取ProcessRecord对象
}
} else {
app = null;
}
if (app == null) {
if (pid > 0 && pid != MY_PID) {
//ProcessRecord为空,则杀掉该进程
Process.killProcessQuiet(pid);
} else {
//退出新建进程的Looper
thread.scheduleExit();
}
return false;
}
//还刚进入attach过程,此时thread应该为null,若不为null则表示该app附到上一个进程,则立刻清空
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}
final String processName = app.processName;
try {
//绑定死亡通知,注意这里是ApplicationThread的代理对象要linkToDeath
//也就是如果ApplicationThread(继承Binder)挂掉了在AppDeathRecipient中可以接收到信息
AppDeathRecipient adr = new AppDeathRecipient(app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
startProcessLocked(app, "link fail", processName); //重新启动进程
return false;
}
//重置进程信息
app.makeActive(thread, mProcessStats); //执行完该语句,则app.thread便不再为空
app.curAdj = app.setAdj = -100;
app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
app.forcingToForeground = null;
updateProcessForegroundLocked(app, false, false);
app.hasShownUi = false;
app.debugging = false;
app.cached = false;
app.killedByAm = false;
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); //移除进程启动超时的消息,这里超时是在AMS启动进程时候加上去的,所以这里一旦启动就要移除
//系统处于ready状态或者该app为FLAG_PERSISTENT进程,则为true
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
//app进程存在正在启动中的provider,则超时10s后发送CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG消息
//这里已经开始provider的操作了
if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
}
try {
...
//获取应用appInfo
ApplicationInfo appInfo = app.instrumentationInfo != null
? app.instrumentationInfo : app.info;
...
// 绑定应用[4]
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
//更新进程LRU队列
updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
app.resetPackageList(mProcessStats);
app.unlinkDeathRecipient();
//每当bind操作失败,则重启启动进程, 此处有可能会导致进程无限重启
startProcessLocked(app, "bind fail", processName);
return false;
}
mPersistentStartingProcesses.remove(app);
mProcessesOnHold.remove(app);
boolean badApp = false;
boolean didSomething = false;
//Activity: 检查最顶层可见的Activity是否等待在该进程中运行
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
badApp = true;
}
}
//Service: 寻找所有需要在该进程中运行的服务
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
badApp = true;
}
}
//Broadcast: 检查是否在这个进程中有下一个广播接收者
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
try {
didSomething |= sendPendingBroadcastsLocked(app);
} catch (Exception e) {
badApp = true;
}
}
//检查是否在这个进程中有下一个backup代理
if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
try {
thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
mBackupTarget.backupMode);
} catch (Exception e) {
badApp = true;
}
}
if (badApp) { //杀掉bad应用
app.kill("error during init", true);
handleAppDiedLocked(app, false, true);
return false;
}
if (!didSomething) {
updateOomAdjLocked(); //更新adj的值
}
return true;
}
我们这里必须小节一下:
- 设置代表该应用进程的ProcessRecord对象的一些成员变量
- 初步设置oo_adj的值,这个是进程优先级核心
- 撤销PROC_START+TIMEOUT_MSG对应操作
- 调用ApplicationThread的binderApplication
- 通知应用进程启动Acivity,Service等组件其中用于启动activity的函数是realStartActivityLocked
4. ApplicationThread.bindApplication()
我们通过APP所在进程,然后通过binder跨到AMS,通过AMS做一些处理之后,然后又调用到APP的进程中保存一些AMS处理过后的信息
public final void bindApplication(String processName, ApplicationInfo appInfo,
List 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) {
if (services != null) {
//保存AMS传递来系统service的信息
ServiceManager.initServiceCache(services);
}
setCoreSettings(coreSettings);//给主线程发消息H.SET_CORE_SETTINGS保存coreSettings的值
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;
sendMessage(H.BIND_APPLICATION, data);//[5]给主线程发送消息BIND_APPLICATION,将data传递过去
}
其中setCoreSettings(coreSettings);
这一句也很重要
private void handleSetCoreSettings(Bundle coreSettings) {
synchronized (mResourcesManager) {
mCoreSettings = coreSettings;
}
onCoreSettingsChange();
}
private void onCoreSettingsChange() {
boolean debugViewAttributes = mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
if (debugViewAttributes != View.mDebugViewAttributes) {
View.mDebugViewAttributes = debugViewAttributes;
// 由于发生改变, 请求所有的activities重启启动
for (Map.Entry entry : mActivities.entrySet()) {
requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false);
}
}
}
5. ActivityThread.handleBindApplication(data);
private void handleBindApplication(AppBindData data) {
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
mCompatConfiguration = new Configuration(data.config);
...
//设置进程名, 也就是说进程名是在进程真正创建以后的BIND_APPLICATION过程中才取名,前面那个名字不算
Process.setArgV0(data.processName);
android.ddm.DdmHandleAppName.setAppName(data.processName, UserHandle.myUserId());
if (data.persistent) {
//低内存设备, persistent进程不采用硬件加速绘制,以节省内存使用量
if (!ActivityManager.isHighEndGfx()) {
HardwareRenderer.disable(false);
}
}
//重置时区
TimeZone.setDefault(null);
Locale.setDefault(data.config.locale);
//更新系统配置
mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
mCurDefaultDisplayDpi = data.config.densityDpi;
applyCompatConfiguration(mCurDefaultDisplayDpi);
//获取LoadedApk对象[5.1]
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
...
// 创建ContextImpl上下文
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
if (!Process.isIsolated()) {
final File cacheDir = appContext.getCacheDir();
if (cacheDir != null) {
System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
}
//用于存储产生/编译的图形代码
final File codeCacheDir = appContext.getCodeCacheDir();
if (codeCacheDir != null) {
setupGraphicsSupport(data.info, codeCacheDir);
}
}
...
//当处于调试模式,则运行应用生成systrace信息
boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;
Trace.setAppTracingAllowed(appTracingAllowed);
//初始化 默认的http代理
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
if (b != null) {
IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
Proxy.setHttpProxySystemProperty(proxyInfo);
}
if (data.instrumentationName != null) {
...
} else {
mInstrumentation = new Instrumentation();
}
//FLAG_LARGE_HEAP则清除内存增长上限
if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
} else {
dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
}
try {
// 此处data.info是指LoadedApk, 通过反射创建目标应用Application对象[5.2]
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
if (!data.restrictedBackupMode) {
List providers = data.providers;
if (providers != null) {
installContentProviders(app, providers);
mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
}
}
mInstrumentation.onCreate(data.instrumentationArgs);
//调用Application.onCreate()回调方法.
mInstrumentation.callApplicationOnCreate(app);
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
小节:
- 创建一个Application对象,该对象是本进程中运行的第一个Application,是通过指LoadedApk
- 如果该Application有ContentProvider则应该安装他们
在这里就开始创建ContentProvider了,所以ContentProvider的创建比其他组件要早。
5.1 ActivityThread.getPackageInfoNoCheck()
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
CompatibilityInfo compatInfo) {
return getPackageInfo(ai, compatInfo, null, false, true, false);
}
private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
boolean registerPackage) {
final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
synchronized (mResourcesManager) {
WeakReference ref;
if (differentUser) {
// Caching not supported across users
ref = null;
} else if (includeCode) {
ref = mPackages.get(aInfo.packageName);
} else {
ref = mResourcePackages.get(aInfo.packageName);
}
LoadedApk packageInfo = ref != null ? ref.get() : null;
if (packageInfo == null || (packageInfo.mResources != null
&& !packageInfo.mResources.getAssets().isUpToDate())) {
packageInfo =
new LoadedApk(this, aInfo, compatInfo, baseLoader,
securityViolation, includeCode &&
(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
if (mSystemThread && "android".equals(aInfo.packageName)) {
packageInfo.installSystemApplicationInfo(aInfo,
getSystemContext().mPackageInfo.getClassLoader());
}
if (differentUser) {
// Caching not supported across users
} else if (includeCode) {
mPackages.put(aInfo.packageName,
new WeakReference(packageInfo));
} else {
mResourcePackages.put(aInfo.packageName,
new WeakReference(packageInfo));
}
}
return packageInfo;
}
}
5.1做的事情主要就是创建了LoadedApk然后返回
5.2 LoadedApk.makeApplication()
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";//默认在这里
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"initializeJavaContextClassLoader");
initializeJavaContextClassLoader();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);//创建ContextImpl对象
//创建Application对象, 该对象名来自于mApplicationInfo.className.
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
...
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
}
}
// Rewrite the R 'constants' for all library apks.
SparseArray packageIdentifiers = getAssets(mActivityThread)
.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;
}
//写R常量
rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
}
return app;
}
主要做了三件事
- 创建ContextImpl对象
- 创建Application对象, 该对象名来自于mApplicationInfo.className.
- 重写了R常量