MVP 使用文檔
導(dǎo)入
將MVP資源包導(dǎo)入
在settings.gradle設(shè)置如下目錄
rootProject.name='Test'
include ':app'
include ': mvplib '
include ' : mvplib:libMvpAnotation:compiler '
在 app build.gradle
implementation project(path: ':mvplib')
annotationProcessor project(path: ':mvplib:libMvpAnotation:compiler')
注釋: compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
必須使用java8依賴
必須導(dǎo)入version.gradlee
使用
注釋使用
@MvpEntity
使用該注解得到從服務(wù)器beam類(這里要特別注意code值)
@MvpEntity
public class HttpResult<T> implements IMvpEntity<T> {
/**
* 'code': '1',
* 'message': '成功提示',
* 'data':
*/
private int code;
private String message;
private T data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
@Override
public boolean isOk() {
//每個(gè)服務(wù)器返回的code值
return code == 1 && data != null;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
@OkInterceptor(1)
添加自定義ok攔截器
@OkInterceptor(1)//括號(hào)里代表OK連接器的等級(jí)
public class Intercepter1 implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
return chain.proceed(chain.request());
}
}
@ApiService
自定義ApiService
@ApiService
public interface AppApiService {
@POST()
Observable<HttpResult<User>> getUser(@FieldMap HashMap<String, Object> map);
}
@BaseUrl
自定義BaseUrl
public interface Constrant {
@BaseUrl
String BASE_URL = "https://www.seetao.com";
}
設(shè)置請(qǐng)求params
public class MvpApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
MvpManager.setParamsGetter(ParamsUtils::getCommonParams);
}
}
自定義解析GsonFactory
@GsonConverter
public class JDGsonConverterFactory extends MvpGsonConverterFactory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new JDGsonResponseBodyConverter<>(gson, adapter,type);
}
}
/**
* 繼承BaseSmartFragment1<>范型返回需要的解析的數(shù)據(jù)
*/
public class JDGsonResponseBodyConverter<T> extends MvpGsonResponseBodyConverter<T> {
public JDGsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter, Type type) {
super(gson, adapter, type);
}
@Override
public String handJson(String json) {
try {
JSONObject jsonObject = new JSONObject(json);
if(!jsonObject.isNull("code")){
int code = jsonObject.getInt("code");
if(code != 1){ // 失敗
if(!jsonObject.isNull("data")){
String data = jsonObject.getString("data");
if(TextUtils.isEmpty(data)){ // 如果 data 是一個(gè)空字符串
jsonObject.remove("data");
return jsonObject.toString();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return json;
}
}
使用
ONE 繼承BaseSmartFragment1
使用在Fragment頁(yè)面
public class VideoFragment extends BaseSmartFragment1<VideoBean> {
/**
*
* @return
* 返回該類所在xml布局
*/
@Override
protected int getLayoutId() {
return R.layout.fragment_video;
}
/**
*
* @param data
* 接受成功bean類
*/
@Override
public void onResult1(MvpResponse<VideoBean> data) {
if (data.getCode() == 1) {
Toast.makeText(getActivity(), data.getData().getList().get(1).getShare_link(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity(), data.getMsg(), Toast.LENGTH_SHORT).show();
}
}
/**
* 1.創(chuàng)建請(qǐng)求對(duì)象如果是
* 范型中添加得到bean類
* Get請(qǐng)求創(chuàng)建GetRequest
* Post請(qǐng)求創(chuàng)建PostRequest
* 2.如果有參數(shù)調(diào)用
* request.setParams();設(shè)置參數(shù)
*3.調(diào)用請(qǐng)求方法
* doRequest(request);
*/
@Override
protected void initView() {
super.initView();
GetRequest<VideoBean> request = new GetRequest<>("/app/v_1_6/article/videolist");
doRequest(request);
}
/**
*
* @param view
* 綁定View
*/
@Override
protected void bindView(View view) {
super.bindView(view);
}
TWO(在p層處理邏輯)
重寫p層
創(chuàng)建契約類
創(chuàng)建Presenter繼承IBasePresenter
創(chuàng)建View繼承IBaseView
public interface ConstrantVideo {
// 創(chuàng)建P層繼承IBasePresenter
interface IVideoPresenter extends IBasePresenter<IVideoView> {
//p傳遞數(shù)據(jù)方法
void getVideoData();
}
// 創(chuàng)建View契約類
interface IVideoView extends IBaseView<ConstrantVideo.IVideoPresenter> {
void onSucces(Video video);
void onFail(String error);
void onNetError();
void showLoadLing();
void closeLoadLing();
}
}
創(chuàng)建P層
BaseRepository創(chuàng)建model成員變量在P層構(gòu)造方法通過new BaseRepository()得到model實(shí)例
在P層方法中根據(jù)請(qǐng)求Url 創(chuàng)建GetRequest或者PostRequest對(duì)象
如果有參數(shù)設(shè)置請(qǐng)求參數(shù)
通過model對(duì)象調(diào)用mModel.doRequest(request,new IBaseCallBack<T>{})獲得數(shù)據(jù)
public class VideoPresenter extends BasePresenter<ConstrantVideo.IVideoView> implements ConstrantVideo.IVideoPresenter {
private BaseRepository mModel;
private CompositeDisposable mCompositeDisposable = new CompositeDisposable();
public VideoPresenter() {
mModel = new BaseRepository();
}
@Override
public void getVideoData() {
// 給請(qǐng)求對(duì)象添加參數(shù)
GetRequest request = new GetRequest("/app/v_1_6/article/videolist");
// 設(shè)置請(qǐng)求參數(shù)
request.setParams(ParamsUtils.getCommonParams());
request.setType(Video.class);
// 加載動(dòng)畫
mView.showLoadLing();
mModel.doRequest(request, new IBaseCallBack<Video>() {
// 切斷cut方法
@Override
public void onCut(Disposable disposable) {
mCompositeDisposable.add(disposable);
}
// 獲取結(jié)果
@Override
public void onResult(MvpResponse<Video> data) {
if (data.getCode() == 1) {
mView.onSucces(data.getData());
mView.closeLoadLing();
} else {
mView.onFail(data.getMsg());
}
}
});
}
@Override
public boolean cancelRequest() {
return true;
}
}
Fragmenrt
繼承BaseMvpFragment<T extend IBasePresenter>implements具體的View
在成功失敗方法得到數(shù)據(jù)
public class VideoFragmenrt extends BaseMvpFragment<ConstrantVideo.IVideoPresenter> implements ConstrantVideo.IVideoView {
@Override
protected int getLayoutView() {
return R.layout.fragment_video_fragmenrt;
}
@Override
public void onSucces(Video video) {
toast(video.getList().get(2).getShare_link());
}
@Override
public void onFail(String error) {
toast(error);
}
@Override
public void onNetError() {
toast("網(wǎng)絡(luò)錯(cuò)誤");
}
@Override
public void showLoadLing() {
showPopLoading();
}
@Override
public void closeLoadLing() {
closeLoading();
}
@Override
public ConstrantVideo.IVideoPresenter creatPresenter() {
return new VideoPresenter();
}
@Override
protected void initView() {
mPresenter.getVideoData();
}
}
Three(在model層做數(shù)據(jù)緩存)
重寫model層
在Fragment
//重寫createPresenter 返回自定義的model 層
@Override
public BaseSmartPresenter1<RecommendData, ?> createPresenter() {
return new BaseSmartPresenter1<>(RecommondRepository.getInstance());
}
重寫model
public class RecommondRepository extends BaseRepository {
private static final String CACHE_FILE_NAME_PREFIX = "version_code";
private static RecommondRepository mInstance;
private HashMap<String, RecommendData> mMemoryData = new HashMap<>();
/**
*
* @return
* 單例是的只有一個(gè)model對(duì)象
*/
public static RecommondRepository getInstance() {
// 判斷對(duì)象是否創(chuàng)建
if (mInstance == null) {
// 在此處創(chuàng)建線程索讓其他線程減少等待時(shí)間
synchronized (RecommondRepository.class) {
// 如果線程1拿到鎖對(duì)象未創(chuàng)建完成,線程2拿到鎖創(chuàng)建完對(duì)象線程1繼續(xù)創(chuàng)建此時(shí)對(duì)象已經(jīng)通過線程2實(shí)例化所以進(jìn)行二次判空
if (mInstance == null) {
// 創(chuàng)建對(duì)象
mInstance = new RecommondRepository();
}
}
}
return mInstance;
}
@Override
public <T> void doRequest(LifecycleProvider lifecycleProvider, MvpRequest<T> request, IBaseCallBack<T> callBack) {
/*取數(shù)據(jù)*/
// 不調(diào)用父類的方法,重寫子類
// super.doRequest(lifecycleProvider, request, callBack);
// 得到欄目ID
String columnId = request.getParams().get(Constract.RequestKey.KEY_COLUMN_ID).toString();
switch (request.getRequestType()) {
// case加入括號(hào){}可以重復(fù)創(chuàng)建變量局部變量只能在方法里有效
/**
* 默認(rèn)都是第一次請(qǐng)求
* 刷新和加載更多都不需要讀取緩存數(shù)據(jù)
*/
case FIRST: {
// step1.先從內(nèi)從存查找直接傳入P層
MvpResponse response = getFromMemory(columnId);
if (response != null) {
callBack.onResult(response);
return;
}
// step2.如果內(nèi)存沒有直接從sdcard讀取
/*
*Observable 內(nèi)置線程池節(jié)省系統(tǒng)開銷
* scared都為耗時(shí)操作為 */
Observable.create(new ObservableOnSubscribe<MvpResponse>() {
@Override
public void subscribe(@NonNull ObservableEmitter<MvpResponse> emitter) throws Throwable {
MvpResponse fromSdCard = getFromSdCard(columnId);
if (fromSdCard != null) {
emitter.onNext(fromSdCard);
emitter.onComplete();
} else {
emitter.onError(new NullPointerException("sdcard no data"));
}
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<MvpResponse>() {
@Override
public void accept(MvpResponse mvpResponse) throws Throwable {
callBack.onResult(mvpResponse);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Throwable {
doRequest(lifecycleProvider, request, callBack, new CacheTask<>(request));
}
});
break;
}
default:{
// 從服務(wù)請(qǐng)求
doRequest(lifecycleProvider,request,callBack,new CacheTask<>(request));
}
}
}
// 讀取內(nèi)存數(shù)據(jù)
private MvpResponse getFromMemory(String key) {
// 看內(nèi)存是否有該數(shù)據(jù)
RecommendData data = mMemoryData.get(key);
if (data != null) {
// 設(shè)置數(shù)據(jù)
MvpResponse<RecommendData> response = new MvpResponse<>();
return response.setData(data).setCode(1).setRequestType(RequestType.FIRST).setType(ResponseType.MEMORY);
}
return null;
}
/**
* @param key
* @return 從sd卡讀取文件
*/
private MvpResponse getFromSdCard(String key) {
// 從內(nèi)存卡讀取數(shù)據(jù)
RecommendData data = MvpDataFileCacheUtils.getencryptedDataFromFile(getCacheDataSdcardFile(key), RecommendData.class);
if (data != null) {
MvpResponse<RecommendData> response = new MvpResponse<>();
return response.setCode(1).setData(data).setType(ResponseType.SDCARD);
}
return null;
}
/**
* @param columnId
* @return 創(chuàng)建手機(jī)文件
*/
// 找到文件
private File getCacheDataSdcardFile(String columnId) {
return new File(MvpManager.getExternalCacheDir(), CACHE_FILE_NAME_PREFIX + columnId);
}
// 緩存數(shù)據(jù)
private class CacheTask<T> implements Consumer<MvpResponse<T>> {//實(shí)現(xiàn)做緩存接口
private MvpRequest request;
CacheTask(MvpRequest request) {
this.request = request;
}
@SuppressWarnings("ALL")
@Override
public void accept(MvpResponse<T> mvpResponse) throws Throwable {
// 得到保存的Key值
String key = request.getParams().get(Constract.RequestKey.KEY_COLUMN_ID).toString();
saveToMemory((MvpResponse<RecommendData>) mvpResponse, request.getRequestType(), key);
saveToSdcard((MvpResponse<RecommendData>) mvpResponse, key);
}
// 保存到card
private void saveToSdcard(MvpResponse<RecommendData> mvpResponse, String key) {
}
// 保存到內(nèi)存
private void saveToMemory(MvpResponse<RecommendData> mvpResponse, RequestType requestType, String key) {
if (requestType != RequestType.LOAD_MORE){//不是加載更多
mMemoryData.clear();//將內(nèi)存設(shè)置空
RecommendData recommendData = new RecommendData();//創(chuàng)建空對(duì)象開辟內(nèi)存
RecommendData serverData = mvpResponse.getData();//從網(wǎng)絡(luò)獲取data
// 設(shè)置數(shù)據(jù)
recommendData.setAlbumId(serverData.getAlbumId());
recommendData.setAlbumNews(serverData.getAlbumNews());
recommendData.setAlbumTitle(serverData.getAlbumTitle());
recommendData.setBannerList(serverData.getBannerList());
recommendData.setFlashId(serverData.getFlashId());
recommendData.setFlashNews(serverData.getFlashNews());
recommendData.setMore(serverData.getMore());
recommendData.setPointTime(serverData.getPointTime());
recommendData.setStart(serverData.getStart());
recommendData.setNews(new ArrayList<>(serverData.getNews()));
// 緩存到集合
mMemoryData.put(key,recommendData);
}else {
RecommendData cacheData = mMemoryData.get(key);//獲取緩存加入數(shù)據(jù)
RecommendData serverData = mvpResponse.getData();//獲取網(wǎng)絡(luò)數(shù)據(jù)
// 如果網(wǎng)絡(luò)數(shù)據(jù)和緩存數(shù)據(jù)都不為空
if(cacheData != null && serverData != null){
// 所有數(shù)據(jù)只有新聞數(shù)據(jù)需要實(shí)施gen新
cacheData.setStart(serverData.getStart());
cacheData.setNumber(serverData.getNumber());
cacheData.setPointTime(serverData.getPointTime());
cacheData.setMore(serverData.getMore());
cacheData.getNews().addAll(serverData.getNews());
}
}
}
}
}