MVPArms是一个整合了大量主流开源项目的Android Mvp快速搭建框架,其中包含Dagger2
Retrofit
,Rxjava
以及Rxbinding
,RxCache
等Rx
系三方库,而且提供UI
自适应方案,本框架将它们结合起来,并所有使用Dagger2
管理并提供给开发者使用,使用本框架开发你的项目就意味着你已经拥有一个MVP+Dagger2+Retrofit+Rxjava项目,发布到github
上能够很是轻松的拿star(在简历中展露头脚),我提供一切迭代和维护成本你只须要在Readme里面注明框架出处,还不赶快行动?前端
Dagger2
管理(将全部模块使用Dagger
链接起来,毫不是简单的使用)Rxjava
UI
自适应http
Request(请求参数,headers) Response(服务器返回的结果,headers,耗时)信息监听,可解析json后根据状态码作相应的全局操做Rxjava
错误处理,错误后自动重试,捕捉整个应用的全部错误Android
开发能力Dagger2
,Rxjava
,Retrofit
的经验,没使用过也必须了解,否则很难使用Mvp
Google官方出品的Mvp
架构项目,含有多个不一样的架构分支(此为Dagger分支).Dagger2
Google根据Square的Dagger1出品的依赖注入框架,经过apt动态生成代码,性能优于用反射技术依赖注入的框架.Rxjava
提供优雅的响应式Api解决异步请求.RxAndroid
为Android提供响应式Api.Rxlifecycle
在Android上使用rxjava都知道的一个坑,就是生命周期的解除订阅,这个框架经过绑定activity和fragment的生命周期完美解决.Rxbinding
JakeWharton大神的View绑定框架,优雅的处理View的响应事件.RxCache
是使用注解为Retrofit加入二级缓存(内存,磁盘)的缓存库Retrofit
Square出品的网络请求库,极大的减小了http请求的代码和步骤.Okhttp
一样Square出品,很少介绍,作Android都应该知道.Autolayout
鸿洋大神的Android全尺寸适配框架.Gson
Google官方的Json Convert框架.Butterknife
JakeWharton大神出品的view注入框架.Androideventbus
一个轻量级使用注解的Eventbus.Timber
JakeWharton大神出品Log框架,内部代码极少,可是思想很是不错.Glide
此库为本框架默认封装图片加载库,可参照着例子更改成其余的库,Api和Picasso
差很少,缓存机制比Picasso
复杂,速度快,适合处理大型图片流,支持gfit,Fresco
太大了!,在5.0一下优点很大,5.0以上系统默认使用的内存管理和Fresco
相似.Realm
速度和跨平台性使它成为现在最火的数据库,美中不足的就是so库太大LeakCanary
Square出品的专门用来检测Android
和Java
的内存泄漏,经过通知栏提示内存泄漏信息RxErroHandler
Rxjava
错误处理库,可在出现错误后重试
此框架适合本身作定制修改,全部暂时不上传至
Jcenter
或Maven
,请自行下载或clonejava
compile project(':arms')
本框架提供一个引用大量第三方库的config.gradle文件,用于第三方库版本管理,将config.gradle复制进根目录,并在项目的顶级build.gradle中引用它android
// Top-level build file where you can add configuration options common to all sub-projects/modules. apply from: "config.gradle" //这里表示引用config.gradle文件 buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.1.2' the individual module build.gradle files } } allprojects { repositories { jcenter() maven { url "https://jitpack.io" }//这里要使用rxcahche指定的仓库 } } task clean(type: Delete) { delete rootProject.buildDir }
由于在顶级build.gradle中引用了它,因此在整个项目的全部build.gradle中均可以使用rootProject.xxx来使用它里面的内容git
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile rootProject.ext.dependencies["junit"] compile rootProject.ext.dependencies["support-v4"] compile rootProject.ext.dependencies["gson"] compile rootProject.ext.dependencies["appcompat-v7"] compile rootProject.ext.dependencies["cardview-v7"] compile rootProject.ext.dependencies["autolayout"] compile rootProject.ext.dependencies["butterknife"] compile rootProject.ext.dependencies["androideventbus"] }
也可使用它来管理一些项目的信息,这样有多个module也能够直接使用一个信息github
android { compileSdkVersion rootProject.ext.android["compileSdkVersion"] buildToolsVersion rootProject.ext.android["buildToolsVersion"] useLibrary 'org.apache.http.legacy' defaultConfig { minSdkVersion rootProject.ext.android["minSdkVersion"] targetSdkVersion rootProject.ext.android["targetSdkVersion"] versionCode rootProject.ext.android["versionCode"] versionName rootProject.ext.android["versionName"] } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }
本框架所有使用Dagger2管理,因此必须依赖Dagger2,找到app的build.gradle,加入以下代码数据库
apply plugin: 'com.android.application' apply plugin: 'com.neenbedankt.android-apt'//使用apt插件 buildscript { repositories { jcenter() mavenCentral() } dependencies { classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'//使用apt } } dependencies { apt rootProject.ext.dependencies["dagger2-apt-compiler"]//依赖apt插件 provided rootProject.ext.dependencies["javax.annotation"]//dagger2必须依赖jsr250 annotation }
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
使用Autolayout 自适应框架必须配置Meta属性及设计图的宽高,详情参考Autolayoutapache
//将设计图的宽高配置后,配合AutoLauout控件使用,在设计图尺寸之外的其它尺寸手机上,也能达到和设计图同样的显示效果 <meta-data android:name="design_width" android:value="1080"/> <meta-data android:name="design_height" android:value="1920"/>
本框架默认使用
Glide
加载图片,但提供一个管理器ImageLoader
提供统一接口,使用策略者模式可轻松替换图片加载框架,本框架默认提供Glide
的自定义缓存配置信息,使用它以前先引用它的自定义配置信息json
<!--glide配置--> <meta-data android:name="com.jess.arms.widget.imageloader.glide.GlideConfiguration" android:value="GlideModule"/>
因为本框架依赖大量三方库,因此已经在arms Module
下的proguard-rules.pro中提供了全部规则,若是想使用它,请复制它替换app Module
中的proguard-rules.pro,混淆时能够根据本身的需求修改或添加规则,混淆前务必注意将Java Bean,自定义组件添加进规则缓存
! 必定不能修改common包的包名,旧版本须要找到和common包下同名的类并删除,而后从新引用common包里的类
服务器
若是你得到本框架的方式是经过clone或者下载:
git pull origin master
拉取最新的版本并自动合并git rm --cache -r app/src/main/java/me/jessyan/mvparms
,下次拉取时就不会拉取Demo的内容若是你得到本框架的方式是经过fork到本身仓库后,clone或下载:
git remote add arms https://github.com/JessYanCoding/MVPArms.git
添加远程仓库,arms是远程仓库的代号,可自定义,之后都经过这个代号对远程仓库做操做git fetch arms
拉取远程仓库最新的版本git merge arms/master --allow-unrelated-histories
合并远程仓库到当前分支--allow-unrelated-histories
只用在第一次合并时添加git rm --cache -r app/src/main/java/me/jessyan/mvparms
,下次拉取时就不会拉取Demo的内容
新建项目的Application继承自
BaseApplication
,并在AndroidManifest中声明
//BaseApplication为抽象类,必须实现getGlobeConfigModule,这里返回整个应用须要的配置信息(将app的全局配置信息封装进module,使用Dagger注入到须要配置信息的地方) @Override protected GlobeConfigModule getGlobeConfigModule() { return GlobeConfigModule .buidler() .baseurl(Api.APP_DOMAIN)//必须提供baseurl .build(); }
Application生命周期是和App是同样的,因此是适合提供一些单例对象,本框架使用
Dagger2
管理,因此使用AppComponent来提供全局全部的单例对象
@Singleton @Component(modules = {AppModule.class, ClientModule.class, ServiceModule.class, ImageModule.class, CacheModule.class, GlobeConfigModule.class}) public interface AppComponent { Application Application(); //服务管理器,retrofitApi ServiceManager serviceManager(); //缓存管理器 CacheManager cacheManager(); //Rxjava错误处理管理类 RxErrorHandler rxErrorHandler(); OkHttpClient okHttpClient(); //图片管理器,用于加载图片的管理类,默认使用glide,使用策略模式,可替换框架 ImageLoader imageLoader(); //gson Gson gson(); //用于管理全部activity AppManager appManager(); }
@Override public void onCreate() { super.onCreate(); mAppComponent = DaggerAppComponent .builder() .appModule(getAppModule())//baseApplication提供 .clientModule(getClientModule())//baseApplication提供 .globeConfigModule(getGlobeConfigModule())//全局配置 .imageModule(getImageModule())//baseApplication提供 .serviceModule(new ServiceModule())//需自行建立 .cacheModule(new CacheModule())//需自行建立 .build(); } //将AppComponent返回出去,供其它地方使用, AppComponent接口中声明的方法返回的实例, 在getAppComponent()拿到对象后均可以直接使用 public AppComponent getAppComponent() { return mAppComponent; }
Retrofit
Api)和CacheModule(提供缓存)都需自行建立,详情ServiceModule(2.1.2) ,CacheModule(2.1.3)
ServiceModule提供RetrofitApi对应的Service,这些Service对象在AppComponent中注入ServiceManager(需继承BaseServiceManager)中统一管理
public interface CommonService { String HEADER_API_VERSION = "Accept: application/vnd.github.v3+json"; @Headers({HEADER_API_VERSION}) @GET("/users") Observable<List<User>> getUsers(@Query("since") int lastIdQueried, @Query("per_page") int perPage); }
@Module public class ServiceModule { @Singleton @Provides CommonService provideCommonService(Retrofit retrofit) { return retrofit.create(CommonService.class); } }
@Singleton public class ServiceManager implements BaseServiceManager { private CommonService mCommonService; //若是须要添加service只需在构造方法中添加对应的service, 在提供get方法返回出去,只要在ServiceModule提供了该service Dagger2会自行注入 @Inject public ServiceManager(CommonService commonService){ this.mCommonService = commonService; } public CommonService getCommonService() { return mCommonService; } }
Cache层默认使用
RxCache
,CacheModule提供RetrofitApi对应的Cache对象,这些Cache对象在AppComponent中注入CacheManager(需继承BaseCacheManager)中统一管理
public interface CommonCache { @LifeCache(duration = 2, timeUnit = TimeUnit.MINUTES) Observable<Reply<List<User>>> getUsers(Observable<List<User>> oUsers, DynamicKey idLastUserQueried, EvictProvider evictProvider); }
@Module public class CacheModule { @Singleton @Provides CommonCache provideCommonService(RxCache rxCache) { return rxCache.using(CommonCache.class); } }
@Singleton public class CacheManager implements BaseCacheManager{ private CommonCache mCommonCache; //若是须要添加Cache只需在构造方法中添加对应的Cache, 在提供get方法返回出去,只要在CacheModule提供了该Cache Dagger2会自行注入 @Inject public CacheManager(CommonCache commonCache) { this.mCommonCache = commonCache; } public CommonCache getCommonCache() { return mCommonCache; } }
让项目的基类Activity继承BaseActivity,BaseActivity默认注入Presenter,因此若是要使用Presenter必须指定对应的范型,而且提供注入Presenter所须要的Component
public abstract class WEActivity<P extends BasePresenter> extends BaseActivity<P> { protected WEApplication mWeApplication; @Override protected void ComponentInject() { mWeApplication = (WEApplication) getApplication(); setupActivityComponent(mWeApplication.getAppComponent()); } //提供AppComponent(提供全部的单例对象)给子类,进行Component依赖 protected abstract void setupActivityComponent(AppComponent appComponent); }
让项目的基类Fragment继承BaseFragment,BaseFragment默认注入Presenter,因此若是要使用Presenter必须指定对应的范型,而且提供注入Presenter所须要的Component
public abstract class WEFragment<P extends BasePresenter> extends BaseFragment<P> { protected WEApplication mWeApplication; @Override protected void ComponentInject() { mWeApplication = (WEApplication)mActivity.getApplication(); setupFragmentComponent(mWeApplication.getAppComponent()); } //提供AppComponent(提供全部的单例对象)给子类,进行Component依赖 protected abstract void setupFragmentComponent(AppComponent appComponent); }
定义业务逻辑MVP,继承MVP各自的基类便可,这里能够稍微粗力度的定义MVP类,即无需每一个Fragment和Activity(每一个页面)都定义不一样的MVP类,能够按照相同的业务逻辑使用一组MVP类
这里根据
public interface UserContract { //对于常用的关于UI的方法能够定义到BaseView中,如显示隐藏进度条,和显示文字消息 interface View extends BaseView { void setAdapter(DefaultAdapter adapter); void startLoadMore(); void endLoadMore(); } //Model层定义接口,外部只需关心model返回的数据,无需关心内部细节,及是否使用缓存 interface Model extends IModel{ Observable<List<User>> getUsers(int lastIdQueried, boolean update); } }
通常让Activity或Fragment实现Contract中定义的View接口,供Presenter调用对应方法操做UI,BaseActivity默认注入Presenter,如想使用Presenter,必须指定Presenter的范型,和实现setupActivityComponent来提供Presenter须要的Component和Module
public class UserActivity extends WEActivity<UserPresenter> implements UserContract.View { @Override protected void setupActivityComponent(AppComponent appComponent) { DaggerUserComponent .builder() .appComponent(appComponent) .userModule(new UserModule(this)) .build() .inject(this); } @Override protected View initView() { return LayoutInflater.from(this).inflate(R.layout.activity_user, null, false); } @Override protected void initData() { } }
Model实现Contract的Model接口,而且继承BaseModel,指定范型为,上面定义的ServiceManager和CacheManager,而后经过两个Manager拿到须要的Service和Cache为Presenter提供须要的数据(是否使用缓存请自行选择)
@ActivityScope public class UserModel extends BaseModel<ServiceManager,CacheManager> implements UserContract.Model{ private CommonService mCommonService; private CommonCache mCommonCache; @Inject public UserModel(ServiceManager serviceManager, CacheManager cacheManager) { super(serviceManager, cacheManager); this.mCommonService = mServiceManager.getCommonService(); this.mCommonCache = mCacheManager.getCommonCache(); } @Override public Observable<List<User>> getUsers(int lastIdQueried, boolean update) { } }
Presenter在MVP中的大部分的做用为经过从Model层接口获取数据,在调用View层接口显示数据,首先实现BasePresenter,指定Model和View的范型,注意必定要指定Contract中定义的接口,Presenter须要的Model和View,都使用Dagger2注入,这样即解藕又方便测试,怎么注入?
@ActivityScope public class UserPresenter extends BasePresenter<UserContract.Model, UserContract.View> { @Inject public UserPresenter(UserContract.Model model, UserContract.View rootView) { super(model, rootView); } //这里定义业务方法,相应用户的交互 public void requestUsers(final boolean pullToRefresh) { } }
这里的Module提供当前业务逻辑对应的View和Model接口(Contract中定义的接口)的实现类,Model须要AppComponent中提供的ServiceManager和CacheManager来实现网络请求和缓存,因此须要经过Component依赖AppComponent拿到这两个Manager
@Module public class UserModule { private UserContract.View view; //构建UserModule时,将View的实现类传进来,这样就能够提供View的实现类给presenter public UserModule(UserContract.View view) { this.view = view; } @ActivityScope @Provides UserContract.View provideUserView(){ return this.view; } @ActivityScope @Provides UserContract.Model provideUserModel(UserModel model){ return model; } }
这里须要注意的是此Component必须依赖AppComponent,这样才能提供Model须要的ServiceManager和CacheManager,提供inject()方法就能将Module及AppComponent中提供的对象注入到对应的类中,inject()中的参数不能是接口,怎么注入?
@ActivityScope @Component(modules = UserModule.class,dependencies = AppComponent.class) public interface UserComponent { void inject(UserActivity activity); }
在上面的代码中ActivityScope大量出如今Module和Component中,Dagger2使用Scope限制每一个Module中提供的对象的生命,Dagger2默认只提供一个
@Singleton
Scope即单例,本框架提供@ActvityScope和@FragmentScope,若有其余需求请自行实现,Module和Component定义相同的Scope后Module中提供的对象的生命周期会和Component中同样(即在Component生命周期内,如需使用到Moudle中提供的对象,只会调用一次@Provide注解的方法获得此对象)
GlobeConfigModule使用建造者模式将App的全局配置信息封装进Module(使用Dagger注入到须要配置信息的地方),能够配置CacheFile,InterCeptor等,由于使用的是建造者模式因此如你有其余配置信息须要使用
Dagger
注入,直接就能够添加进Builder而且不会影响到其余地方
//如需添加个Boolean字段提供给Log工具类,来判断是否打印Log @Module public class GlobeConfigModule { private Boolean isLog; private GlobeConfigModule(Buidler buidler) { this.isLog = builder.isLog } public static Buidler buidler() { return new Buidler(); } public static final class Buidler { private Boolean isLog; private Buidler() {} //1.给Builder中添加个方法接受isLog字段 public Buidler isLog(Boolean isLog) { this.isLog = isLog; return this; } public GlobeConfigModule build() { return new GlobeConfigModule(this); } } //2.使用@Provides,将isLog返回出去,供Dagger注入到Log工具类 @Singleton @Provides Boolean provideIsLog() { return isLog; } }
经过GlobeConfigModule.globeHttpHandler()方法传入GlobeHttpHandler
@Override protected GlobeConfigModule getGlobeConfigModule() { return GlobeConfigModule .buidler() .baseurl(Api.APP_DOMAIN) .globeHttpHandler(new GlobeHttpHandler() {// 这里能够提供一个全局处理http响应结果的处理类, // 这里能够比客户端提早一步拿到服务器返回的结果,能够作一些操做,好比token超时,从新获取 @Override public Response onHttpResultResponse(String httpResult, Interceptor.Chain chain, Response response) { //这里能够先客户端一步拿到每一次http请求的结果,能够解析成json,作一些操做,如检测到token过时后 //从新请求token,并从新执行请求 try { if (!TextUtils.isEmpty(httpResult)) { JSONArray array = new JSONArray(httpResult); JSONObject object = (JSONObject) array.get(0); String login = object.getString("login"); String avatar_url = object.getString("avatar_url"); Timber.tag(TAG).w("result ------>" + login + " || avatar_url------>" + avatar_url); } } catch (JSONException e) { e.printStackTrace(); return response; } //这里若是发现token过时,能够先请求最新的token,而后在拿新的token放入request里去从新请求 //注意在这个回调以前已经调用过proceed,因此这里必须本身去创建网络请求,如使用okhttp使用新的request去请求 // create a new request and modify it accordingly using the new token // Request newRequest = chain.request().newBuilder().header("token", newToken) // .build(); // // retry the request // // response.body().close(); //若是使用okhttp将新的请求,请求成功后,将返回的response return出去便可 //若是不须要返回新的结果,则直接把response参数返回出去 return response; } // 这里能够在请求服务器以前能够拿到request,作一些操做好比给request统一添加token或者header @Override public Request onHttpRequestBefore(Interceptor.Chain chain, Request request) { //若是须要再请求服务器以前作一些操做,则从新返回一个作过操做的的requeat如增长header,不作操做则返回request //return chain.request().newBuilder().header("token", tokenId) // .build(); return request; } }) .build(); }
若是须要使用Rxjava的全局错误处理,需经过GlobeConfigModule.responseErroListener()方法传入ResponseErroListener,并在每次使用Rxjava调用subscribe时,使用ErrorHandleSubscriber,并传入AppComponent中提供的RxErrorHandler,此Subscribe,默认已经实现OnError方法,如想自定义能够重写OnError方法
@Override protected GlobeConfigModule getGlobeConfigModule() { return GlobeConfigModule .buidler() .baseurl(Api.APP_DOMAIN) .responseErroListener(new ResponseErroListener() { // 用来提供处理全部错误的监听 // rxjava必要要使用ErrorHandleSubscriber(默认实现Subscriber的onError方法),此监听才生效 @Override public void handleResponseError(Context context, Exception e) { Timber.tag(TAG).w("------------>" + e.getMessage()); UiUtils.SnackbarText("net error"); } }).build(); }
Observable .just(1) .retryWhen(new RetryWithDelay(3,2))//遇到错误时重试,第一个参数为重试几回,第二个参数为重试的间隔 .subscribe(new ErrorHandleSubscriber<Integer>(mErrorHandler) { @Override public void onNext(Integer Integer) { } });
本框架默认使用
Glide
实现图片加载功能,使用ImagerLoader提供统一的接口,ImagerLoader使用策略模式和建造者模式,能够动态切换图片框架(好比说切换成Picasso
),而且加载图片时传入的参数也能够随意扩展(loadImage方法在须要扩展参数时,也不须要改动,所有经过Builder扩展,好比你想让内部的图片加载框架,清除缓存你只须要定义个boolean字段,内部根据这个字段if|else,其余操做同理)
public class PicassoImageLoaderStrategy implements BaseImageLoaderStrategy<PicassoImageConfig> { @Override public void loadImage(Context ctx, PicassoImageConfig config) { Picasso.with(ctx) .load(config.getUrl()) .into(config.getImageView()); } }
public class PicassoImageConfig extends ImageConfig{ private PicassoImageConfig(Buidler builder) { this.url = builder.url; this.imageView = builder.imageView; this.placeholder = builder.placeholder; this.errorPic = builder.errorPic; } public static Buidler builder() { return new Buidler(); } public static final class Buidler { private String url; private ImageView imageView; private int placeholder; protected int errorPic; private Buidler() { } public Buidler url(String url) { this.url = url; return this; } public Buidler placeholder(int placeholder) { this.placeholder = placeholder; return this; } public Buidler errorPic(int errorPic){ this.errorPic = errorPic; return this; } public Buidler imagerView(ImageView imageView) { this.imageView = imageView; return this; } public PicassoImageConfig build() { if (url == null) throw new IllegalStateException("url is required"); if (imageView == null) throw new IllegalStateException("imageview is required"); return new PicassoImageConfig(this); } } }
Glide
)方法一 在ImageModule中返回PicassoImageLoaderStrategy @Module public class ImageModule { @Singleton @Provides public BaseImageLoaderStrategy provideImageLoaderStrategy() { return new PicassoImageLoaderStrategy(); } @Singleton @Provides public ImageLoader provideImageLoader(BaseImageLoaderStrategy strategy) { return new ImageLoader(strategy); } } 方法2 拿到AppComponent中的 ImagerLoader mApplication .getAppComponent() .imageLoader() .setLoadImgStrategy(new PicassoImageLoaderStrategy()); 使用方法 mApplication .getAppComponent() .imageLoader() .loadImage(mApplication, GlideImageConfig .builder() .url(data.getAvatarUrl()) .imagerView(mAvater) .build());
本框架使用
AndroidEventBus
实现事件总线,此框架使用注解标记目标方法,统一将Tag的常量写到EventBusTag接口中,便于管理,若是要在当前对象中使用AndroidEventBus
请在须要使用的Activity,Fragment,Presenter中重写useEventBus()
,返回true表明使用,默认返回true
本框架使用AutoLayout框架,实现控件自适应,此框架要让组件自适应,必须让它的父控件,从新测量,和重写LayoutParams,而官方只默认提供了三个ViewGroup,AutoRelativeLayout,AutoLinearLayout,AutoFrameLayout实现了这些操做,为了方便开发者使用,本框架提供了一些经常使用的AutoLayout组件,在框架的widget包下的autolayout包中,在
xml
中引用便可使子控件自适应,而且还提供一个 Template(在最后面)用于生成自适应所须要的的Auto系列View,如须要使ScrollView的子控件自适应,使用此Template输入ScrollView,便可生成AutoScrollView,在xml
中引用便可
框架提供一个建造者模式的自定义PopupWindow组件CustomPopupWindow,本身实现布局后就能够直接使用这个实现PopupWindow,使用建造者模式,随意扩展自定义参数
本框架提供DefaultAdapter和BaseHolder基类快速实现Recycleview.
本框架使用RxPermissions用于权限管理(适配android6.0),并提供PermissionUtil工具类一行代码实现权限请求.适配Android6.0权限管理详解
PermissionUtil.launchCamera(new RequestPermission() { @Override public void onRequestPermissionSuccess() { launchCapture();//请求权限成功后作一些操做 } }, mRxPermissions, mRootView, mErrorHandler);
在主项目(app)的build.gradle中配置是否开启打印Log或则是否使用
LeakCanary
,等调试工具
android { buildTypes { debug { //这两个变量是自定义的,本身也能够自定义字段,他会默认配置到BuildConfig中,app中能够根据这些字段执行一些操做 buildConfigField "boolean", "LOG_DEBUG", "true" buildConfigField "boolean", "USE_CANARY", "true" minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } release { buildConfigField "boolean", "LOG_DEBUG", "false" buildConfigField "boolean", "USE_CANARY", "false" minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }
public class WEApplication extends BaseApplication { @Override public void onCreate() { if (BuildConfig.LOG_DEBUG) {//Timber日志打印 Timber.plant(new Timber.DebugTree()); } if (BuildConfig.USE_CANARY) {//leakCanary内存泄露检查 LeakCanary.install(this); } } }
AppManager用于管理全部的Activity,内部持有一个含有全部存活的Activity(未调用onDestroy)的List,和一个当前在最前端的Activity(未调用onPause),AppManager封装有多种方法,能够很方便的对它们进行操做,也能够在未持有AppManager的状况下,经过
EventBus
远程遥控它的全部方法,这样咱们能够在整个app的任何地方对任何Activity进行全局操做,好比在app请求网络超时时让最前端的Activity显示链接超时的交互页面(这个逻辑不用写到当前请求的Activity里,能够在一个单例类里作全局的统一操做,由于能够随时经过AppManager拿到当前的Activity)
EventBus
post Message实现,经过不一样的what区分不一样的方法和Handler同理,能够根据本身的需求适当的在AppManager中添加对应的方法/** * 经过eventbus post事件,远程遥控执行对应方法 */ @Subscriber(tag = APPMANAGER_MESSAGE, mode = ThreadMode.MAIN) public void onReceive(Message message) { switch (message.what) { case START_ACTIVITY: dispatchStart(message); break; case SHOW_SNACKBAR: showSnackbar((String) message.obj, message.arg1 == 0 ? false : true); break; case KILL_ALL: killAll(); break; case APP_EXIT: AppExit(); break; } }
感谢本框架所使用到的全部三方库的Author,以及全部为Open Sourece
作无私贡献的Developer和Organizations,使咱们能更好的工做和学习,本人也会将业余时间回报给开源社区