您的位置:首页 > 移动开发 > Android开发

Android Mvp+Rxjava+Retrofit实战

2016-08-13 10:53 519 查看

Android Mvp+Rxjava+Retrofit实战

目录结构



build.gradle

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:24.0.0'
compile 'com.orhanobut:logger:1.8'
compile 'io.reactivex:rxjava:1.1.7'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.google.code.gson:gson:2.7'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
}


Rxjava+Retrofit统一Http的封装

HttpService

Retrofit的配置

public interface HttpService {
/**
* 测量多点之间的直线距离
*
* @param waypoints 需要测距的点的经纬度坐标;需传入两个或更多的点。两个点之间用 “; ”进行分割开,单个点的经纬度用“,”分隔开;例如: waypoints=118
*                  .77147503233,32.054128923368;116.3521416286, 39.965780080447;116
*                  .28215586757,39.965780080447
* @param ak
* @param output
* @return
*/
@FormUrlEncoded
@POST("distance?")
Observable<BaseHttpResult<List<String>>> getDistance(@Field("waypoints") String waypoints,
@Field("ak") String ak,
@Field("output") String output);
}


HttpUtil

Retrofit和Rxjava进行结合 封装网络请求类

public class HttpUtil {
/**
* 超时时间
*/
private static final int DEFAULT_TIMEOUT = 10;
/**
* retrofit
*/
private Retrofit retrofit;
/**
* 接口请求
*/
private HttpService httpService;

public HttpService getHttpService() {
return httpService;
}

private HttpUtil() {
//创建一个OkHttpClient并设置超时时间
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
//添加迭代器
httpClientBuilder.addInterceptor(new LoggerInterceptor());
retrofit = new Retrofit.Builder()
.client(httpClientBuilder.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(StaticCode.BASE_URL)
.build();
httpService = retrofit.create(HttpService.class);
}

//在访问HttpUtil时创建单例
private static class SingletonHolder {
private static final HttpUtil INSTANCE = new HttpUtil();
}

//获取单例
public static HttpUtil getInstance() {
return SingletonHolder.INSTANCE;
}

/**
* 组装Observable
*
* @param observable
*/
public Observable packageObservable(Observable observable) {
return observable.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}

/**
* 获取网络数据不转化
*
* @param observable
*/
public Subscription sendHttp(Observable observable, HttpSubscriber listener) {
return packageObservable(observable)
.subscribe(listener);
}

/**
* 获取网络数据转化
*
* @param observable
*/
public <T> Subscription sendHttpWithMap(Observable observable, HttpSubscriber<T>
listener) {
return observable.compose(this.<T>applySchedulers())
.subscribe(listener);
}

/**
* Observable 转化
*
* @param <T>
* @return
*/
<T> Observable.Transformer<BaseHttpResult<T>, T> applySchedulers() {
return new Observable.Transformer<BaseHttpResult<T>, T>() {
@Override
public Observable<T> call(Observable<BaseHttpResult<T>> baseHttpResultObservable) {
return baseHttpResultObservable.map(new HttpFunc<T>())
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
};
}

/**
* 用来统一处理Http请求到的数据,并将数据解析成对应的Model返回
*
* @param <T> Subscriber真正需要的数据类型
*/
private class HttpFunc<T> implements Func1<BaseHttpResult<T>, T> {

@Override
public T call(BaseHttpResult<T> baseHttpResult) {
//获取数据失败则抛出异常 会进入到subscriber的onError中
if (!baseHttpResult.getStatus().equals(StaticCode.HTTP_RESPONSE_SUCCESS))
throw new RuntimeException(baseHttpResult.getStatus());

return baseHttpResult.getResults();
}
}
}


LoggerInterceptor

日志打印和请求头的增加

public class LoggerInterceptor implements Interceptor {

@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request().newBuilder().addHeader("version", "1.0")
.addHeader("clientSort", "android").addHeader("Charset", "UTF-8")
.build();

printRequestLog(originalRequest);
Response response = null;
try {
//发送网络请求
response = chain.proceed(originalRequest);
printResult(response);
} catch (SocketTimeoutException e) {
//此处不抛异常  连接超时会crash 没有找到其他好的方法
e.printStackTrace();

}
return response;
}

/**
* 打印请求日志
*
* @param originalRequest
* @return
* @throws IOException
*/
private void printRequestLog(Request originalRequest) throws IOException {
FormBody.Builder formBuilder = new FormBody.Builder();
String msg = originalRequest.url() + "\n";
RequestBody oidBody = originalRequest.body();
if (oidBody instanceof FormBody) {
FormBody formBody = (FormBody) oidBody;
for (int i = 0; i < formBody.size(); i++) {
String name = URLDecoder.decode(formBody.encodedName(i), "utf-8");
String value = URLDecoder.decode(formBody.encodedValue(i), "utf-8");
if (!TextUtils.isEmpty(value)) {
formBuilder.add(name, value);
msg += name + "  =  " + value + "\n";
}
}
}
Logger.i(msg);
}
/**
* 打印返回日志
*
* @param response
* @throws IOException
*/
private void printResult(Response response) throws IOException {
ResponseBody responseBody = response.body();
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = source.buffer();
Charset UTF8 = Charset.forName("UTF-8");
MediaType contentType = responseBody.contentType();
if (contentType != null) {
UTF8 = contentType.charset(UTF8);
}
String a = buffer.clone().readString(UTF8);
Logger.i(a);
}

}


BaseHttpResult

public class BaseHttpResult<T> {
public String status;

private T results;

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public T getResults() {
return results;
}

public void setResults(T results) {
this.results = results;
}
}


HttpSubscriber

Rxjava的回调

public abstract class HttpSubscriber<T> extends Subscriber<T> {

/**
* 请求标示
*/
private int tag;

public HttpSubscriber(int tag) {
this.tag = tag;
}

@Override
public void onCompleted() {
_complete();
}

@Override
public void onError(Throwable e) {
_complete();
onError(e.getMessage(), tag);
}

@Override
public void onNext(T t) {
onSuccess(t, tag);
}

public abstract void onSuccess(T t, int tag);

public abstract void onError(String msg, int tag);

public abstract void _complete();

}


Mvp的加入

MvpView

public interface MvpView {

void showLoadingDialog();

void dismissLoadingDialog();

}


IBasePresenter

public interface IBasePresenter<V extends MvpView> {

void subscribe();

void unsubscribe();

}


BasePresenter

对Presenter公共部分进行初始化

public abstract class BasePresenter

使用示例

MainActivity

Activity中实现View

public class MainActivity extends AppCompatActivity implements MainContract.IMainView {

private MainPre mainPre;
private android.widget.TextView getDistance;
private android.widget.TextView firstToSecondDistance;
private android.widget.TextView secondToThreeDistance;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.secondToThreeDistance = (TextView) findViewById(R.id.second_to_three_distance);
this.firstToSecondDistance = (TextView) findViewById(R.id.first_to_second_distance);
this.getDistance = (TextView) findViewById(R.id.get_distance);

mainPre = new MainPre(this);

getDistance.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mainPre.subscribe();
}
});
}

@Override
public void setFirstPointToSecondPointDistance(String distance) {
firstToSecondDistance.setText(distance);
}

@Override
public void setSecondPointToThreePointDistance(String distance) {
secondToThreeDistance.setText(distance);
}

@Override
public void showLoadingDialog() {
//这边可以做Dialog的显示
Logger.e("请求开始");
}

@Override
public void dismissLoadingDialog() {
//这边可以做Dialog的隐藏
Logger.e("请求结束");
}
}


MainContract

public class MainContract {
/**
* Created by huangweizhou on 16/8/10.
*/

public interface IMainView extends MvpView {
/**
* 第一个点和第二个点之间的距离
*
* @param distance
*/
void setFirstPointToSecondPointDistance(String distance);

/**
* 第二个点和第三个点之间的距离
*
* @param distance
*/

void setSecondPointToThreePointDistance(String distance);
}
}


MainPre

presenter中绑定对应的View和解析的类型

public class MainPre extends BasePresenter<MainContract.IMainView, List<String>> {
public MainPre(MainContract.IMainView view) {
super(view);
}

@Override
public void onSuccess(List<String> strings, int tag) {
baseView.setFirstPointToSecondPointDistance(strings.get(0));
baseView.setSecondPointToThreePointDistance(strings.get(1));
}

@Override
public void onError(String msg, int tag) {
Logger.e(msg);
}

@Override
public void subscribe() {
sendHttpWithMap(httpService.getDistance("118.77147503233,32.054128923368;\n" +
"     116.3521416286,39.965780080447;116.28215586757,39\n" +
"     .965780080447", "6cyEpstfAo1HSFGPSeshRXa459p3TyT0", "json"));
}
}


StaticCode

public class StaticCode {

/**
* Java地址
*/
public static final String BASE_URL = "http://api.map.baidu.com/telematics/v3/";

/**
* 获取网络数据成功
*/
public static final String HTTP_RESPONSE_SUCCESS = "Success";

}


源码地址

Mvp-RxJava-Retrofit
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android mvp