此处以retrofit 为例:方便创建新项目的时候,不用拷贝太多东西。
首先第一步:
可以创建一个工具类的项目,然后创建一个library。步骤如上所示。这样的话方便测试,自己的工具类封装是否成功,也方便在创建新项目的时候,可以直接在新项目中创建一个与我们工具类中的library 相同名字的 library,例如我的项目中,为了方便以后library的拷贝方便,我会都创建为 mylibrary.
第二步:封装自己的网络请求框架。此处以我的项目中的retrofit 为例子。
1.引入依赖。
/** 网络请求的封装 */ implementation 'com.squareup.retrofit2:retrofit:2.1.0'//retrofit implementation 'com.google.code.gson:gson:2.6.2'//Gson 库 //下面两个是RxJava 和RxAndroid 添加这两个依赖 可以直接使用rxbus implementation 'io.reactivex:rxjava:1.1.0' implementation 'io.reactivex:rxandroid:1.1.0' implementation 'com.squareup.retrofit2:converter-gson:2.1.0' //转换器,请求结果转换成Model implementation 'com.squareup.retrofit2:adapter-rxjava:2.1.0' //配合Rxjava 使用 implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1' implementation 'com.squareup.okhttp3:okhttp:3.4.1'
2.封装相关的类。
其中一个关键的点 就是,将我们最终调用 的httpmanager 这个类 ,写到我们的APP包下,方便我们跟随不同项目,不同的需求进行修改。灵活使用。
其中,httpmanager中调用的工具类,需要在我们的library中封装完成,因为这些类,不会因为业务的变化而变化,或者说变化比较小。
3.retrofit的优点是比较优雅,此处举例演示,如何使用library中的工具类,创建APP包下的请求manager。
package com.example.administrator.mytestretrofit.http;
import android.util.Log;
import com.example.mylibrary.app.Constants;
import com.example.administrator.mytestretrofit.http.remote.RemoteService;
import com.example.mylibrary.http.engine.ExceptionEngine;
import com.example.mylibrary.http.engine.RetryWhenNetworkException;
import com.example.mylibrary.http.gson.IJson;
import com.example.mylibrary.http.interceptor.MoreBaseUrlInterceptor;
import com.example.mylibrary.http.subscriber.ProgressSubscriber;
import com.example.mylibrary.utils.log.LogUtils;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
/**
* http交互处理类
*/
public class HttpManager {
public static final String TAG = "HttpManager-------";
/*超时设置*/
private static final int DEFAULT_TIMEOUT = 6;
private RemoteService httpService;
private volatile static HttpManager INSTANCE;
//构造方法私有
private HttpManager() {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
LogUtils.d(TAG,message);
}
});
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder builder = new OkHttpClient().newBuilder()
.connectTimeout(5, TimeUnit.SECONDS) //设置超时时间 10s
.readTimeout(5, TimeUnit.SECONDS) //设置读取超时时间
.writeTimeout(5, TimeUnit.SECONDS) //设置写入超时时间
.addInterceptor(httpLoggingInterceptor)//添加一个拦截器
.addInterceptor(new MoreBaseUrlInterceptor());
OkHttpClient okClient = builder.build();
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(IJson.gson)) // 使用Gson作为数据转换器
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 使用RxJava作为回调适配器
.client(okClient)
.baseUrl(Constants.Base.BASE_URL_RELEASE)//获取 最终的base url
/*.baseUrl(App.getInstance().getRealUrl())//此处选择 api 的真实网址*/
.build();
httpService = retrofit.create(RemoteService.class);
}
//获取单例
public static HttpManager getInstance() {
if (INSTANCE == null) {
synchronized (HttpManager.class) {
if (INSTANCE == null) {
INSTANCE = new HttpManager();
}
}
}
return INSTANCE;
}
/**
* 处理http请求
*
* @param basePar 封装的请求数据
*/
public void doHttpDeal(BaseEntity basePar) {
//if (basePar.isShowProgress())
ProgressSubscriber subscriber = new ProgressSubscriber(basePar.getListener()
, basePar.getContext()
, basePar.isShowProgress()
, basePar.isCancel()
, basePar.isShowError()
, basePar.getMsg());
basePar.getObservable(httpService)
/*失败后的retry配置*/
.retryWhen(new RetryWhenNetworkException())
/*生命周期管理*/
.compose(basePar.getTransformer())
// .map(new_icon ServerResponseFunc<String>())//拦截服务器返回的错误
.onErrorResumeNext(new HttpResponseFunc<String>()) //HttpResultFunc()为拦截onError事件的拦截器
/*http请求线程*/
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
/*回调线程*/
.observeOn(AndroidSchedulers.mainThread())
/*结果判断*/
// .map(basePar)
.subscribe(subscriber);
}
private class HttpResponseFunc<T> implements Func1<Throwable, Observable<T>> {
@Override
public Observable<T> call(Throwable throwable) {
Log.e(TAG,"----这是啥异常?--");
throwable.printStackTrace();
return Observable.error(ExceptionEngine.handleException(throwable)); //ExceptionEngine为处理异常的驱动器
}
}
}
大家可以看一下 ,这个是我封装的请求调用类,关注点可以放到 import上面。
其实这个类里面,大部分也是 一些不用变化的内容,只是关键在 RemoteService 这个类里面。
public interface RemoteService {
/**
* 登录请求token
*/
@Headers("urlname:common_base_url_header")
@POST("action/LoginAction/mobileNumberLogin")
Observable<Response<BaseHttpEntity<LoginForAccessTokenEntity>>> loginForToken(
@Body FormBody body
);
/**
* 根据token请求jssionid
*/
@Headers("urlname:common_base_url_header")
@POST("action/LoginAction/csLogin")
Observable<Response<BaseHttpEntity<UserInfoEntity>>> loginFromTokenToJssionId(
@Body FormBody body
);
/**
* 发送验证码接口
* mobileNumber:11位手机号
* type:验证码类型 0注册 1重置密码 2修改手机号 3修改支付密码
*/
@Headers("urlname:common_base_url_header")
@POST("action/LoginAction/sendSMSCode")
Observable<Response<BaseHttpEntity<SendSMSCodeEntity>>> getSendSMSCode(
@Body FormBody body
);
}
这个类是需要根据我们的业务进行变动的,为了方便我们的一个项目中,会创建多个module,所以,将httpmanager 分别放在module中是比较方便的。
3.接下来就行请求的接口api ,与返回的数据entity。
举例演示:
这些网络请求的接口api,与返回的数据类 根据自己的后台返回的数据,灵活的创建,这里不多做赘述。
4.在module中的调用举例:
亲测有效。大家也可以尝试一下,封装一个数据自己的工具项目。 或许大家都已经有了属于自己的工具项目,就是我落后一步啦。哈哈