Android功能庫初始化管理利器

前言

隨着本身開發的應用的版本迭代,新功能不斷增多,隨之引入的第三方庫也不可避免地多了起來,你可能就會發現本身應用Application中各類框架的初始化代碼也在逐漸臃腫起來:什麼推送啦,分享啦,統計啦,定位啦...另外還有你本身封裝的一些工具和框架。這些七七八八加起來,可能最終你的Application會變成這樣:java

public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        //初始化推送
        PushAgent mPushAgent = PushAgent.getInstance(this);
        mPushAgent.register(new IUmengRegisterCallback() {
            @Override
            public void onSuccess(String deviceToken) {
                //註冊成功會返回device token
            }

            @Override
            public void onFailure(String s, String s1) {
            }
        });
        //初始化統計
        UMConfigure.init(this,"5a12384aa40fa3551f0001d1","umeng",UMConfigure.DEVICE_TYPE_PHONE,"");
        //初始化分享
        PlatformConfig.setWeixin("wxdc1e388c3822c80b", "3baf1193c85774b3fd9d18447d76cab0");
        PlatformConfig.setSinaWeibo("3921700954", "04b48b094faeb16683c32669824ebdad","http://sns.whalecloud.com");
        PlatformConfig.setYixin("yxc0614e80c9304c11b0391514d09f13bf");
        PlatformConfig.setQQZone("100424468", "c7394704798a158208a74ab60104f0ba");
        PlatformConfig.setTwitter("3aIN7fuF685MuZ7jtXkQxalyi", "MK6FEYG63eWcpDFgRYw4w9puJhzDl0tyuqWjZ3M7XJuuG7mMbO");
        //初始化定位
        LocationClient mLocationClient = new LocationClient(context);
        mLocationClient.setLocOption(getLocationOption());
        mLocationClient.registerLocationListener(new MyLocationListener());
        mLocationClient.start();
        mLocationClient.requestLocation();
        //初始化glide
        DisplayOption options = DisplayOption.builder().setDefaultResId(R.drawable.ic_default)
                .setErrorResId(-1).setLoadingResId(-1);
        imageDisplayLoader.setDefaultDisplayOption(options);
        //初始化本身的一些工具 
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                
            }

        });

    }
}
複製代碼

上面我只是列舉了一些經常使用的功能框架,從我的開發經驗上說,這些應用程序級別的框架,做用的時間貫穿APP的整個生命週期,因此都會要求你在一開始的時候就進行初始化。android

優化方案git

對於單一模塊的App來講,可能問題不大,只要先定義一個統一接口,而後分別實現,最後添加到一個集合,在Application中統一調用就行了:github

public interface IAppInit {
    void init(@NonNull Application application);
}

public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        List<IAppInit> initList = new ArrayList<>();
        initList.add(new ShareInit());
        initList.add(new PushInit());
        initList.add(new ImageInit());
        for (IAppInit iAppInit : initList) {
            iAppInit.init(this);
        }
    }
}

複製代碼

但現在不少的進行了組件化的改造,其中的一個重要思想就是功能模塊的組件化,也就是解耦,彼此互不依賴,但若是咱們仍是像上面這樣作的話就等於違背了這個思想,把這些功能模塊的初始化代碼所有集中在了一塊兒。更好的方案固然是在模塊內部作初始化,並且不須要在Application中統一調用這些初始化代碼。bash

優雅地進行框架初始化

爲了更好地解決這個問題,我寫了Initiator這個Gradle插件。使用方法異常簡單:在程序的任意位置,只要實現IAppInit接口就能夠了,無需手動調用,Initiator會在編譯時自動搜索全部實現了該接口的類,並生成調用init()方法的的代碼。Initiator支持kotlin,支持Application類型和library類型的module。app

public class PushInit implements IAppInit {
    @Override
    public void init(Application application) {
        Log.d("init==", "PushInit");
    }
}
複製代碼

爲了知足更多初始化需求,還能夠爲每一個初始化增長多種配置,只要在這個類上加一個@AppInit註解就好了:框架

@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE})
public @interface AppInit {
    boolean background() default false; //在工做線程中初始化,默認false

    boolean inChildProcess() default true;//容許在子進程中初始化,多進程應用Application的onCreate方法會調用屢次,默認true

    boolean onlyInDebug() default false;//只在debug中作初始化,默認false

    int priority() default 0;//初始化優先級,數字越大,優先級越高,初始化時間越早

    long delay() default 0L;//初始化執行延時時間,在主線程和工做線程均可以延時
}
複製代碼

採用編譯期註解,不使用反射,代碼在編譯時生成,對最終程序運行性能影響很小。最終咱們的代碼可能以下:ide

@AppInit(priority = 22, delay = 1740, onlyInDebug = true)
public class PushInit implements IAppInit {

    @Override
    public void init(Application application) {
        Log.d("init==", "PushInit");
    }
}

複製代碼

注意,若是你沒有作這些特別的配置,不須要加這個註解。另外你可能對Application作了多重繼承Initiator會找到多個Application的子類,請在你須要初始化的入口加上@InitContext註解:工具

@InitContext
public class App extends BaseApplication {

}
複製代碼

目前暫時只支持Application類型,後期考慮增長Activity的支持,由於有些初始化能夠延後放到啓動頁或首頁來作。目前能夠用延時策略替代。組件化

引入方式

首先,在項目根目錄的 build.gradle文件中增長如下內容:

dependencies {
         classpath 'com.renny.initiator:plugin:'${latest_version}" } 複製代碼

而後,在 applicationlibrary 模塊的build.gradle 文件中應用插件:

apply plugin: 'com.android.application'
// apply plugin: 'com.android.library'
apply plugin: 'initiator'
複製代碼

Gradle Plugin或者實現方式感興趣的同窗請看源碼:Github連接。歡迎你們找找bug,提提新功能~

相關文章
相關標籤/搜索