Application, Activity, ContentProvider启动顺序

拓展知识:Zygote创建进程,Application启动以及Java类加载器等的相关基础

出现问题原因分析:

1.公司坚持使用eclipse集成friebase统计SDK

2.Application、ContentProvider、Activity执行顺序不够清晰

使用eclipse集成friebase统计SDK,涉及到aar转eclipse的过程中,aar中的jar存在资源ID的引用,我们的做法是在工程中新建一个aar包名对应的R文件,R中的资源变量,全部当前App中R文件的赋值,friebase集成过程中com.google.android.gms.R.string.common_google_play_services_unknown_issue 变量被FirebaseInitProviderdu的onCreate函数间接调用。

package com.google.android.gms;

public final class R {
    public static final class integer {
        public static int google_play_services_version = getIdByName("integer", "google_play_services_version");
    }
    public static final class string {
        public static int common_google_play_services_unknown_issue = .getIdByName("string", "common_google_play_services_unknown_issue");
    }
}
       /**
	 * 通过资源ID获取名称
	 * @param typeName
	 * @param name
	 * @return
	 */
	public static int getIdByName(String typeName, String name) {
		String pkgName = UserApp.curApp().getPackageName();
        int id = -1;
        try {
            Class<?> rClass = Class.forName(pkgName + ".R");
            Class[] rClassArr = rClass.getClasses();
            Class desireClass = null;
            
            for (int i = 0; i < rClassArr.length; ++i) {
                if (rClassArr[i].getName().split("\\$")[1].equals(typeName)) {
                    desireClass = rClassArr[i];
                    break;
                }
            }
            if (desireClass != null) {
                id = desireClass.getField(name).getInt(desireClass);
            }
            
        } catch (Exception e) {
            
        }
        return id;
    }

 

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0"
    package="com.example.android.persistence">
    <application
        android:theme="@ref/0x7f0d0006"
        android:label="@ref/0x7f0c001f"
        android:icon="@ref/0x7f0b0000"
        android:debuggable="true"
        android:testOnly="true"
        android:allowBackup="false"
        android:supportsRtl="true">

        <provider
            android:name="com.google.firebase.provider.FirebaseInitProvider"
            android:authorities="com.minesweeper.mines.miner.firebaseinitprovider"
            android:exported="false"
            android:initOrder="100" />
    </application>
</manifest>

通过测试日志发现执行顺序如下:

Application->attachBaseContext()
ContentProvider->onCreate()
Application->onCreate()
Activity->onCreate()

可见在接入组件库后,打包过程中合并AndroidManifest.xml文件,注册了ContentProvider。利用其执行顺序这个特性,去初始化组件库。

很是巧妙的解耦方式。

Application, Activity, ContentProvider启动顺序
Android的Proxy/Delegate Application框架

0 条评论
发表一条评论