BasePerryMvp
基于MVP+RxJava+Retrofit的通用型的基础网络请求架构,其包含了BaseActivity、BaseFragment、BaseModel、BasePresenter、BaseView。
依赖
Step 1.
添加Jitpack到您的root gradle,如果无法导包,一般情况下都是这个原因,请仔细检查
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0-rc2'
}
}
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
Step 2.
在需要使用到的Module中添加以下依赖
apply plugin: 'com.jakewharton.butterknife'
dependencies {
implementation 'com.github.weipeilong123:BasePerryMvp:1.0.3'
annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0-rc2'
}
注意
库中已有的依赖如下
api 'com.jakewharton:butterknife:9.0.0-rc2'
annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0-rc2'
api 'org.projectlombok:lombok:1.16.18'
api 'javax.annotation:javax.annotation-api:1.2'
api 'com.android.support:appcompat-v7:28.0.0'
api 'com.android.support:support-v13:28.0.0'
api 'com.android.support:cardview-v7:28.0.0'
api 'com.android.support:design:28.0.0'
api 'com.android.support:recyclerview-v7:28.0.0'
api 'com.google.code.gson:gson:2.8.5'
api 'com.squareup.okio:okio:1.14.0'
api 'com.squareup.okhttp3:okhttp:3.11.0'
api 'io.reactivex:rxjava:1.2.4'
api 'io.reactivex:rxandroid:1.2.1'
api 'com.squareup.retrofit2:retrofit:2.4.0'
api 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
api 'com.squareup.retrofit2:converter-gson:2.4.0'
api 'com.squareup.retrofit2:converter-scalars:2.1.0'
api 'com.squareup.okhttp3:logging-interceptor:3.4.2'
api 'com.github.bumptech.glide:glide:3.7.0'
api 'jp.wasabeef:glide-transformations:2.0.2'
api 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.22'
api 'org.greenrobot:eventbus:3.1.1'
api 'com.alibaba:fastjson:1.2.36'
api 'com.afollestad.material-dialogs:core:0.9.4.5'
api 'org.apache.commons:commons-lang3:3.5'
另外,library中util包下的GlideMan是加载图片的二次封装,可用来加载圆形、圆角图片等等。
使用方法
Demo目录结构
Step 1.
创建Bean模型,将你的API接口请求的结果用GsonFormat快速生成JSon实体类
GankBean.class
public class GankBean {
/**
* error : false
* results : [{"_id":"597e016c421aa90ca209c523","createdAt":"2017-07-30T23:55:24.154Z","desc":"Android终端","publishedAt":"2017-09-21T13:27:15.675Z","source":"chrome","type":"Android","url":"https://github.com/termux/termux-app","used":true,"who":"Jason"},{"_id":"597f2861421aa90ca209c527","createdAt":"2017-07-31T20:53:53.217Z","desc":"Google从 API 21 新增了接口 android.app.usage , 通过这个api我们可以统计到每个app的使用情况,启动次数,启动时间等,也可以判断是否前后台,比较方便。","images":["http://img.gank.io/c778f7da-b580-490b-961d-34706a57d326"],"publishedAt":"2017-09-21T13:27:15.675Z","source":"web","type":"Android","url":"http://www.jianshu.com/p/bdf47afe110d","used":true,"who":"Tamic (码小白)"},{"_id":"5980492b421aa90ca209c533","createdAt":"2017-08-01T17:26:03.968Z","desc":"内存泄漏简要分析","publishedAt":"2017-09-21T13:27:15.675Z","source":"web","type":"Android","url":"https://zhuanlan.zhihu.com/p/28169456?group_id=874607398092935168","used":true,"who":"Li Wenjing"},{"_id":"59c3201e421aa9727ddd19b6","createdAt":"2017-09-21T10:12:46.866Z","desc":"安卓版本的VegaScroll","images":["http://img.gank.io/22a7d123-7776-4954-8f73-176ad9e18ddf"],"publishedAt":"2017-09-21T13:27:15.675Z","source":"web","type":"Android","url":"https://github.com/xmuSistone/VegaLayoutManager","used":true,"who":"stone"},{"_id":"59bbe478421aa9118c8262ca","createdAt":"2017-09-15T22:32:24.21Z","desc":"Android上取代HashMap的ArrayMap","images":["http://img.gank.io/a87f186b-47cc-44a4-98c7-a2dd05576fe7"],"publishedAt":"2017-09-20T13:17:38.709Z","source":"web","type":"Android","url":"http://www.jianshu.com/p/088b9383f974","used":true,"who":"Niekon"},{"_id":"59bf3bb0421aa9118887ac35","createdAt":"2017-09-18T11:21:20.893Z","desc":"Glide v4最全中文文档来了!","publishedAt":"2017-09-20T13:17:38.709Z","source":"web","type":"Android","url":"https://github.com/Muyangmin/glide-docs-cn","used":true,"who":"Muyangmin"},{"_id":"59c1c557421aa9727fdb25c3","createdAt":"2017-09-20T09:33:11.73Z","desc":"你知道APP从启动到主页面显示经历了哪些过程吗?","publishedAt":"2017-09-20T13:17:38.709Z","source":"web","type":"Android","url":"https://mp.weixin.qq.com/s?__biz=MzIwMzYwMTk1NA==&mid=2247487014&idx=1&sn=ce2e5378d0dd8a8bc6b85358a8aaa47c","used":true,"who":"陈宇明"},{"_id":"59c1d24d421aa972845f2077","createdAt":"2017-09-20T10:28:29.264Z","desc":"全民 Google ARCore,解决官方不支持设备问题","publishedAt":"2017-09-20T13:17:38.709Z","source":"web","type":"Android","url":"https://github.com/tomthecarrot/arcore-for-all","used":true,"who":null},{"_id":"59b7909f421aa911847a0391","createdAt":"2017-09-12T15:45:35.132Z","desc":"View的事件分发机制\u2014\u2014由浅入深解析","publishedAt":"2017-09-19T12:07:31.405Z","source":"web","type":"Android","url":"http://www.jianshu.com/p/e6ceb7f767d8","used":true,"who":"匡罡"},{"_id":"59bfe526421aa911847a03b3","createdAt":"2017-09-18T23:24:22.545Z","desc":"一个简约番茄时钟的实现思路","images":["http://img.gank.io/cc9e461f-3e8d-456f-bba5-e15b80509dfb"],"publishedAt":"2017-09-19T12:07:31.405Z","source":"web","type":"Android","url":"http://rkhcy.github.io/2017/09/18/TomatoView%E5%AE%9E%E7%8E%B0/","used":true,"who":"HuYounger"}]
*/
private boolean error;
private List<ResultsBean> results;
public boolean isError() {
return error;
}
public void setError(boolean error) {
this.error = error;
}
public List<ResultsBean> getResults() {
return results;
}
public void setResults(List<ResultsBean> results) {
this.results = results;
}
public static class ResultsBean {
/**
* _id : 597e016c421aa90ca209c523
* createdAt : 2017-07-30T23:55:24.154Z
* desc : Android终端
* publishedAt : 2017-09-21T13:27:15.675Z
* source : chrome
* type : Android
* url : https://github.com/termux/termux-app
* used : true
* who : Jason
* images : ["http://img.gank.io/c778f7da-b580-490b-961d-34706a57d326"]
*/
private String _id;
private String createdAt;
private String desc;
private String publishedAt;
private String source;
private String type;
private String url;
private boolean used;
private String who;
private List<String> images;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public boolean isUsed() {
return used;
}
public void setUsed(boolean used) {
this.used = used;
}
public String getWho() {
return who;
}
public void setWho(String who) {
this.who = who;
}
public List<String> getImages() {
return images;
}
public void setImages(List<String> images) {
this.images = images;
}
}
}
Step 2.
将您的Application类继承自BaseMvpApplication,并在AndroidManifest中注册。
MyApp.class
public class MyApp extends BaseMvpApplication {
@Override
public void setTimeout(int connect, int read, int write) {
super.setTimeout(15, 12, 12);//设置连接超时,读超时,写超时
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ren.perry.baseperrymvp">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:name=".MyApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
Step 3.
创建网络请求相关的类
ApiService.class
public interface ApiService {
/**
* 干货集中营
*/
String GANK_URL = "http://gank.io";
//---------------------------------我只是个分割线-------------------------------------------------
/**
* 干货数据
*
* @param type type
* @param page page
* @return TopBean
*/
@GET("/api/data/{type}/10/{page}")
Observable<GankBean> gankData(
@Path("type") String type,
@Path("page") int page);
}
ApiEngine.class
public class ApiEngine {
private volatile static ApiEngine apiEngine;
private ApiEngine() {
}
public static ApiEngine getInstance() {
if (apiEngine == null) {
synchronized (ApiEngine.class) {
if (apiEngine == null) {
apiEngine = new ApiEngine();
}
}
}
return apiEngine;
}
public ApiService getGankService() {
return new Retrofit.Builder()
.baseUrl(ApiService.GANK_URL)
.client(NetClient.getInstance().getOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build().create(ApiService.class);
}
}
Step 4.
创建MVP模式相关的类
MainContract.class
public interface MainContract {
interface View extends BaseView {
void onSuccess(GankBean bean);
void onError(ApiException.ResponseException e);
}
interface Model extends BaseModel {
Observable<GankBean> getGankData(String type, int page);
}
abstract class Presenter extends BasePresenter<View, Model> {
public abstract void getGankData(String type, int page);
}
}
MainModel.class
public class MainModel implements MainContract.Model {
@Override
public Observable<GankBean> getGankData(String type, int page) {
return ApiEngine.getInstance()
.getGankService()
.gankData(type, page)
// .retryWhen(FuncTry.tryError()) //失败5s后自动重试
.compose(RxSchedulers.<GankBean>switchThread());
}
}
MainPresenter.class
public class MainPresenter extends MainContract.Presenter {
public MainPresenter(MainContract.View view) {
mView = view;
mModel = new MainModel();
}
@Override
public void getGankData(String type, int page) {
addSubscribe(mModel.getGankData(type, page)
.subscribe(new BaseSubscriber<GankBean>() {
@Override
public void onError(ApiException.ResponseException e) {
mView.onError(e);
}
@Override
public void onNext(GankBean bean) {
mView.onSuccess(bean);
}
}));
}
}
Step 5.
将Activity、Fragment继承自BaseActivity、BaseFragment,并增加泛型Presenter。
MainActivity.class
public class MainActivity extends BaseActivity<MainPresenter> implements MainContract.View {
@Bind(R.id.iv)
ImageView iv;
@Override
protected int initLayoutId() {
return R.layout.activity_main;
}
@Override
protected void initView() {
}
@Override
protected MainPresenter onCreatePresenter() {
return new MainPresenter(this);//创建Presenter对象
}
@Override
public void onSuccess(GankBean bean) {
//请求成功返回的结果
Log.e("MainActivity", "获取到数据:" + bean.getResults().size() + "条数据");
Glide.with(this)
.load(bean.getResults().get(0).getUrl())
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher)
.into(iv);
}
@Override
public void onError(ApiException.ResponseException e) {
//请求失败返回的结果
Log.e("MainActivity", "获取数据失败:" + e.code + "," + e.message);
Toast.makeText(this, e.message, Toast.LENGTH_SHORT).show();
}
@OnClick(R.id.btn)
public void onViewClicked() {
mPresenter.getGankData("福利", 1);
}
}