无侵入进行SDK的初始化

无侵入进行SDK的初始化

0.前言

我们在集成第三方SDK的时候大多都会在Application的onCreate方法里进行SDK的初始化或配置工作,这好像也没有什么问题,不过我们能不能能做的更好一点呢?就是希望用户在gradle文件里compile一下相应的库就可以直接使用,不需要额外的初始化和配置.这个问题,我在阅读Android Architecture Components(https://developer.android.com/topic/libraries/architecture/index.html) 源码时找到答案,现在把这个方案记录下来。

1.注册占位的Provider

<provider

android:name="android.arch.lifecycle.LifecycleRuntimeTrojanProvider"
    android:authorities="com.example.android.persistence.lifecycle-trojan"
    android:exported="false"
    android:multiprocess="true" />

2.在Provider的onCreate初始化

public class LifecycleRuntimeTrojanProvider extends ContentProvider {
    public LifecycleRuntimeTrojanProvider() {
    }

    public boolean onCreate() {
        LifecycleDispatcher.init(this.getContext());
        ProcessLifecycleOwner.init(this.getContext());
        return true;
    }

    @Nullable
    public Cursor query(@NonNull Uri uri, String[] strings, String s, String[] strings1, String s1) {
        return null;
    }

    @Nullable
    public String getType(@NonNull Uri uri) {
        return null;
    }

    @Nullable
    public Uri insert(@NonNull Uri uri, ContentValues contentValues) {
        return null;
    }

    public int delete(@NonNull Uri uri, String s, String[] strings) {
        return 0;
    }

    public int update(@NonNull Uri uri, ContentValues contentValues, String s, String[] strings) {
        return 0;
    }
}

3.分析和总结

先说下结论:Provider的onCreate优先于Application的onCreate执行,并且此时的Application已经创建成功,而Provider里的context正是Application的对象,完全符合需求。(也就是和在Application的onCreate里是写一样一样的)

LifecycleRuntimeTrojanProvider.onCreate的调用栈:
这里写图片描述

Application.onCreate的调用栈:
这里写图片描述

由ActivityThread的handleBindApplication方法可以看到,是先调用installContentProviders方法,然后调用mInstrumentation.callApplicationOnCreate方法的。

public final class ActivityThread {

private void handleBindApplication(AppBindData data) {
    // Allow disk access during application and provider setup. This could
   // block processing ordered broadcasts, but later processing would
   // probably end up doing the same disk access.
   final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
   try {
       // If the app is being launched for full backup or restore, bring it up in
       // a restricted environment with the base application class.
       Application app = data.info.makeApplication(data.restrictedBackupMode, null);
       mInitialApplication = app;

       // don't bring up providers in restricted mode; they may depend on the
       // app's custom Application class
       if (!data.restrictedBackupMode) {
           if (!ArrayUtils.isEmpty(data.providers)) {
               installContentProviders(app, data.providers);
               // For process that contains content providers, we want to
               // ensure that the JIT is enabled "at some point".
               mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
           }
       }

       // Do this after providers, since instrumentation tests generally start their
       // test thread at this point, and we don't want that racing.
       try {
           mInstrumentation.onCreate(data.instrumentationArgs);
       }
       catch (Exception e) {
           throw new RuntimeException(
               "Exception thrown in onCreate() of "
               + data.instrumentationName + ": " + e.toString(), e);
       }

       try {
           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);
   }
}
}

参考

* Android Architecture Components(https://developer.android.com/topic/libraries/architecture/index.html)
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 成长之路 设计师:Amelia_0503 返回首页