github地址:https://github.com/Dragonxwl/MyBasePro
实现网络请求的几个步骤:
1.目录结构
image.png
2.build配置(app路径下)
//OkHttp
api 'com.squareup.okhttp3:okhttp:3.11.0'
api 'com.squareup.okhttp3:logging-interceptor:3.11.0'
api 'com.squareup.retrofit2:retrofit:2.4.0'
api 'com.squareup.retrofit2:converter-gson:2.4.0'
api('com.squareup.retrofit2:converter-simplexml:2.4.0') {
exclude module: 'stax-api'
exclude module: 'stax'
exclude module: 'xpp3'
}
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
//RxJava
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
//RxLifecycle
implementation 'com.trello.rxlifecycle2:rxlifecycle:2.2.2'
implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.2'
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.2'
3.主要类 okhttp
RetrofitClient 类
public class RetrofitClient {
private Retrofit mRetrofit;
private OkHttpClient mOkHttpClient;
private HashMap mServiceCache = new HashMap<>();
private static RetrofitClient mInstance;
private static final String ENTER = "\r\n";
public RetrofitClient() {
}
public synchronized static RetrofitClient getInstance() {
if (mInstance == null) {
synchronized (RetrofitClient.class) {
mInstance = new RetrofitClient();
}
}
return mInstance;
}
public void init(String baseUrl, Interceptor customInterceptor) {
if (mRetrofit == null) {
if (mOkHttpClient == null) {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(@NonNull String message) {
LogUtil.LogI("HTTP:", message);
}
});
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
mOkHttpClient = new OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.addInterceptor(customInterceptor)
.build();
}
mRetrofit = new Retrofit.Builder()
.client(mOkHttpClient)
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
} else {
mRetrofit = new Retrofit.Builder()
.client(mOkHttpClient)
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
}
public static RequestBody jsonToRequestBody(JSONObject json) {
return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json.toString());
}
public static RequestBody stringToRequestBody(String string) {
return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), string);
}
public T obtainService(Class apiService) {
T retrofitService = (T) mServiceCache.get(apiService.getCanonicalName());
if (retrofitService == null) {
retrofitService = mRetrofit.create(apiService);
mServiceCache.put(apiService.getCanonicalName(), retrofitService);
}
return retrofitService;
}
}
RxSchedulers
public class RxSchedulers {
public static FlowableTransformer compose() {
return new FlowableTransformer() {
@Override
public Flowable apply(Flowable observable) {
return observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
};
}
}
BaseObserver
public abstract class BaseObserver extends DisposableSubscriber {
@Override
public void onNext(T value) {
if (value.getErrorCode() == ErrorCode.SUCCESS) {
onSuccess(value);
} else {
if (value.getErrorCode() == ErrorCode.ERROR_ACCESS_TOKEN_ERROR) {
} else {
onFailed(value.getErrorCode(), value.getErrorMessage());
}
}
}
@Override
public void onError(Throwable e) {
if (e instanceof HttpException) {
HttpException httpException = (HttpException) e;
onError(httpException.code(), httpException.message());
ToastUtil.toast(Application.getContext(), "网络开小差了(" + httpException.code() + ")");
LogUtil.e_uninit("BaseObserver", "onError:" + e.getMessage());
} else {
onError(-1, e.getMessage());
ToastUtil.toast(Application.getContext(), "网络开小差了(" + -1 + ")");
LogUtil.e_uninit("BaseObserver", "onError:" + e.getMessage());
}
}
@Override
public void onComplete() {
}
protected abstract void onSuccess(T t);
protected abstract void onFailed(int code, String msg);
protected abstract void onError(int code, String msg);
}
ApiService
定义接口
public interface ApiService {
/**
* 接口用途:学生登录-根据手机号密码
*/
@POST("/ac-common/oauth/sms/stu")
Flowable loginWithSMS(@Body RequestBody info);
/**
* 接口用途:获取预配置信息
*/
@GET("/ac-client/profile/{appId}/{buildId}")
Flowable updateVersion(@Path("appId") int appId, @Path("buildId") int buildId
, @QueryMap Map params);
/**
* 上传用户应用列表
*/
@POST("/ac-client/user-apps/save")
Flowable GetUserApps(@Body RequestBody body);
}
HeaderInterceptor
请求头拦截器 主要目的是在请求前添加请求头 eg:token
public class HeaderInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request.Builder builder = originalRequest.newBuilder();
builder.addHeader("Content-Type", "application/json");
builder.addHeader("request-id", StringUtils.getUUID());
//设置token
if (!noTokenList.contains(originalRequest.url().toString().replace(Application.GetHost(),""))) {
String token = ACConfig.getInstance().getAccessToken();
if (!TextUtils.isEmpty(token)) {
builder.addHeader("access-token", token);
LogUtil.LogI("HTTP-access-token:", token);
}
}
Request newRequest = builder.build();
return chain.proceed(newRequest);
}
}
ErrorCode
自定义服务器错误
public class ErrorCode {
public static final int SUCCESS = 0;
public static final int ERROR_ACCESS_TOKEN_ERROR = 102;
}
4.BaseActivity
Activity基类 继承 RxAppCompatActivity (主要目的获取Activity生命周期)
public class BaseActivity extends RxAppCompatActivity
5.MainActivity
启动页
执行RetrofitClient初始化
Application.GetHost() 接口地址 eg:https://www.xxxxx.com
HeaderInterceptor 请求头拦截器 主要用途设置请求请头 (拦截器功能后面会详细说
https://www.jianshu.com/p/3a0027e08ada
)
// okhttp 初始化
RetrofitClient.getInstance().init(Application.GetHost(), new HeaderInterceptor());
6.okhttpDemoActivity
Demo页面 执行网络请求并显示结果
public class okhttpDemoActivity extends BaseActivity
public void Get_getProfileByAppId(final Context context) {
try {
int buildId = Application.getAppVersionCode(context);
Map params = new HashMap<>();
params.put("channelName", StringUtils.getChannelName(this));
RetrofitClient.getInstance()
.obtainService(ApiService.class)
.updateVersion(8, buildId, params)
.compose(RxSchedulers.compose())
// .compose(this.bindToLifecycle()) //不绑定生命周期
.subscribe(new BaseObserver() {
@Override
protected void onSuccess(ProfileResultBean bean) {
TextView_value.setText(bean.data.dbCode + "");
}
@Override
protected void onFailed(int code, String msg) {
}
@Override
protected void onError(int code, String msg) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
7.混淆
proguard-rules.pro 文件
# gson entity
-keep class com.xwl.mybasepro.bean.** {*;}
#okhttp
-dontwarn okhttp3.**
-keep class okhttp3.**{*;}
#okio
-dontwarn okio.**
-keep class okio.**{*;}
#retrofit2 混淆
-dontwarn javax.annotation.**
-dontwarn javax.inject.**
# OkHttp3
-dontwarn okhttp3.logging.**
-keep class okhttp3.internal.**{*;}
-dontwarn okio.**
# Retrofit
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
# RxJava RxAndroid
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
long producerIndex;
long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
rx.internal.util.atomic.LinkedQueueNode consumerNode;
}
8.AndroidManifest 配置文件申请权限