79

Application, Activity, ContentProvider启动顺序

 5 years ago
source link: http://blog.uiuno.com/2018/07/28/15/13/10/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

拓展知识: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;
    }
<code><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></code><code></code>

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

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

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

很是巧妙的解耦方式。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK