*本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布
一 背景
public class MainApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
Log.v("testLog", getLogStr() );
}
@Override
public void onCreate() {
super.onCreate();
Log.v("testLog", getLogStr());
}
private String getLogStr() {
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
return elements[3].getClassName() + "___" + elements[3].getMethodName();
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.v("testLog", getLogStr());
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
public class MainService extends Service{
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.v("testLog",getLogStr());
return null;
}
@Override
public void onCreate() {
Log.v("testLog",getLogStr());
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v("testLog",getLogStr());
return super.onStartCommand(intent, flags, startId);
}
}
public class MainReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.v("testLog", getLogStr());
}
}
public class MainProvider extends ContentProvider {
@Override
public boolean onCreate() {
Log.v("testLog", getLogStr());
return false;
}
@Nullable
@Override
public Bundle call(String method, String arg, Bundle extras) {
Log.v("testLog", getLogStr());
return super.call(method, arg, extras);
}
... ...
}
android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
android:name="com.zxl.test.MainApplication"
android:label="@string/app_name" >
android:name="com.zxl.test.MainActivity">
android:name="android.intent.action.MAIN" />
android:name="android.intent.category.LAUNCHER" />
android:name="com.zxl.test.MainService" android:exported="true"/>
android:name="com.zxl.test.MainProvider"
android:authorities="com.zxl.test.MainProvider"
android:exported="true" />
android:name="com.zxl.test.MainReceiver">
android:name="android.intent.action.BOOT_COMPLETED" />
V/testLog (2537) : com.zxl.test.MainApplication___attachBaseContext
V/testLog (2537) : com.zxl.test.MainProvider___onCreate
V/testLog (2537) : com.zxl.test.MainApplication___onCreate
V/testLog (2537) : com.zxl.test.MainActivity___onCreate
Intent intent = new Intent();
intent.setClassName("com.zxl.test","com.zxl.test.MainService");
intent.setPackage("com.zxl.test");
startService(intent);
V/testLog (2726) : com.zxl.test.MainApplication___attachBaseContext
V/testLog (2726) : com.zxl.test.MainProvider___onCreate
V/testLog (2726) : com.zxl.test.MainApplication___onCreate
V/testLog (2726) : com.zxl.test.MainService___onCreate
V/testLog (2726) : com.zxl.test.MainService___onStartCommand
V/testLog (1251) : com.zxl.test.MainApplication___attachBaseContext
V/testLog (1251) : com.zxl.test.MainProvider___onCreate
V/testLog (1251) : com.zxl.test.MainApplication___onCreate
V/testLog (1251) : com.zxl.test.MainReceiver___onReceive
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse( "content://com.zxl.test.MainProvider" );
resolver.call( uri,"","",null );
V/testLog (26997) : com.zxl.test.MainApplication___attachBaseContext
V/testLog (26997) : com.zxl.test.MainProvider___onCreate
V/testLog (26997) : com.zxl.test.MainApplication___onCreate
V/testLog (26997) : com.zxl.test.MainProvider___call
public class MainProvider extends ContentProvider {
@Override
public boolean onCreate() {
Log.v("testLog", getLogStr() + " start");
for (int i= 0; i < 10; i++){
SystemClock.sleep(100);
Log.v("testLog", getLogStr() + " i = " + i);
}
Log.v("testLog", getLogStr() + " end");
return false;
}
... ...
}
V/testLog (3326) : com.zxl.test.MainApplication___attachBaseContext
V/testLog (3326) : com.zxl.test.MainProvider___onCreate start
V/testLog (3326) : com.zxl.test.MainProvider___onCreate i = 0
V/testLog (3326) : com.zxl.test.MainProvider___onCreate i = 1
V/testLog (3326) : com.zxl.test.MainProvider___onCreate i = 2
V/testLog (3326) : com.zxl.test.MainProvider___onCreate i = 3
V/testLog (3326) : com.zxl.test.MainProvider___onCreate i = 4
V/testLog (3326) : com.zxl.test.MainProvider___onCreate i = 5
V/testLog (3326) : com.zxl.test.MainProvider___onCreate i = 6
V/testLog (3326) : com.zxl.test.MainProvider___onCreate i = 7
V/testLog (3326) : com.zxl.test.MainProvider___onCreate i = 8
V/testLog (3326) : com.zxl.test.MainProvider___onCreate i = 9
V/testLog (3326) : com.zxl.test.MainProvider___onCreate end
V/testLog (3326) : com.zxl.test.MainApplication___onCreate
V/testLog (3326) : com.zxl.test.MainActivity___onCreate
public class MainApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
Log.v("testLog", getLogStr() );
}
@Override
public void onCreate() {
super.onCreate();
Log.v( "testLog", getLogStr() + " start" );
for( int i = 0; i < 10; i++ )
{
Log.v( "testLog", getLogStr() + " i = " + i );
SystemClock.sleep( 50 );
}
Log.v( "testLog", getLogStr() + " end" );
}
}
public class MainProvider extends ContentProvider {
@Override
public boolean onCreate() {
Log.v("testLog", getLogStr());
return false;
}
@Nullable
@Override
public Bundle call(String method, String arg, Bundle extras) {
Log.v("testLog", getLogStr());
for (int i = 0; i < 10; i++) {
Log.v("testLog", getLogStr() + " i = " + i);
SystemClock.sleep(30);
}
return super.call(method, arg, extras);
}
... ...
}
V/testLog (20660): com.zxl.test.MainApplication___attachBaseContext
V/testLog (20660): com.zxl.test.MainProvider___onCreate
V/testLog (20660): com.zxl.test.MainApplication___onCreate start
V/testLog (20660): com.zxl.test.MainApplication___onCreate i = 0
V/testLog (20660): com.zxl.test.MainProvider___call
V/testLog (20660): com.zxl.test.MainProvider___call i = 0
V/testLog (20660): com.zxl.test.MainProvider___call i = 1
V/testLog (20660): com.zxl.test.MainApplication___onCreate i = 1
V/testLog (20660): com.zxl.test.MainProvider___call i = 2
V/testLog (20660): com.zxl.test.MainProvider___call i = 3
V/testLog (20660): com.zxl.test.MainApplication___onCreate i = 2
V/testLog (20660): com.zxl.test.MainProvider___call i = 4
V/testLog (20660): com.zxl.test.MainApplication___onCreate i = 3
V/testLog (20660): com.zxl.test.MainProvider___call i = 5
V/testLog (20660): com.zxl.test.MainProvider___call i = 6
V/testLog (20660): com.zxl.test.MainApplication___onCreate i = 4
V/testLog (20660): com.zxl.test.MainProvider___call i = 7
V/testLog (20660): com.zxl.test.MainProvider___call i = 8
V/testLog (20660): com.zxl.test.MainApplication___onCreate i = 5
V/testLog (20660): com.zxl.test.MainProvider___call i = 9
V/testLog (20660): com.zxl.test.MainApplication___onCreate i = 6
V/testLog (20660): com.zxl.test.MainApplication___onCreate i = 7
V/testLog (20660): com.zxl.test.MainApplication___onCreate i = 8
V/testLog (20660): com.zxl.test.MainApplication___onCreate i = 9
V/testLog (20660): com.zxl.test.MainApplication___onCreate end
public class MainApplication extends Application {
public MainApplication(){
Log.v("testLog", "com.zxl.test.MainApplication__MainApplication" );
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
Log.v("testLog", getLogStr() );
}
@Override
public void onCreate() {
super.onCreate();
Log.v( "testLog", getLogStr() );
}
}
V/testLog (20989): com.zxl.test.MainApplication__MainApplication
V/testLog (20989): com.zxl.test.MainApplication___attachBaseContext
V/testLog (20989): com.zxl.test.MainProvider___onCreate
V/testLog (20989): com.zxl.test.MainApplication___onCreate
public class MainApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
Log.v("testLog", getLogStr() );
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse( "content://com.zxl.test.MainProvider" );
resolver.call( uri,"","",null );
}
@Override
public void onCreate() {
super.onCreate();
Log.v( "testLog", getLogStr() );
}
}
public class MainProvider extends ContentProvider {
@Override
public boolean onCreate() {
Log.v("testLog", getLogStr() + " this = " + this );
return false;
}
@Override
public Bundle call(String method, String arg, Bundle extras) {
Log.v("testLog", getLogStr() + " this = " + this);
return super.call(method, arg, extras);
}
... ...
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.v("testLog", getLogStr());
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse( "content://com.zxl.test.MainProvider" );
resolver.call( uri,"","",null );
}
}
V/testLog (25337): com.zxl.test.MainApplication___attachBaseContext
V/testLog (25337): com.zxl.test.MainProvider___onCreate this = com.zxl.test.MainProvider@38fe7481
V/testLog (25337): com.zxl.test.MainProvider___call this = com.zxl.test.MainProvider@38fe7481
V/testLog (25337): com.zxl.test.MainProvider___onCreate this = com.zxl.test.MainProvider@1f17967
V/testLog (25337): com.zxl.test.MainApplication___onCreate
V/testLog (25337): com.zxl.test.MainActivity___onCreate
V/testLog (25337): com.zxl.test.MainProvider___call this = com.zxl.test.MainProvider@38fe7481
frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
... ...
Looper.prepareMainLooper();
- // 1. 先看此处,此处调用了 attach 方法
- ActivityThread thread = new ActivityThread();
thread.attach(false);
... ...
Looper.loop();
- throw new RuntimeException("Main thread loop unexpectedly exited");
}
frameworks/base/core/java/android/app/ActivityThread.java
private void attach(boolean system) {
- ... ...
- // 2. 上面注释1中,传递的system值为false,所以跳转到这个if语句中
- if (!system) {
- ... ...
// 3. 得到了AMS(ActivityManagerService)在本地的服务代理
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
// 4. 通知
AMS 创建Application,其实ASM之后还是会回调到ActivityThread的bindApplication方法,- // 而bindApplication方法,会调用到 handleBindApplication 方法
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
... ...
} else {
... ...
}
- ... ...
}
frameworks/base/core/java/android/app/ActivityThread.java
private void handleBindApplication(AppBindData data) {
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
... ...
try {
// 5. makeApplication方法最终会调用到apk的Application的attachBaseContext方法,
// 这里的info其实是LoaderApk的一个实例
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
- ... ...
}
frameworks/base/core/java/android/app/LoadedApk.java
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
... ...
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
initializeJavaContextClassLoader();
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// 5.1 接着看newApplication的方法实现;
// mInstrumentation是Instrumentation的实例
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
- mApplication = app;
... ...
return app;
}
frameworks/base/core/java/android/app/Instrumentation.java
// 5.2 这个方法是在5.1中调用的方法
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
// 5.3 这个方法直接调用另一个方法
- return newApplication(cl.loadClass(className), context);
}
static public Application newApplication(Class> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
// 5.4 在这里终于看到Application这个类了,接着看attach的方法
app.attach(context);
return app;
}
frameworks/base/core/java/android/app/Application.java
final void attach(Context context) {
// 5.5 在这里终于看到调用attachBaseContext这个方法了。
- // 我们重新回到 注释5 的那段代码,接着往下看
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
frameworks/base/core/java/android/app/ActivityThread.java
private void handleBindApplication(AppBindData data) {
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
... ...
try {
// 5. makeApplication方法最终会调用到apk的Application的attachBaseContext方法
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
if (!data.restrictedBackupMode) {
List<ProviderInfo> providers = data.providers;
if (providers != null) {
// 6. installContentProviders就是初始化应用中的ContentProvider组件,
// 最终会调用到ContentProvider的onCreate方法;
// 所以,从注释5 和 注释6 的前后顺序,就可以解释为什么Application的attachBaseContext
// 比 ContentProvider的onCreate的方法要早。
installContentProviders(app, providers);
mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
}
}
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
throw new RuntimeException(
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}
try {
// 7. 这个方法,其实就是调用了Application的onCreate方法,
// 所以,结合注释5、注释6和注释7,可以证实调用顺序确实是:
// Application的attachBaseContext ---> ContentProvider的onCreate ---> Application的onCreate
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
frameworks/base/core/java/android/app/ActivityThread.java
private IActivityManager.ContentProviderHolder installProvider(Context context,
IActivityManager.ContentProviderHolder holder, ProviderInfo info,
boolean noisy, boolean noReleaseNeeded, boolean stable) {
... ...
try {
// 6.1.1 通过反射,构造出ContentProvider的实例,
final java.lang.ClassLoader cl = c.getClassLoader();
localProvider = (ContentProvider)cl.
loadClass(info.name).newInstance();
provider = localProvider.getIContentProvider();
if (provider == null) {
Slog.e(TAG, "Failed to instantiate class " +
info.name + " from sourceDir " +
info.applicationInfo.sourceDir);
return null;
}
if (DEBUG_PROVIDER) Slog.v(TAG, "Instantiating local provider " + info.name);
// 6.1.2 此处调用attachInfo,在这个方法中会有一些初始化的动作,最终会调用到ContentProvider的onCreate方法
localProvider.attachInfo(c, info);
} catch (java.lang.Exception e) {
if (!mInstrumentation.onException(null, e)) {
throw new RuntimeException(
"Unable to get provider " + info.name
+ ": " + e.toString(), e);
}
return null;
}
... ...
}
frameworks/base/core/java/android/content/ContentProvider.java
private void attachInfo(Context context, ProviderInfo info, boolean testing) {
mNoPerms = testing;
if (mContext == null) {
mContext = context;
if (context != null) {
mTransport.mAppOpsManager = (AppOpsManager) context.getSystemService(
Context.APP_OPS_SERVICE);
}
mMyUid = Process.myUid();
if (info != null) {
setReadPermission(info.readPermission);
setWritePermission(info.writePermission);
setPathPermissions(info.pathPermissions);
mExported = info.exported;
mSingleUser = (info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0;
setAuthorities(info.authority);
}
// 6.1.3 终于在此处看到调用onCreate方法了
ContentProvider.this.onCreate();
}
}
frameworks/base/core/java/android/app/Instrumentation.java
public void callApplicationOnCreate(Application app) {
// 7.1 就这么简单明了,在这里看到了真正调用Application的onCreate方法的地方
app.onCreate();
- }
- /framework/base/core/android/content/ContextWrapper.java
@Override
public Context getApplicationContext() {
- // a. mBase是什么?mBase是Context的一个实例,在这类里面它是通过两种方式被赋值,
- // 第一个是在ContextWrapper的构造方法;第二个是在ContextWrapper的attachBaseContext方法;
- // 而我们是从Application中跟踪过来,而Application的创建过程体现在注释5 到 注释5.5中,
- // 因此,不难发现mBase其实是一个ContextImpl的实例;
return mBase.getApplicationContext();
}
- /framework/base/core/android/app/ContextImpl.java
@Override
public Context getApplicationContext() {
// b. 看逻辑发现,如果mPackageInfo不为空,就调用mPackageInfo的getApplication()方法;
// 而mPackageInfo又是什么呢?
通过看源码发现它是 LoaderApk的实例;- // 这个mPackageInfo是在什么时候得到的呢?接着往下看
return (mPackageInfo != null) ?
mPackageInfo.getApplication() : mMainThread.getApplication();
}
- /framework/base/core/android/app/ContextImpl.java
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
// c. 具体还是调用到了ContextImp的构造方法
return new ContextImpl(null, mainThread,
packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
}
private ContextImpl(ContextImpl container, ActivityThread mainThread,
LoadedApk packageInfo, IBinder activityToken, UserHandle user, int flags,
Display display, Configuration overrideConfiguration, int createDisplayWithId) {
mOuterContext = this;
... ...
- // c.1 mPackageInfoInfo被赋值了,
- // 而 packageInfo是 从createAppContext中一步步传过来的LoaderApk的实例;
mPackageInfo = packageInfo;
mResourcesManager = ResourcesManager.getInstance();
- ... ...
}
- /framework/base/core/android/app/LoaderApk.java
// d. 好吧,代码就这么“简单纯朴”;
// 好吧,这不是我们想要的;继续分析mApplication 是什么时候被赋值的
// 在LoaderApk中搜索 “mApplication =”,发现有且仅有一行代码,看接着看注释 d.1
Application getApplication() {
return mApplication;
}
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
... ...
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) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
// d.1 此处是仅有的一处 "mApplication =";
// 再看看之前的代码,发现是不是很眼熟,这不就是 之前 注释5.1的那段代码吗?
mApplication = app;
... ...
return app;
}