此处以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中的调用举例:
亲测有效。大家也可以尝试一下,封装一个数据自己的工具项目。 或许大家都已经有了属于自己的工具项目,就是我落后一步啦。哈哈