目录结构
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>> 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 Subscription sendHttpWithMap(Observable observable, HttpSubscriber
listener) {
return observable.compose(this.applySchedulers())
.subscribe(listener);
}
/**
* Observable 转化
*
* @param
* @return
*/
Observable.Transformer, T> applySchedulers() {
return new Observable.Transformer, T>() {
@Override
public Observable call(Observable> baseHttpResultObservable) {
return baseHttpResultObservable.map(new HttpFunc())
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
};
}
/**
* 用来统一处理Http请求到的数据,并将数据解析成对应的Model返回
*
* @param Subscriber真正需要的数据类型
*/
private class HttpFunc implements Func1, T> {
@Override
public T call(BaseHttpResult 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 {
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;
}
}
Rxjava的回调
public abstract class HttpSubscriber extends Subscriber {
/**
* 请求标示
*/
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 {
void subscribe();
void unsubscribe();
}
BasePresenter
对Presenter公共部分进行初始化
public abstract class BasePresenter implements
IBasePresenter {
protected HttpUtil httpUtil = null;
protected HttpService httpService = null;
protected V baseView;
/**
* 统一取消网络请求
*/
private CompositeSubscription compositeSubscription;
public BasePresenter(V view) {
this.baseView = view;
httpUtil = HttpUtil.getInstance();
httpService = httpUtil.getHttpService();
compositeSubscription = new CompositeSubscription();
}
protected HttpSubscriber getProgressSubscriber(int tag) {
baseView.showLoadingDialog();
return new HttpSubscriber(tag) {
@Override
public void onSuccess(T t, int tag) {
BasePresenter.this.onSuccess(t, tag);
}
@Override
public void onError(String msg, int tag) {
BasePresenter.this.onError(msg, tag);
}
@Override
public void _complete() {
baseView.dismissLoadingDialog();
}
};
}
/**
* 发送网络请求对结果不进行转化
*
* @param observable
* @param tag
*/
protected void sendHttp(Observable observable, int tag) {
compositeSubscription.add(httpUtil.sendHttp(observable, getProgressSubscriber(tag)));
}
protected void sendHttp(Observable observable) {
sendHttp(observable, 0);
}
/**
* 发送网络请求对结果进行转化
*
* @param observable
* @param tag
*/
protected void sendHttpWithMap(Observable observable, int tag) {
compositeSubscription.add(httpUtil.sendHttpWithMap(observable, getProgressSubscriber
(tag)));
}
protected void sendHttpWithMap(Observable observable) {
sendHttpWithMap(observable, 0);
}
public abstract void onSuccess(T t, int tag);
public abstract void onError(String msg, int tag);
/**
* 取消网络请求
*/
@Override
public void unsubscribe() {
if (compositeSubscription != null && compositeSubscription.hasSubscriptions())
compositeSubscription.unsubscribe();
}
/**
* 手动添加subscription
*
* @param subscription
*/
public void addSubscription(Subscription subscription) {
if (compositeSubscription == null) {
compositeSubscription = new CompositeSubscription();
}
compositeSubscription.add(subscription);
}
}
使用示例
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> {
public MainPre(MainContract.IMainView view) {
super(view);
}
@Override
public void onSuccess(List 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";
}