一個(gè)快速集成框架:MVP+Dagger+主流框架,有它足矣
前言
今年的Android技術(shù)圈中MVP,Dagger2,Rxjava,Retrofit這些詞匯非常火,隨便打開(kāi)一個(gè)技術(shù)論壇都充斥著大量的關(guān)于這些技術(shù)的文章,Github也充斥著各種以基于MVP+Retrofit+RxJava+Dagger2+MaterialDesign開(kāi)發(fā)的xxxx為標(biāo)題的開(kāi)源項(xiàng)目或Demo.
但是大家這么熱心的開(kāi)源此類(lèi)項(xiàng)目,一直重復(fù)的做著同樣的事教授大家使用的方式和技巧有沒(méi)有想過(guò)依賴(lài)一個(gè)第三方庫(kù),就可以快速的搭建此類(lèi)框架?
特性
- 自動(dòng)生成MVP,Dagger2相關(guān)類(lèi)
- 版本更新
- 更新日志
- 通用框架,適合所有類(lèi)型的項(xiàng)目,支持大型項(xiàng)目的開(kāi)發(fā),Demo的包結(jié)構(gòu)直接可以拿來(lái)用
- 全部使用Dagger2管理(將所有模塊使用Dagger連接起來(lái),絕不是簡(jiǎn)單的使用)
- 大量使用Rxjava
- 修改包名(common包不要修改)后就可以直接使用,快速接入(老項(xiàng)目接入請(qǐng)按下面的步驟)
- 全部UI自適應(yīng)
- 圖片加載類(lèi)ImageLoader使用策略模式和建造者模式,輕松切換圖片加載框架和功能擴(kuò)展
- Model層提供Retrofit API和RxCache,是否使用緩存自行選擇
- 全局http Request(請(qǐng)求參數(shù),headers) Response(服務(wù)器返回的結(jié)果,headers,耗時(shí))信息監(jiān)聽(tīng),可解析json后根據(jù)狀態(tài)碼做相應(yīng)的全局操作
- 全局Rxjava錯(cuò)誤處理,錯(cuò)誤后自動(dòng)重試,捕捉整個(gè)應(yīng)用的所有錯(cuò)誤
框架結(jié)構(gòu)
包結(jié)構(gòu)
開(kāi)發(fā)須知
- 開(kāi)發(fā)者需要具有一定的Android開(kāi)發(fā)能力
- 開(kāi)發(fā)者必須有使用Dagger2,Rxjava,Retrofit的經(jīng)驗(yàn),沒(méi)使用過(guò)也必須了解,不然很難使用
Libraries簡(jiǎn)介
- MvpGoogle官方出品的Mvp架構(gòu)項(xiàng)目,含有多個(gè)不同的架構(gòu)分支(此為Dagger分支).
- Dagger2Google根據(jù)Square的Dagger1出品的依賴(lài)注入框架,通過(guò)apt動(dòng)態(tài)生成代碼,性能優(yōu)于用反射技術(shù)依賴(lài)注入的框架.
- Rxjava提供優(yōu)雅的響應(yīng)式Api解決異步請(qǐng)求.
- RxAndroid為Android提供響應(yīng)式Api.
- Rxlifecycle在Android上使用rxjava都知道的一個(gè)坑,就是生命周期的解除訂閱,這個(gè)框架通過(guò)綁定activity和fragment的生命周期***解決.
- RxbindingJakeWharton大神的View綁定框架,優(yōu)雅的處理View的響應(yīng)事件.
- RxCache是使用注解為Retrofit加入二級(jí)緩存(內(nèi)存,磁盤(pán))的緩存庫(kù)
- RetrofitSquare出品的網(wǎng)絡(luò)請(qǐng)求庫(kù),極大的減少了http請(qǐng)求的代碼和步驟.
- Okhttp同樣Square出品,不多介紹,做Android都應(yīng)該知道.
- Autolayout鴻洋大神的Android全尺寸適配框架.
- GsonGoogle官方的Json Convert框架.
- ButterknifeJakeWharton大神出品的view注入框架.
- Androideventbus一個(gè)輕量級(jí)使用注解的Eventbus.
- TimberJakeWharton大神出品Log框架,內(nèi)部代碼極少,但是思想非常不錯(cuò).
- Glide此庫(kù)為本框架默認(rèn)封裝圖片加載庫(kù),可參照著例子更改為其他的庫(kù),Api和Picasso差不多,緩存機(jī)制比Picasso復(fù)雜,速度快,適合處理大型圖片流,支持gfit,F(xiàn)resco太大了!,在5.0一下優(yōu)勢(shì)很大,5.0以上系統(tǒng)默認(rèn)使用的內(nèi)存管理和Fresco類(lèi)似.
- Realm速度和跨平臺(tái)性使它成為如今最火的數(shù)據(jù)庫(kù),美中不足的就是so庫(kù)太大
- LeakCanarySquare出品的專(zhuān)門(mén)用來(lái)檢測(cè)Android和Java的內(nèi)存泄漏,通過(guò)通知欄提示內(nèi)存泄漏信息
- RxErroHandlerRxjava錯(cuò)誤處理庫(kù),可在出現(xiàn)錯(cuò)誤后重試
1 開(kāi)發(fā)準(zhǔn)備
此框架適合自己做定制修改,所有暫時(shí)不上傳至Jcenter或Maven,請(qǐng)自行下載或clone
1.1 導(dǎo)入框架
- compile project(':arms')
1.2 引用config.build
本框架提供一個(gè)引用大量第三方庫(kù)的config.gradle文件,用于第三方庫(kù)版本管理,將config.gradle復(fù)制進(jìn)根目錄,并在項(xiàng)目的***build.gradle中引用它
1.2.1 使用config.build
因?yàn)樵?**build.gradle中引用了它,所以在整個(gè)項(xiàng)目的所有build.gradle中都可以使用rootProject.xxx來(lái)使用它里面的內(nèi)容
也可以使用它來(lái)管理一些項(xiàng)目的信息,這樣有多個(gè)module也可以直接使用一個(gè)信息
1.3 依賴(lài)Dagger2
本框架全部使用Dagger2管理,所以必須依賴(lài)Dagger2,找到app的build.gradle,加入如下代碼
1.4 配置AndroidManifest
1.4.1 添加權(quán)限
1.4.2 配置Autolayout Meta
使用Autolayout 自適應(yīng)框架必須配置Meta屬性及設(shè)計(jì)圖的寬高,詳情參考Autolayout
1.4.3 引用Glide自定義屬性
本框架默認(rèn)使用Glide加載圖片,但提供一個(gè)管理器ImageLoader提供統(tǒng)一接口,使用策略者模式可輕松替換圖片加載框架,本框架默認(rèn)提供Glide的自定義緩存配置信息,使用它之前先引用它的自定義配置信息
- <!--glide配置-->
- <meta-data
- android:name="com.jess.arms.widget.imageloader.glide.GlideConfiguration"
- android:value="GlideModule"/>
1.5 混淆
由于本框架依賴(lài)大量三方庫(kù),所以已經(jīng)在arms Module下的proguard-rules.pro中提供了所有規(guī)則,如果想使用它,請(qǐng)復(fù)制它替換app Module中的proguard-rules.pro,混淆時(shí)可以根據(jù)自己的需求修改或添加規(guī)則,混淆前務(wù)必注意將Java Bean,自定義組件添加進(jìn)規(guī)則
1.6 版本更新
! 一定不能修改common包的包名,舊版本需要找到和common包下同名的類(lèi)并刪除,然后重
新引用common包里的類(lèi)
如果你獲得本框架的方式是通過(guò)clone或者下載:
- 直接可以通過(guò)命令行g(shù)it pull origin master拉取***的版本并自動(dòng)合并
- 如果你修改了包名還得執(zhí)行命令git rm --cache -r app/src/main/java/me/jessyan/mvparms,下次拉取時(shí)就不會(huì)拉取Demo的內(nèi)容
如果你獲得本框架的方式是通過(guò)fork到自己倉(cāng)庫(kù)后,clone或下載:
- git remote add arms https://github.com/JessYanCoding/MVPArms.git 添加遠(yuǎn)程倉(cāng)庫(kù),arms是遠(yuǎn)程倉(cāng)庫(kù)的代號(hào),可自定義,以后都通過(guò)這個(gè)代號(hào)對(duì)遠(yuǎn)程倉(cāng)庫(kù)作操作
- git fetch arms拉取遠(yuǎn)程倉(cāng)庫(kù)***的版本
- git merge arms/master --allow-unrelated-histories合并遠(yuǎn)程倉(cāng)庫(kù)到當(dāng)前分支
- 后面如果本框架有更新就只用重復(fù)2,3步,--allow-unrelated-histories只用在***次合并時(shí)添加
- 如果你修改了包名還得執(zhí)行命令git rm --cache -r app/src/main/java/me/jessyan/mvparms,下次拉取時(shí)就不會(huì)拉取Demo的內(nèi)容
2 快速開(kāi)始
2.1 繼承BaseApplication
新建項(xiàng)目的Application繼承自BaseApplication,并在AndroidManifest中聲明
2.1.1 AppComponent
Application生命周期是和App是一樣的,所以是適合提供一些單例對(duì)象,本框架使用Dagger2管理,所以使用AppComponent來(lái)提供全局所有的單例對(duì)象
創(chuàng)建AppComponent接口
- 構(gòu)造AppComponent對(duì)象
- ServiceModule(提供RetrofitApi)和CacheModule(提供緩存)都需自行創(chuàng)建,詳情ServiceModule(2.1.2) ,CacheModule(2.1.3)
2.1.2 ServiceModule
ServiceModule提供RetrofitApi對(duì)應(yīng)的Service,這些Service對(duì)象在AppComponent中注入ServiceManager(需繼承BaseServiceManager)中統(tǒng)一管理
- 自行定義Retrofit Service如下,熟練Retrofit請(qǐng)忽略
- 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);
- }
- 定義ServiceModule,這里使用Retrofit對(duì)象(ClientModule提供)實(shí)例化Service接口,提供所有Service對(duì)象(可以根據(jù)不同的邏輯劃分多個(gè)Service接口)
- @Module
- public class ServiceModule {
- @Singleton
- @Provides
- CommonService provideCommonService(Retrofit retrofit) {
- return retrofit.create(CommonService.class);
- }
- }
- AppComponent將所有的Service注入到ServiceManager中,所有Model層都可以拿到此對(duì)象,意味著每個(gè)Model都可以請(qǐng)求任意Api
2.1.3 CacheModule
Cache層默認(rèn)使用RxCache,CacheModule提供RetrofitApi對(duì)應(yīng)的Cache對(duì)象,這些Cache對(duì)象在AppComponent中注入CacheManager(需繼承BaseCacheManager)中統(tǒng)一管理
- 自行定義RxCache Provider如下,熟練RxCache請(qǐng)忽略
- public interface CommonCache {
- @LifeCache(duration = 2, timeUnit = TimeUnit.MINUTES)
- Observable<Reply<List<User>>> getUsers(Observable<List<User>> oUsers, DynamicKey idLastUserQueried, EvictProvider evictProvider);
- }
- 定義CacheModule,這里使用RxCache對(duì)象(ClientModule提供)實(shí)例化所有Cache接口,提供所有Cache對(duì)象
- @Module
- public class CacheModule {
- @Singleton
- @Provides
- CommonCache provideCommonService(RxCache rxCache) {
- return rxCache.using(CommonCache.class);
- }
- }
- AppComponent將所有的Cache注入到CacheManager中,所有Model層都可以拿到所有的Cache對(duì)象
2.2 繼承BaseActivity
讓項(xiàng)目的基類(lèi)Activity繼承BaseActivity,BaseActivity默認(rèn)注入Presenter,所以如果要使用Presenter必須指定對(duì)應(yīng)的范型,并且提供注入Presenter所需要的Component
2.3 繼承BaseFragment
讓項(xiàng)目的基類(lèi)Fragment繼承BaseFragment,BaseFragment默認(rèn)注入Presenter,所以如果要使用Presenter必須指定對(duì)應(yīng)的范型,并且提供注入Presenter所需要的Component
2.4 MVP實(shí)戰(zhàn)
定義業(yè)務(wù)邏輯MVP,繼承MVP各自的基類(lèi)即可,這里可以稍微粗力度的定義MVP類(lèi),即無(wú)需每個(gè)Fragment和Activity(每個(gè)頁(yè)面)都定義不同的MVP類(lèi),可以按照相同的業(yè)務(wù)邏輯使用一組MVP類(lèi)
2.4.1 Contract
這里根據(jù)Google官方的MVP項(xiàng)目,可以在Contract中定義MVP的接口,便于管理,此框架無(wú)需定義Presenter接口,所以Contract只定義Model和View的接口
2.4.2 View
一般讓Activity或Fragment實(shí)現(xiàn)Contract中定義的View接口,供Presenter調(diào)用對(duì)應(yīng)方法操作UI,BaseActivity默認(rèn)注入Presenter,如想使用Presenter,必須指定Presenter的范型,和實(shí)現(xiàn)setupActivityComponent來(lái)提供Presenter需要的Component和Module
2.4.3 Model
Model實(shí)現(xiàn)Contract的Model接口,并且繼承BaseModel,指定范型為,上面定義的ServiceManager和CacheManager,然后通過(guò)兩個(gè)Manager拿到需要的Service和Cache為Presenter提供需要的數(shù)據(jù)(是否使用緩存請(qǐng)自行選擇)
2.4.4 Presenter
Presenter在MVP中的大部分的作用為通過(guò)從Model層接口獲取數(shù)據(jù),在調(diào)用View層接口顯示數(shù)據(jù),首先實(shí)現(xiàn)BasePresenter,指定Model和View的范型,注意一定要指定Contract中定義的接口,Presenter需要的Model和View,都使用Dagger2注入,這樣即解藕又方便測(cè)試,怎么注入?
2.4.5 MVP Module
這里的Module提供當(dāng)前業(yè)務(wù)邏輯對(duì)應(yīng)的View和Model接口(Contract中定義的接口)的實(shí)現(xiàn)類(lèi),Model需要AppComponent中提供的ServiceManager和CacheManager來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求和緩存,所以需要通過(guò)Component依賴(lài)AppComponent拿到這兩個(gè)Manager
2.4.6 MVP Component
這里需要注意的是此Component必須依賴(lài)AppComponent,這樣才能提供Model需要的ServiceManager和CacheManager,提供inject()方法就能將Module及AppComponent中提供的對(duì)象注入到對(duì)應(yīng)的類(lèi)中,inject()中的參數(shù)不能是接口,怎么注入?
- @ActivityScope
- @Component(modules = UserModule.class,dependencies = AppComponent.class)
- public interface UserComponent {
- void inject(UserActivity activity);
- }
2.4.7 Dagger Scope
在上面的代碼中ActivityScope大量出現(xiàn)在Module和Component中,Dagger2使用Scope限制每個(gè)Module中提供的對(duì)象的生命,Dagger2默認(rèn)只提供一個(gè)@SingletonScope即單例,本框架提供@ActvityScope和@FragmentScope,如有其他需求請(qǐng)自行實(shí)現(xiàn),Module和Component定義相同的Scope后Module中提供的對(duì)象的生命周期會(huì)和Component中一樣(即在Component生命周期內(nèi),如需使用到Moudle中提供的對(duì)象,只會(huì)調(diào)用一次@Provide注解的方法得到此對(duì)象)
2.4.8 MVP總結(jié)
以后每個(gè)業(yè)務(wù)邏輯都重復(fù)構(gòu)造這些類(lèi),只是換個(gè)名字而已,值得注意的是MVP剛開(kāi)始用時(shí)確實(shí)會(huì)覺(jué)得平白無(wú)故多了很多類(lèi),非常繁瑣麻煩,但是等頁(yè)面代碼邏輯越來(lái)多時(shí),你會(huì)發(fā)現(xiàn)其中的好處,邏輯清晰,解耦,便于團(tuán)隊(duì)協(xié)作,測(cè)試容易,錯(cuò)誤好定位,所以現(xiàn)在本框架提供Template自動(dòng)生成代碼解決這個(gè)痛點(diǎn),讓開(kāi)發(fā)者更加愉快的使用本框架
3 功能使用
3.1 App全局配置信息(使用Dagger注入)
GlobeConfigModule使用建造者模式將App的全局配置信息封裝進(jìn)Module(使用Dagger注入到需要配置信息的地方),可以配置CacheFile,InterCeptor等,因?yàn)槭褂玫氖墙ㄔ煺吣J剿匀缒阌衅渌渲眯畔⑿枰褂肈agger注入,直接就可以添加進(jìn)Builder并且不會(huì)影響到其他地方
- //如需添加個(gè)Boolean字段提供給Log工具類(lèi),來(lái)判斷是否打印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中添加個(gè)方法接受isLog字段
- public Buidler isLog(Boolean isLog) {
- this.isLog = isLog;
- return this;
- }
- public GlobeConfigModule build() {
- return new GlobeConfigModule(this);
- }
- }
- //2.使用@Provides,將isLog返回出去,供Dagger注入到Log工具類(lèi)
- @Singleton
- @Provides
- Boolean provideIsLog() {
- return isLog;
- }
- }
3.2 全局捕捉Http請(qǐng)求和響應(yīng)
通過(guò)GlobeConfigModule.globeHttpHandler()方法傳入GlobeHttpHandler
- @Override
- protected GlobeConfigModule getGlobeConfigModule() {
- return GlobeConfigModule
- .buidler()
- .baseurl(Api.APP_DOMAIN)
- .globeHttpHandler(new GlobeHttpHandler() {// 這里可以提供一個(gè)全局處理http響應(yīng)結(jié)果的處理類(lèi),
- // 這里可以比客戶(hù)端提前一步拿到服務(wù)器返回的結(jié)果,可以做一些操作,比如token超時(shí),重新獲取
- @Override
- public Response onHttpResultResponse(String httpResult, Interceptor.Chain chain, Response response) {
- //這里可以先客戶(hù)端一步拿到每一次http請(qǐng)求的結(jié)果,可以解析成json,做一些操作,如檢測(cè)到token過(guò)期后
- //重新請(qǐng)求token,并重新執(zhí)行請(qǐng)求
- 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;
- }
- //這里如果發(fā)現(xiàn)token過(guò)期,可以先請(qǐng)求***的token,然后在拿新的token放入request里去重新請(qǐng)求
- //注意在這個(gè)回調(diào)之前已經(jīng)調(diào)用過(guò)proceed,所以這里必須自己去建立網(wǎng)絡(luò)請(qǐng)求,如使用okhttp使用新的request去請(qǐng)求
- // 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將新的請(qǐng)求,請(qǐng)求成功后,將返回的response return出去即可
- //如果不需要返回新的結(jié)果,則直接把response參數(shù)返回出去
- return response;
- }
- // 這里可以在請(qǐng)求服務(wù)器之前可以拿到request,做一些操作比如給request統(tǒng)一添加token或者h(yuǎn)eader
- @Override
- public Request onHttpRequestBefore(Interceptor.Chain chain, Request request) {
- //如果需要再請(qǐng)求服務(wù)器之前做一些操作,則重新返回一個(gè)做過(guò)操作的的requeat如增加header,不做操作則返回request
- //return chain.request().newBuilder().header("token", tokenId)
- // .build();
- return request;
- }
- })
- .build();
- }
3.3 全局錯(cuò)誤處理及發(fā)生錯(cuò)誤時(shí)重新執(zhí)行
如果需要使用Rxjava的全局錯(cuò)誤處理,需通過(guò)GlobeConfigModule.responseErroListener()方法傳入ResponseErroListener,并在每次使用Rxjava調(diào)用subscribe時(shí),使用ErrorHandleSubscriber,并傳入AppComponent中提供的RxErrorHandler,此Subscribe,默認(rèn)已經(jīng)實(shí)現(xiàn)OnError方法,如想自定義可以重寫(xiě)OnError方法
- 在Rxjava中使用
3.4 切換圖片請(qǐng)求框架
本框架默認(rèn)使用Glide實(shí)現(xiàn)圖片加載功能,使用ImagerLoader提供統(tǒng)一的接口,ImagerLoader使用策略模式和建造者模式,可以動(dòng)態(tài)切換圖片框架(比如說(shuō)切換成Picasso),并且加載圖片時(shí)傳入的參數(shù)也可以隨意擴(kuò)展(loadImage方法在需要擴(kuò)展參數(shù)時(shí),也不需要改動(dòng),全部通過(guò)Builder擴(kuò)展,比如你想讓內(nèi)部的圖片加載框架,清除緩存你只需要定義個(gè)boolean字段,內(nèi)部根據(jù)這個(gè)字段if|else,其他操作同理)
- 使用ImageLoader必須傳入一個(gè)實(shí)現(xiàn)了BaseImageLoaderStrategy接口的圖片加載實(shí)現(xiàn)類(lèi)從而實(shí)現(xiàn)動(dòng)態(tài)切換,所以首先要實(shí)現(xiàn)BaseImageLoaderStrategy,實(shí)現(xiàn)時(shí)必須指定一個(gè)繼承自ImageConfig的實(shí)現(xiàn)類(lèi),使用建造者模式,可以?xún)?chǔ)存一些信息,比如URL, ImageView,Placeholder等,可以不斷的擴(kuò)展,供圖片加載框架使用
- 實(shí)現(xiàn)ImageCofig使用建造者模式
- 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);
- }
- }
- }
- 在ImageLoader構(gòu)造時(shí)可以傳入PicassoImageLoaderStrategy(),也可以通過(guò)AppComponent拿到ImageLoader對(duì)象后,setLoadImgStrategy(new PicassoImageLoaderStrategy)替換之前的實(shí)現(xiàn)(默認(rèn)使用Glide)
3.***ndroidEventBus Tag
本框架使用AndroidEventBus實(shí)現(xiàn)事件總線,此框架使用注解標(biāo)記目標(biāo)方法,統(tǒng)一將Tag的常量寫(xiě)到EventBusTag接口中,便于管理,如果要在當(dāng)前對(duì)象中使用AndroidEventBus請(qǐng)?jiān)谛枰褂玫腁ctivity,Fragment,Presenter中重寫(xiě)useEventBus(),返回true代表使用,默認(rèn)返回true
3.6 AutoLayout組件
本框架使用AutoLayout框架,實(shí)現(xiàn)控件自適應(yīng),此框架要讓組件自適應(yīng),必須讓它的父控件,重新測(cè)量,和重寫(xiě)LayoutParams,而官方只默認(rèn)提供了三個(gè)ViewGroup,AutoRelativeLayout,AutoLinearLayout,AutoFrameLayout實(shí)現(xiàn)了這些操作,為了方便開(kāi)發(fā)者使用,本框架提供了一些常用的AutoLayout組件,在框架的widget包下的autolayout包中,在xml中引用即可使子控件自適應(yīng),并且還提供一個(gè) Template(在***面)用于生成自適應(yīng)所需要的的Auto系列View,如需要使ScrollView的子控件自適應(yīng),使用此Template輸入ScrollView,即可生成AutoScrollView,在xml中引用即可
3.7 自定義PopupWindow
框架提供一個(gè)建造者模式的自定義PopupWindow組件CustomPopupWindow,自己實(shí)現(xiàn)布局后就可以直接使用這個(gè)實(shí)現(xiàn)PopupWindow,使用建造者模式,隨意擴(kuò)展自定義參數(shù)
3.8 快速實(shí)現(xiàn)RecycleView
本框架提供DefaultAdapter和BaseHolder基類(lèi)快速實(shí)現(xiàn)Recycleview.
- BaseHolder默認(rèn)初始化了ButterKnife和AutoLayout,繼承后不僅可以直接注入View,布局還可以自適應(yīng)屏幕
- RecycleView默認(rèn)是不提供Item的點(diǎn)擊事件的,使用DefaultAdapter調(diào)用setOnItemClickListener可以實(shí)現(xiàn)Item的點(diǎn)擊事件
3.9 權(quán)限管理(適配Android6.0權(quán)限管理)
本框架使用RxPermissions用于權(quán)限管理(適配android6.0),并提供PermissionUtil工具類(lèi)一行代碼實(shí)現(xiàn)權(quán)限請(qǐng)求.適配Android6.0權(quán)限管理詳解
- PermissionUtil.launchCamera(new RequestPermission() {
- @Override
- public void onRequestPermissionSuccess() {
- launchCapture();//請(qǐng)求權(quán)限成功后做一些操作
- }
- }, mRxPermissions, mRootView, mErrorHandler);
3.10 Gradle配置啟動(dòng)DeBug模式
在主項(xiàng)目(app)的build.gradle中配置是否開(kāi)啟打印Log或則是否使用LeakCanary,等調(diào)試工具
- 在build.gradle中配置
- 在代碼中使用(比如在application中做一些初始化設(shè)置)
3.11 AppManager(管理所有的Activity)
AppManager用于管理所有的Activity,內(nèi)部持有一個(gè)含有所有存活的Activity(未調(diào)用onDestroy)的List,和一個(gè)當(dāng)前在最前端的Activity(未調(diào)用onPause),AppManager封裝有多種方法,可以很方便的對(duì)它們進(jìn)行操作,也可以在未持有AppManager的情況下,通過(guò)EventBus遠(yuǎn)程遙控它的所有方法,這樣我們可以在整個(gè)app的任何地方對(duì)任何Activity進(jìn)行全局操作,比如在app請(qǐng)求網(wǎng)絡(luò)超時(shí)時(shí)讓最前端的Activity顯示連接超時(shí)的交互頁(yè)面(這個(gè)邏輯不用寫(xiě)到當(dāng)前請(qǐng)求的Activity里,可以在一個(gè)單例類(lèi)里做全局的統(tǒng)一操作,因?yàn)榭梢噪S時(shí)通過(guò)AppManager拿到當(dāng)前的Activity)
遠(yuǎn)程遙控通過(guò)EventBuspost Message實(shí)現(xiàn),通過(guò)不同的what區(qū)分不同的方法和Handler同理,可以根據(jù)自己的需求適當(dāng)?shù)脑贏ppManager中添加對(duì)應(yīng)的方法
總結(jié)
如果你是構(gòu)建一個(gè)全新的項(xiàng)目,直接將整個(gè)項(xiàng)目clone(或者下載)下來(lái),直接將Demo當(dāng)成主Module,再將項(xiàng)目包名改成自己的包名,Demo包含可以直接使用的包結(jié)構(gòu),一個(gè)主流的MVP+Dagger2+Retrofit+Rxjava框架就這樣輕松的構(gòu)建成功了,現(xiàn)在你參考Demo Mvp包下的UserActivity的格式,使用Template在對(duì)應(yīng)包下自動(dòng)生成MVP,Dagger2相關(guān)類(lèi),配合查閱Wiki文檔慢慢掌握本框架,看再多文章不如早點(diǎn)在項(xiàng)目中使用它,在實(shí)踐中學(xué)習(xí)總是最快的.