0%

Android-Application

概述

android系统会为每个程序进程的运行时创建一个Application类的对象且仅创建一个,且application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局的单例的,所以在不同的Activity,Service中获得的对象都是同一个对象。所以通过Application来进行一些,数据传递,数据共享等,数据缓存等操作。

注:本文基于Android 9.0源码,为了文章的简洁性,引用源码的地方可能有所删减。

多进程

不同的进程会有自己的Application实例,如果应用中采用多进程方式,onCreate方法会执行多次,可以根据不同的进程名字进行不同的初始化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class MyApplication extends Application {
private final static String PROCESS_NAME = "com.hearing";
private static MyApplication myApplication = null;

public static MyApplication getApplication() {
return myApplication;
}

/**
* 判断是不是UI主进程,因为有些东西只能在UI主进程初始化
*/
public static boolean isAppMainProcess() {
try {
int pid = android.os.Process.myPid();
String process = getAppNameByPID(MyApplication.getApplication(), pid);
if (TextUtils.isEmpty(process)) {
return true;
} else if (PROCESS_NAME.equalsIgnoreCase(process)) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return true;
}
}

/**
* 根据Pid得到进程名
*/
public static String getAppNameByPID(Context context, int pid) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (android.app.ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
if (processInfo.pid == pid) {
return processInfo.processName;
}
}
return "";
}

@Override
public void onCreate() {
super.onCreate();

myApplication = this;

if (isAppMainProcess()) {
//do something for init
}
}
}

生命周期

onCreate

在创建应用程序时创建

onTerminate

当终止应用程序对象时调用,不保证一定被调用,当程序是被内核终止以便为其他应用程序释放资源,那么将不会提醒,并且不调用应用程序的对象的onTerminate方法而直接终止进程

onLowMemory

当后台程序已经终止资源还匮乏时会调用这个方法。好的应用程序一般会在这个方法里面释放一些不必要的资源来应付当后台程序已经终止,前台应用程序内存还不够时的情况。

onTrimMemory

当系统回调确认该进程是时候回收不必要的内存了,这将例如发生在后台时,没有足够的内存保持尽可能多的后台进程运行一样。一般发生在点击Home键、Task任务菜单键时被执行。

onConfigurationChanged

配置改变时触发这个方法

ActivityLifecycleCallbacks

概述

ActivityLifecycleCallbacks 是用来监听所有 Activity 的生命周期回调。接口定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface ActivityLifecycleCallbacks {
// 当Activity调用Activity#onCreate时调用
void onActivityCreated(Activity activity, Bundle savedInstanceState);
// 当Activity调用Activity#onStart时调用
void onActivityStarted(Activity activity);
// 当Activity调用Activity#onResume时调用
void onActivityResumed(Activity activity);
// 当Activity调用Activity#onPause时调用
void onActivityPaused(Activity activity);
// 当Activity调用Activity#onStop时调用
void onActivityStopped(Activity activity);
// 当Activity调用Activity#onSaveInstanceState时调用
void onActivitySaveInstanceState(Activity activity, Bundle outState);
// 当Activity调用Activity#onDestroy时调用
void onActivityDestroyed(Activity activity);
}

使用:

1
2
3
4
5
6
7
8
public class MyApplication extends Application {

@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(mAppLifecycleCallbacks);
}
}

管理Activity栈

Activity 页面栈,最常用的实现就是用来完全退出应用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private static HashMap<Integer, WeakReference<Activity>> sActivities = new HashMap<>();

public void finishAllActivity() {
for (int i : sActivities.keySet()) {
if (sActivities.get(i) != null && sActivities.get(i).get() != null) {
Activity activity = sActivities.get(i).get();
if (!Util.isFinishingOrDestroyed(activity)) {
activity.finish();
}
}
}
sActivities.clear();
}

@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
WeakReference<Activity> wa = new WeakReference<>(activity);
sActivities.put(activity.hashCode(), wa);
}

@Override
public void onActivityDestroyed(Activity activity) {
sActivities.remove(activity.hashCode());
}

获取当前Activity

1
2
3
4
5
6
7
8
9
10
11
public Activity getCurrentActivity() {
if (sCurrentActivity == null) {
return null;
}
return sCurrentActivity.get();
}

@Override
public void onActivityResumed(Activity activity) {
sCurrentActivity = new WeakReference<>(activity);
}

判断应用前后台

方法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// ActivityLifecycleCallbacks.java
private volatile int appCount = 0;
private volatile boolean isForground = true;

@Override
public void onActivityStarted(Activity activity) {
synchronized (this) {
appCount++;
if (!isForground) {
isForground = true;
Log.e("AppLifecycle", "app into forground ");
}
}
}

@Override
public void onActivityStopped(Activity activity) {
synchronized (this) {
appCount--;
if (!isForgroundAppValue()) {
isForground = false;
Log.e("AppLifecycle", "app into background ");
}
}
}

private boolean isForgroundAppValue() {
synchronized (this) {
return appCount > 0;
}
}

方法二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
public class AppStatusObserver {
private static AppStatusObserver sInstance;

static final int EVENT_ON_ACTIVITY_RESUMED = 0;
static final int EVENT_ON_ACTIVITY_STOPPED = 1;

@AppStatus
private int mAppStatus = STATUS.STATUS_NONE;

public interface STATUS {
int STATUS_NONE = 0;
int STATUS_BACKGROUND = 1;
int STATUS_FOREGROUND = 2;
}

@Retention(RetentionPolicy.SOURCE)
@IntDef({STATUS.STATUS_BACKGROUND, STATUS.STATUS_FOREGROUND})
public @interface AppStatus {
}

private int mCurResumeActivityHC;
private Set<WeakReference> mWRListener;

private AppStatusObserver() {
mWRListener = new HashSet<>();
}

public boolean isAppInBackground() {
return mAppStatus == STATUS.STATUS_BACKGROUND;
}

public boolean isAppInForeground() {
return mAppStatus == STATUS.STATUS_FOREGROUND;
}

public void registerListener(IStatusChgListener listener) {
for (WeakReference w : mWRListener) {
IStatusChgListener l = (IStatusChgListener) w.get();
if (l == listener) {
return;
}
}
WeakReference<IStatusChgListener> w = new WeakReference<>(listener);
mWRListener.add(w);
}

public void unregisterListener(IStatusChgListener listener) {
for (WeakReference w : mWRListener) {
IStatusChgListener l = (IStatusChgListener) w.get();
if (l == listener) {
w.clear();
break;
}
}
}

void onActivityLifecycleEvent(@NonNull Activity activity, int event) {
synchronized (AppStatusObserver.class) {
switch (event) {
case EVENT_ON_ACTIVITY_RESUMED:
if (mAppStatus != STATUS.STATUS_FOREGROUND) {
if ((activity.hashCode() == mCurResumeActivityHC || mCurResumeActivityHC == 0)) {
notifyChange(STATUS.STATUS_FOREGROUND);
mAppStatus = STATUS.STATUS_FOREGROUND;
} else if (mAppStatus == STATUS.STATUS_BACKGROUND) {
notifyChange(STATUS.STATUS_FOREGROUND);
mAppStatus = STATUS.STATUS_FOREGROUND;
}
}
this.mCurResumeActivityHC = activity.hashCode();
break;
case EVENT_ON_ACTIVITY_STOPPED:
if (activity.hashCode() == mCurResumeActivityHC) {
notifyChange(STATUS.STATUS_BACKGROUND);
mAppStatus = STATUS.STATUS_BACKGROUND;
}
break;
}
}
}

private void notifyChange(@AppStatus int status) {
for (WeakReference w : mWRListener) {
IStatusChgListener listener = (IStatusChgListener) w.get();
if (listener != null) {
listener.onStatusChange(status);
}
}
}

public synchronized static AppStatusObserver getInstance() {
if (sInstance == null) {
sInstance = new AppStatusObserver();
}
return sInstance;
}

public interface IStatusChgListener {
void onStatusChange(@AppStatus int status);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
// ActivityLifecycleCallbacks.java
private AppStatusObserver mAppStatusChgObserver = AppStatusObserver.getInstance();

@Override
public void onActivityResumed(Activity activity) {
mAppStatusChgObserver.onActivityLifecycleEvent(activity, AppStatusObserver.EVENT_ON_ACTIVITY_RESUMED);
}

@Override
public void onActivityStopped(Activity activity) {
mAppStatusChgObserver.onActivityLifecycleEvent(activity, AppStatusObserver.EVENT_ON_ACTIVITY_STOPPED);
}

原理

system进程和app进程都运行着一个或多个app,每个app都会有一个对应的Application对象。本文将解析以下两种进程创建Application的过程:

  • system_server进程;
  • app进程;

system_server进程

SystemServer.main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// SystemServer.java
public final class SystemServer {
...
public static void main(String[] args) {
//先初始化SystemServer对象,再调用对象的run()方法
new SystemServer().run();
}
}

private void run() {
Looper.prepareMainLooper();// 准备主线程looper

//加载android_servers.so库,该库包含的源码在frameworks/base/services/目录下
System.loadLibrary("android_servers");

createSystemContext(); //初始化系统上下文

//创建系统服务管理
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

//启动各种系统服务
try {
startBootstrapServices(); // 启动引导服务
startCoreServices(); // 启动核心服务
startOtherServices(); // 启动其他服务
} catch (Throwable ex) {
throw ex;
}

//一直循环执行
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}

createSystemContext

1
2
3
4
5
6
7
8
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}

ActivityThread

构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public final class ActivityThread extends ClientTransactionHandler {
// 创建ApplicationThread对象
final ApplicationThread mAppThread = new ApplicationThread();
final Looper mLooper = Looper.myLooper();
// class H extends Handler
final H mH = new H();
// 当前进程中首次初始化的app对象
Application mInitialApplication;
final ArrayList<Application> mAllApplications = new ArrayList<Application>();
// 标记当前进程是否为system进程
boolean mSystemThread = false;
// 记录system进程的ContextImpl对象
private ContextImpl mSystemContext;
private ContextImpl mSystemUiContext;

final ArrayMap<String, WeakReference<LoadedApk>> mPackages = new ArrayMap<>();
final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages = new ArrayMap<>();
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
static volatile Handler sMainThreadHandler; // set once in main()
private static volatile ActivityThread sCurrentActivityThread;

ActivityThread() {
mResourcesManager = ResourcesManager.getInstance();
}
}

systemMain

1
2
3
4
5
6
7
8
9
10
11
12
13
public static ActivityThread systemMain() {
// The system process on low-memory devices do not get to use hardware
// accelerated drawing, since this can add too much overhead to the
// process.
if (!ActivityManager.isHighEndGfx()) {
ThreadedRenderer.disable(true);
} else {
ThreadedRenderer.enableForegroundTrimming();
}
ActivityThread thread = new ActivityThread();
thread.attach(true, 0);
return thread;
}

创建完ActivityThread对象,接下来执行attach()操作:

attach

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
// ...
} 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);
// mPackageInfo是LoadedApk对象
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);
}
}
// ...
}

public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
mSystemContext = ContextImpl.createSystemContext(this);
}
return mSystemContext;
}
}

ContextImpl

构造函数

部分成员变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
final @NonNull ActivityThread mMainThread;
final @NonNull LoadedApk mPackageInfo;
private @Nullable ClassLoader mClassLoader;

private final @Nullable IBinder mActivityToken;

private final String mBasePackageName;
private final String mOpPackageName;

private final @NonNull ResourcesManager mResourcesManager;
private @NonNull Resources mResources;
private @Nullable Display mDisplay; // may be null if default display

private PackageManager mPackageManager;

构造函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,
@NonNull LoadedApk packageInfo, @Nullable String splitName,
@Nullable IBinder activityToken, @Nullable UserHandle user, int flags,
@Nullable ClassLoader classLoader) {
// ...
mMainThread = mainThread;
mActivityToken = activityToken;
mFlags = flags;

// 将传入的LoadedApk赋值给了mPackageInfo
mPackageInfo = packageInfo;
mSplitName = splitName;
mClassLoader = classLoader;
mResourcesManager = ResourcesManager.getInstance();
// ...
}

createSystemContext

1
2
3
4
5
6
7
8
static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread);
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, null);
context.setResources(packageInfo.getResources());
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetrics());
return context;
}

createAppContext

1
2
3
4
5
6
7
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null,
null, null, 0, null);
context.setResources(packageInfo.getResources());
return context;
}

LoadedApk

构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
private final ActivityThread mActivityThread;
final String mPackageName;
private ApplicationInfo mApplicationInfo;
private String mAppDir;
private String mResDir;
private String[] mOverlayDirs;
private String mDataDir;
private String mLibDir;
private File mDataDirFile;
private File mDeviceProtectedDataDirFile;
private File mCredentialProtectedDataDirFile;
private final ClassLoader mBaseClassLoader;
private final boolean mSecurityViolation;
private final boolean mIncludeCode;
private final boolean mRegisterPackage;
private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
/** WARNING: This may change. Don't hold external references to it. */
Resources mResources;
private ClassLoader mClassLoader;
private Application mApplication;

private String[] mSplitNames;
private String[] mSplitAppDirs;
private String[] mSplitResDirs;
private String[] mSplitClassLoaderNames;

private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers = new ArrayMap<>();
private final ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers = new ArrayMap<>();
private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices = new ArrayMap<>();
private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices = new ArrayMap<>();

LoadedApk(ActivityThread activityThread) {
mActivityThread = activityThread;
mApplicationInfo = new ApplicationInfo();
mApplicationInfo.packageName = "android";
mPackageName = "android";
mAppDir = null;
mResDir = null;
mSplitAppDirs = null;
mSplitResDirs = null;
mSplitClassLoaderNames = null;
mOverlayDirs = null;
mDataDir = null;
mDataDirFile = null;
mDeviceProtectedDataDirFile = null;
mCredentialProtectedDataDirFile = null;
mLibDir = null;
mBaseClassLoader = null;
mSecurityViolation = false;
mIncludeCode = true;
mRegisterPackage = false;
mClassLoader = ClassLoader.getSystemClassLoader();
mResources = Resources.getSystem();
mAppComponentFactory = createAppFactory(mApplicationInfo, mClassLoader);
}

makeApplication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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")) {
initializeJavaContextClassLoader();
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
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.
// ...
return app;
}

getClassLoader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public ClassLoader getClassLoader() {
synchronized (this) {
if (mClassLoader == null) {
createOrUpdateClassLoaderLocked(null /*addedPaths*/);
}
return mClassLoader;
}
}

private void createOrUpdateClassLoaderLocked(List<String> addedPaths) {
if (mPackageName.equals("android")) {
// Note: This branch is taken for system server and we don't need to setup
// jit profiling support.
if (mClassLoader != null) {
// nothing to update
return;
}

if (mBaseClassLoader != null) {
mClassLoader = mBaseClassLoader;
} else {
mClassLoader = ClassLoader.getSystemClassLoader();
}
mAppComponentFactory = createAppFactory(mApplicationInfo, mClassLoader);

return;
}
// ...
}

// ClassLoader.java
public static ClassLoader getSystemClassLoader() {
return SystemClassLoader.loader;
}

static private class SystemClassLoader {
public static ClassLoader loader = ClassLoader.createSystemClassLoader();
}

private static ClassLoader createSystemClassLoader() {
String classPath = System.getProperty("java.class.path", ".");
String librarySearchPath = System.getProperty("java.library.path", "");
return new PathClassLoader(classPath, librarySearchPath, BootClassLoader.getInstance());
}

Instrumentation.newApplication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Instrumentation.java
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
// private AppComponentFactory getFactory(String pkg) {}
Application app = getFactory(context.getPackageName())
.instantiateApplication(cl, className);
app.attach(context);
return app;
}

// frameworks/base/core/java/android/app/AppComponentFactory.java
public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
@NonNull String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Application) cl.loadClass(className).newInstance();
}

接着是Application.attach()方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Application.java
final void attach(Context context) {
attachBaseContext(context); // Application的mBase
// ContextImpl.getImpl(context)返回的就是context自身
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}

// class ContextImpl extends Context {}
// ContextImpl.java
static ContextImpl getImpl(Context context) {
Context nextContext;
while ((context instanceof ContextWrapper) &&
(nextContext=((ContextWrapper)context).getBaseContext()) != null) {
context = nextContext;
}
return (ContextImpl)context;
}

attch方法的主要功能:

  • 将新创建的ContextImpl对象保存到Application的父类成员变量mBase;
  • 将新创建的LoadedApk对象保存到Application的成员变量mLoadedApk;

如果想通过反射获取应用的ClassLoader,需要从LoadedApk对象中获取,LoadedApk对象也同样可以通过反射方式获取,它的实例在许多对象中都有引用,比如说:ContextImpl和Application中都有引用:

  • ContextImpl:如上代码中可以看到,在Application#attachBaseContext(Context base)回调中可以拿到ContextImpl实例,进一步可以获得LoadedApk对象;
  • Application:应注意到,在调用了attachBaseContext之后,Application中的mLoadedApk字段才被赋值,因此在attachBaseContext中反射获取到的LoadedApk会是null,可以在onCreate回调时再尝试反射调用。

App进程

ActivityThread

main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
// ...
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"
// ...
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);

if (sMainThreadHandler == null) {
// static volatile Handler sMainThreadHandler;
sMainThreadHandler = thread.getHandler();
}

Looper.loop();

throw new RuntimeException("Main thread loop unexpectedly exited");
}

这是运行在app进程,当进程由zygote fork后执行ActivityThread的main方法。

attach

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
// ...
} else {
// ...
}
}

mgr.attachApplication是通过Binder方式调用AMS中的方法。

H

在H内部类中定义了许多种message类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class H extends Handler {
public static final int BIND_APPLICATION = 110;
public static final int EXIT_APPLICATION = 111;
public static final int RECEIVER = 113;
public static final int CREATE_SERVICE = 114;
public static final int SERVICE_ARGS = 115;
public static final int STOP_SERVICE = 116;

public static final int CONFIGURATION_CHANGED = 118;
public static final int CLEAN_UP_CONTEXT = 119;
public static final int GC_WHEN_IDLE = 120;
public static final int BIND_SERVICE = 121;
public static final int UNBIND_SERVICE = 122;
public static final int DUMP_SERVICE = 123;
public static final int LOW_MEMORY = 124;
public static final int PROFILER_CONTROL = 127;
public static final int CREATE_BACKUP_AGENT = 128;
public static final int DESTROY_BACKUP_AGENT = 129;
public static final int SUICIDE = 130;
public static final int REMOVE_PROVIDER = 131;
public static final int ENABLE_JIT = 132;
public static final int DISPATCH_PACKAGE_BROADCAST = 133;
public static final int SCHEDULE_CRASH = 134;
public static final int DUMP_HEAP = 135;
public static final int DUMP_ACTIVITY = 136;
public static final int SLEEPING = 137;
public static final int SET_CORE_SETTINGS = 138;
public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
public static final int DUMP_PROVIDER = 141;
public static final int UNSTABLE_PROVIDER_DIED = 142;
public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
public static final int INSTALL_PROVIDER = 145;
public static final int ON_NEW_ACTIVITY_OPTIONS = 146;
public static final int ENTER_ANIMATION_COMPLETE = 149;
public static final int START_BINDER_TRACKING = 150;
public static final int STOP_BINDER_TRACKING_AND_DUMP = 151;
public static final int LOCAL_VOICE_INTERACTION_STARTED = 154;
public static final int ATTACH_AGENT = 155;
public static final int APPLICATION_INFO_CHANGED = 156;
public static final int RUN_ISOLATED_ENTRY_POINT = 158;
public static final int EXECUTE_TRANSACTION = 159;
public static final int RELAUNCH_ACTIVITY = 160;
}

AMS.attachApplication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}

private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
ProcessRecord app;
long startTime = SystemClock.uptimeMillis();
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid); // 根据pid获取ProcessRecord
}
} else {
app = null;
}

thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, isAutofillCompatEnabled);
return true;
}

ApplicationThread.bindApplication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> 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,
String buildSerial, boolean autofillCompatibilityEnabled) {
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;
data.buildSerial = buildSerial;
data.autofillCompatibilityEnabled = autofillCompatibilityEnabled;
sendMessage(H.BIND_APPLICATION, data);
}

sendMessage方法最终走的是mH.sendMessage(msg),mH是H类型:

ActivityThread.handleBindApplication

当主线程收到H.BIND_APPLICATION,则调用handleBindApplication:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// ActivityThread.java
private void handleBindApplication(AppBindData data) {
mBoundApplication = data;
Process.setArgV0(data.processName); // 设置进程名
// ...
// 创建LoadedApk对象,并将其加入到mPackages,也就是说每个app都会创建唯一的LoadedApk对象。
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
// ...

// 创建ContextImpl上下文
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
// ...
Application app;
try {
// 此处data.info是指LoadedApk, 通过反射创建目标应用Application对象
app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
// ...
mInstrumentation.onCreate(data.instrumentationArgs);
//回调onCreate
mInstrumentation.callApplicationOnCreate(app);

} finally {
}
}

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<LoadedApk> 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())) {
// 创建LoadedApk对象
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<LoadedApk>(packageInfo));
} else {
mResourcePackages.put(aInfo.packageName,
new WeakReference<LoadedApk>(packageInfo));
}
}
return packageInfo;
}
}

创建LoadedApk对象,并将将新创建的LoadedApk加入到mPackages,也就是说每个app都会创建唯一的LoadedApk对象。此处aInfo来源于ProcessRecord.info变量,也就是进程中的第一个app。

LoadedApk.makeApplication

getClassLoader

该方法跟system_server一样,其内调用的getClassLoader也调用了createOrUpdateClassLoaderLocked方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
private void createOrUpdateClassLoaderLocked(List<String> addedPaths) {
if (mPackageName.equals("android")) {
// ...
}

if (mRegisterPackage) {
try {
ActivityManager.getService().addPackageDependency(mPackageName);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

final List<String> zipPaths = new ArrayList<>(10);
final List<String> libPaths = new ArrayList<>(10);

final String defaultSearchPaths = System.getProperty("java.library.path");
final boolean treatVendorApkAsUnbundled = !defaultSearchPaths.contains("/vendor/lib");

makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths);

String libraryPermittedPath = mDataDir;

final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);

boolean needToSetupJitProfiles = false;
if (mClassLoader == null) {
mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip,
mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
libraryPermittedPath, mBaseClassLoader,
mApplicationInfo.classLoaderName);
mAppComponentFactory = createAppFactory(mApplicationInfo, mClassLoader);
needToSetupJitProfiles = true;
}

List<String> extraLibPaths = new ArrayList<>(3);
String abiSuffix = VMRuntime.getRuntime().is64Bit() ? "64" : "";
if (!defaultSearchPaths.contains("/vendor/lib")) {
extraLibPaths.add("/vendor/lib" + abiSuffix);
}
if (!defaultSearchPaths.contains("/odm/lib")) {
extraLibPaths.add("/odm/lib" + abiSuffix);
}
if (!defaultSearchPaths.contains("/product/lib")) {
extraLibPaths.add("/product/lib" + abiSuffix);
}
if (!extraLibPaths.isEmpty()) {
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
try {
ApplicationLoaders.getDefault().addNative(mClassLoader, extraLibPaths);
} finally {
StrictMode.setThreadPolicy(oldPolicy);
}
}

if (addedPaths != null && addedPaths.size() > 0) {
final String add = TextUtils.join(File.pathSeparator, addedPaths);
ApplicationLoaders.getDefault().addPath(mClassLoader, add);
// Setup the new code paths for profiling.
needToSetupJitProfiles = true;
}

if (needToSetupJitProfiles && !ActivityThread.isSystem()) {
setupJitProfileSupport();
}
}

// ApplicationLoaders.java
ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled,
String librarySearchPath, String libraryPermittedPath,
ClassLoader parent, String classLoaderName) {
return getClassLoader(zip, targetSdkVersion, isBundled, librarySearchPath,
libraryPermittedPath, parent, zip, classLoaderName);
}

private ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled,
String librarySearchPath, String libraryPermittedPath,
ClassLoader parent, String cacheKey, String classLoaderName) {
ClassLoader baseParent = ClassLoader.getSystemClassLoader().getParent();

synchronized (mLoaders) {
if (parent == null) {
parent = baseParent;
}

if (parent == baseParent) {
ClassLoader loader = mLoaders.get(cacheKey);
if (loader != null) {
return loader;
}

ClassLoader classloader = ClassLoaderFactory.createClassLoader(
zip, librarySearchPath, libraryPermittedPath, parent,
targetSdkVersion, isBundled, classLoaderName);
GraphicsEnvironment.getInstance().setLayerPaths(
classloader, librarySearchPath, libraryPermittedPath);

mLoaders.put(cacheKey, classloader);
return classloader;
}

ClassLoader loader = ClassLoaderFactory.createClassLoader(
zip, null, parent, classLoaderName);
return loader;
}
}

// ClassLoaderFactory.java
public static ClassLoader createClassLoader(String dexPath,
String librarySearchPath, String libraryPermittedPath, ClassLoader parent,
int targetSdkVersion, boolean isNamespaceShared, String classloaderName) {

final ClassLoader classLoader = createClassLoader(dexPath, librarySearchPath, parent, classloaderName);
// ...
return classLoader;
}

public static ClassLoader createClassLoader(String dexPath,
String librarySearchPath, ClassLoader parent, String classloaderName) {
if (isPathClassLoaderName(classloaderName)) {
return new PathClassLoader(dexPath, librarySearchPath, parent);
} else if (isDelegateLastClassLoaderName(classloaderName)) {
return new DelegateLastClassLoader(dexPath, librarySearchPath, parent);
}

throw new AssertionError("Invalid classLoaderName: " + classloaderName);
}

Instrumentation.newApplication

逻辑与system_server类似。

总结

App进程的Application创建过程,跟system进程的核心逻辑都差不多。只是app进程多了两次binder调用。其中newApplication方法中通过类加载器加载了Application Class对象,并通过其newInstance方法创建了Application实例。

Application