?? Sugar
image
最新版本1.0.1.4
需求:新項目只需5分鐘接入,之后直接開擼,不用關心網絡、圖片、模式、穩定等問題,支持mvp一個activity對應多個presenter。
適用自己的才是最好的!
更新日志
- 2019-06-14 更新 kotlin接入啦,還有一些好用的方法更新,后續更新文檔
- 2019-05-29 最新,新鮮temeple出爐,請拉到最后看效果
- 2019-05-31 更新 1.0.1.3升級到androidx
- ...
To do
- anko
- kotlin-mvp temeple
- kotlin 全面支持 ??
- 圖片加載庫更換策略,或者為了方便使用直接用一套寫好的放入
- 常用控件(刷新,標題等等)
- more...
最新修改
-
SugarHandleSubscriber
用于接口請求時候僅處理onNext()
,因為在SugarRepository
里面的customObservable(Observable observable)
函數里面統一處理了錯誤異常抓取,一般情況下不需要再處理OnError
當然可以重載函數的時候做處理
.doOnError(throwable -> {
LogUtils.i("doOnError------" + throwable);
if (mIView != null) {
mIView.showLoadFailed();
}
if (rxErrorHandler != null){
//統一異常抓取
rxErrorHandler.getHandlerFactory().handleError((Throwable) throwable);
}
});
- 使用
SugarHandleSubscriber
- java :
@Override
public void getFuliDataRepository(String size, String index) {
mModel.getFuliDataRepository(size, index)
.subscribe(new SugarHandleSubscriber<List<GirlsData>>() {
@Override
public void onNext(List<GirlsData> girlsData) {
mView.bindData(girlsData);
}
});
}
- kotlin
mModel.getFuliDataRepository(size, index)
.subscribe({
mView.bindData(it)
})
-
1.0.1.4
版本之后Presenter
不支持在Activity/Fragment
后寫泛型,只支持注解
- java:
@CreatePresenter(presenter = GankPresenter.class)
public class GankActivity extends BaseActivity implements GankContract.IView{
@PresenterVariable
GankPresenter mPresenter;
}
- kotlin
@CreatePresenter(presenter = [GankPresenter::class])
class KtGankActivity : BaseActivity(), GankContract.IView{
@PresenterVariable
internal var mPresenter: GankPresenter? = null
}
實用到的庫(排名不分先后)
RetrofitUrlManager retrofit動態綁定url
Gloading 深度解耦Android App中全局加載中、加載失敗及空數據視圖
RxPermissions Android runtime permissions powered by RxJava2
使用效果
image
圖片有壓縮,可以下載demo apk進行體驗
demo-debug.apk
安裝和依賴
3種選擇
1、 git clone https://github.com/wobiancao/sugar.git
implementation project(':sugarlibrary')
2、 implementation 'com.wobiancao:sugarlibrary:{version}'
3、 allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
implementation 'com.github.wobiancao:sugar:{version}'
統一配置
創建DemoConfigure 繼承于SugarConfigure 重載相關方法即可:
- 網絡配置(Retrofit和okhttp3)
Retrofit
請求,rxbus等) - 狀態欄默認顏色
ImmersionBar
- toast樣式
ToastUtils
你可以不用設置,有默認的 RxErroHandler rxjava異常獲取
- 網絡設置直接見代碼即可,跟retrofit一樣的配置,寫了一些默認的攔截器可繼承后使用也可自己寫,host可以動態配置
RetrofitUrlManager
- 解耦頁面狀態切換
Gloading
你可以不用設置,有默認的 - 默認等待框
BaseLoadingDialog
你可以不用設置,有默認的 - 更多詳見
AppConfigureDelegate
public class DemoConfigure extends SugarConfigure {
public DemoConfigure(Application application) {
super(application);
}
@Override
public ResponseErrorListener getErrorResponse() {
return new ResponseErrorListener() {
@Override
public void handleResponseError(Context context, Throwable t) {
LogUtils.i("捕獲異常---" + t.getMessage());
ToastUtils.show("發生異常---" + t.getMessage());
}
};
}
@Override
public int getStatusColor() {
return R.color.colorPrimary;
}
@Override
public AppHttpSetting getHttpSetting() {
return AppHttpSetting
.builder()
.with(mApplication)
//設置初始的baseUrl host
.setBaseUrl(Gank.HOST)
//動態修改baseUrl 具體看https://github.com/JessYanCoding/RetrofitUrlManager
.putDomain(Wan.DOMAN, Wan.HOST)
//是否打印網絡請求日志 默認否
.setHttpLog(true)
//百度Stetho即可 網絡監測等 默認否
.setHttpMoniter(true)
//設置緩存時間 默認60s
.setCacheMaxTime(65)
//設置連接超時 默認20s
.connectTimeout(20)
//設置讀取超時 默認20s
.readTimeout(20)
//設置寫入超時 默認20s
.writeTimeout(20)
//請求header
.addHeaderInterceptor(getHeader())
//添加請求明文公共參數
.addCustomHeaderInterceptor(getCustomHeader())
//token過期等請求成功處理 一般不需要處理
// .addExceptionInterceptor(getExceptionInterceptor())
//其它攔截
// .addInterceptor(xx)
// .addNetworkInterceptor(xxx)
// 配置自己的緩存
// .cache(xx)
//甚至另外寫一套自己的okhttp builder 也行
// .setOkHttpBuilder(xxx)
.build();
}
@Override
public IToastStyle getToastStyle() {
return new ToastStyle();
}
}
- 創建DemoApplication繼承于 LibApplication < S extends SugarConfigure > 重寫initConfigure()初始化配置即可,詳見
DemoApplication
public class DemoApplication extends LibApplication<DemoConfigure> {
@Override
protected void initConfigure() {
mConfigure = new DemoConfigure(this);
}
@Override
protected void init() {
}
}
網絡請求統一配置
-
問題:
我們使用RetrofitUrlManager
解決了retorfit動態配置baseUrl的問題,但是每個域名或者說每個接口返回參數封裝等的可能不統一(這種情況一般不會出現在公司項目)比如我這個app要展示Gank.io
和WanAndroid
的界面,這樣就是兩個網絡請求封裝,使用sugar可以快速解決此類問題; - 使用之前先看源碼
SugarRepository
/**
* @author wobiancao
* @date 2019/5/20
* desc :
*/
public class SugarRepository {
/**
* 0 沒loading 1 dialog形式 2page形式
*/
protected final static int LOADING_TYPE_NULL = 0;
/**
* 0 沒loading 1 dialog形式 2page形式
*/
protected final static int LOADING_TYPE_DIALOG = 1;
/**
* 0 沒loading 1 dialog形式 2page形式
*/
protected final static int LOADING_TYPE_PAGE = 2;
protected BaseIView mIView;
public SugarRepository(BaseIView IView) {
mIView = IView;
}
protected Observable addObservable(Observable observable) {
if (mIView == null) {
return null;
}
return customObservable(observable);
}
protected Observable addObservable(Observable observable, int loadingType) {
if (mIView == null) {
return null;
}
return customObservable(observable)
.doOnSubscribe(disposable -> {
if (loadingType > 0) {
if (loadingType == LOADING_TYPE_DIALOG) {
mIView.showDialogLoading();
} else {
mIView.showLoading();
}
}
});
}
private Observable customObservable(Observable observable) {
return observable
.compose(mIView.getProvider().bindToLifecycle())
.retryWhen(new RetryWithDelay(2, 2))
.subscribeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.doFinally(() -> {
if (mIView != null) {
mIView.hideDialogLoading();
}
})
.doOnNext(o -> {
LogUtils.e("doOnNext------" + o);
if (mIView != null) {
mIView.showLoadSuccess();
}
})
.doOnError(throwable -> {
LogUtils.e("doOnError------" + throwable);
if (mIView != null) {
mIView.showLoadFailed();
}
});
}
}
addObservable(Observable observable)不會使用任何loading效果,
addObservable(Observable observable, int loadingType) loadingType : 0 沒loading 、1 dialog形式 、2 page形式Repository首先有個契約類,
RepositoryContract
xxxModel為需要增加的一個域名接口,統一配置apiService、請求函數、相應的transformer
/**
* @author wobiancao
* @date 2019-05-21
* desc :
*/
public class RepositoryContract {
/**
* gank.io
*/
public interface GankModel {
Gank getService();
/**
* Transformer 需要處理api返回值包裝的加上即可
* @param <T>
* @return
*/
<T> ObservableTransformer<GirlsResult<T>, T> gankTransformer();
Observable<List<GirlsData>> getFuliDataRepository(String size, String index);
}
/**
* wanandroid
*/
public interface WanModel{
Wan getService();
/**
* Transformer 需要處理api返回值包裝的加上即可
* @param <T>
* @return
*/
<T> ObservableTransformer<WanResult<T>, T> wanTransformer();
Observable<WanData> getWanArticleList(String index);
}
}
- 使用,如GankRepository
/**
* @author wobiancao
* @date 2019/5/20
* desc :
*/
public class GankRepository extends SugarRepository implements RepositoryContract.GankModel {
public GankRepository(BaseIView IView) {
super(IView);
}
@Override
public Gank getService() {
return AppHttpClient.getInstance().initService(Gank.class);
}
@Override
public <T> ObservableTransformer<GirlsResult<T>, T> gankTransformer() {
return upstream -> upstream
.flatMap((Function<GirlsResult<T>, ObservableSource<T>>) tGirlsResult -> {
if (tGirlsResult == null) {
return Observable.error(new HttpException("返回值為null"));
}
if (!tGirlsResult.error) {
return Observable.just(tGirlsResult.results);
} else {
return Observable.error(new HttpException("接口異常"));
}
});
}
@Override
public Observable<List<GirlsData>> getFuliDataRepository(String size, String index) {
return addObservable(getService()
.getFuliData(size, index)
.compose(gankTransformer()), LOADING_TYPE_PAGE);
}
}
最后mvp創建(之后會寫相應的Template
??已寫好)
- 以
WanActivity
舉例 - 構成為
WanContract契約
、WanPresenter
好了,完了,結束。
image
- =。=假的,接下來看代碼
WanContract
/**
* @author wobiancao
* @date 2019-05-21
* desc :
*/
public class WanContract {
public interface PView{
void getWanArticleList(String index);
}
public interface IView extends BaseIView {
/**
* 綁定列表數據
* @param data
*/
void bindData(WanData data);
}
}
WanPresenter
/**
* @author wobiancao
* @date 2019-05-21
* desc :
*/
public class WanPresenter extends BasePresenter<WanContract.IView, WanRepository> implements WanContract.PView {
@Override
protected void initRepository() {
mModel = new WanRepository(mView);
}
@Override
public void getWanArticleList(String index) {
mModel.getWanArticleList(index)
.subscribe(new ErrorHandleSubscriber<WanData>(rxErrorHandler) {
@Override
public void onNext(WanData wanData) {
mView.bindData(wanData);
}
});
}
}
- 就是這么簡單,最后就是在view層如何使用了,老規矩先看代碼
WanActivity
/**
* @author wobiancao
* @date 2019-05-21
* desc :
*/
@CreatePresenter(presenter = WanPresenter.class)
public class WanActivity extends BaseActivity<WanPresenter> implements WanContract.IView {
@PresenterVariable
WanPresenter mPresenter;
TextView mInfoView;
Toolbar mToolbar;
@Override
protected int getContentView() {
return R.layout.gank_activity_list;
}
@Override
public void init(Bundle savedInstanceState) {
mInfoView = findViewById(R.id.tv_info);
mToolbar = findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle("WanAndroid");
}
}
@Override
public void loadData() {
mPresenter.getWanArticleList("1");
}
@Override
public void bindData(WanData data) {
String jsonStr = new Gson().toJson(data);
mInfoView.setText(jsonStr);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
}
是的Presenter創建只需要注解即可,并且支持多個presenter
這里要萬分感謝EasyMvp一個簡單強大且靈活的MVP框架
- 首先,單個presenter
@CreatePresenter(presenter = WanPresenter.class)
public class WanActivity extends BaseActivity<WanPresenter> implements WanContract.IView
獲取presenter變量兩種方式
1、通過注解
@PresenterVariable
WanPresenter mPresenter;
2、通過getPresenter()函數1.0.1.4
之后不支持
xxActivity extends BaseActivity<xxPresenter>...
xxPresenter getPresenter()
- 多個prenenter
就只有通過注解獲得變量了
@CreatePresenter(presenter = {xxPresenter1.class, xxPresenter2.class})
xxActivity extends BaseActivity...
@PresenterVariable
xxPresenter1 mPresenter1;
@PresenterVariable
xxPresenter2 mPresenter2;
本庫github地址 sugar 簡單便捷 快速開發Android項目,集合流行框架封裝mvp + rxjava2 + retrofit2 + rxlifecycle2 + arouter...
mvp Template完成
- 效果圖
image
image
-
使用見圖解
image
image
使用步驟:
- 下載源碼目錄在 Sugar/SugarMvpTemplate
image
把兩個文件夾放入
{Android Studio installation dir}\plugins\android\lib\templates\activities\
路徑下重啟Android studio即可使用
About me
- Email: a420245103@gmail.com
- 掘金: https://juejin.im/user/568be89760b24d71fed19d2b
- 簡書: http://www.lxweimin.com/u/114bbbfb977f
- apkbus: http://www.apkbus.com/?496060
- github: https://github.com/wobiancao
License
Copyright 2019, wobiancao
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.