Haven't written a blog for a long time, Khan, usually like to read the blog, but do not like to write a blog, this is not possible, ashamed!
This year, I entered a new company, the boss said, first familiar with the code, and after the new UI comes out, refactoring. So these days, I've been familiar with the code and started building the basic framework of the project.
Rxjava, Retrofit, Okhttp, MVP, these keywords are more popular last year, any technology forum or technology blog, you can see, if you or he, also feel strange to these keywords, congratulations, you and I are the same, OUT, o()o.
Also, don't be anxious to learn new things. Step by step, if you don't understand it once, then look back and see the second time, the third time........................................... ... See more, familiar with, then it will be used, if there is ambition, you can study the source code, think about specific implementation principles.
Horizontal line~~~~
Rxjava knowledge, recommendation throw line blog, address: http://gank.io/post/560e15be2dca930e00da1083 What I want to say is that I have read this blog more than five times. It's easy to get confused at first, and then I can understand it when I look at it.
Retrofit knowledge, direct access to official documents, address: http://square.github.io/retrofit/
Okhttp knowledge, also directly look at official documents, address: http://square.github.io/okhttp/
MVP related, here recommend to look at Google's official demo, address: https://github.com/googlesamples/android-architecture
The above screenshots are official demo, MVP, MVVM and so on, which are worth referring to.
After reading the official recommendation, take a look at this blog, address: http://www.jianshu.com/p/ac51c9b88af3 Or take the off-the-shelf MVPArms on Github, address: https://github.com/JessYanCoding/MVPArms/wiki
Well, that's all I know.~~~~
Now let's look at the encapsulation of my own practice in my project. I try to write in detail. If there are problems or feel inappropriate, you can give me advice and help each other. That's the progress of learning.
First look at the project configuration file:
The part of the red circle is dependent, which is really convenient for AS. Think about how troublesome it would be if Eclipse was replaced. In fact, now AS has slowly become the mainstream, although I am looking at 14 years of project, it is EC structure, sweat.
After the dependencies are added, look at the package structure of the project:
1. All of them are related to net work requests, and the implementation of download and upload monitoring by encapsulating okhttp.
2. mvp is naturally View, Presenter, Mode.
3. util tool class.
4. View custom view.
5. common related generic things.
1. Encapsulation of network requests:
Network requests mainly look at ApiServer.java,RetrofitManager.java,StringObserver.java and BaseObserver.java.
1.ApiServer.java :
@GET("{url}")
Observable<String> get(@Path("url") String url,
@QueryMap Map<String, String> maps);
@FormUrlEncoded
@POST("{url}")
Observable<String> post(
@Path("url") String url,
@FieldMap Map<String, String> maps);
@POST("{url}")
Observable<String> post(
@Path("url") String url,
@Body RequestBody body);
@Multipart
@POST("{url}")
Observable<String> uploadFile(
@Path("url") String url,
@Part("description") RequestBody description,
@Part MultipartBody.Part file);
@Multipart
@POST("{url}")
Observable<String> uploadFile(
@Path("url") String url,
@PartMap Map<String, RequestBody> map);
@GET
Call<ResponseBody> downloadFile(@Url String fileUrl);
}
Retrofit is not different from official writing. The only difference is that URLs are not written to death. Define several commonly used get,post(key-value and json), upload files, download files, etc.
2.RetrofitManager.java:
mRetrofit = new Retrofit.Builder()
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
//.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.baseUrl(Constant.Base_Url)
.client(getOkhttpClient())
.build();
apiServer = mRetrofit.create(ApiServer.class);
}
private OkHttpClient getOkhttpClient() {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
NetLog.d("", message);
}
});
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
mOkhttp = new OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.addInterceptor(new PublicParamsInterceptor())
.connectTimeout(CONNEC_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
.retryOnConnectionFailure(false)
.connectionPool(new ConnectionPool())
.build();
return mOkhttp;
}
public static RetrofitManager getInstance() {
if (mInstance == null) {
synchronized (RetrofitManager.class) {
if (mInstance == null) {
mInstance = new RetrofitManager();
}
}
}
return mInstance;
}
public ApiServer getApiServer() {
return apiServer;
}
Single-profit design mode, because the whole project can share the same network request. The 14-year project I've seen these days, I feel like crying.~~~
mRetrofit = new Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) //.addConverterFactory(GsonConverterFactory.create()) .addConverterFactory(ScalarsConverterFactory.create()) .baseUrl(Constant.Base_Url) .client(getOkhttpClient()) .build();
See the addition of two converter s, in fact, this is the case, originally intended to be directly encapsulated into a BaseBean, but found that the data returned from the background is not uniform at all, once data, once orders, the only uniform is a resultCode field, "SUCCESS" represents success, or failure. The most frustrating, the most frustrating is that the interface documents are not available, and in the next few days I have to sort out the next interface documents myself, Lentinus edodes. That's why StringObserver.java and BaseObserver.java have emerged, and there may be a better solution. String is the only choice here for the caller to parse.
mOkhttp = new OkHttpClient.Builder() .addInterceptor(httpLoggingInterceptor) .addInterceptor(new PublicParamsInterceptor()) .connectTimeout(CONNEC_TIMEOUT, TimeUnit.SECONDS) .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS) .writeTimeout(READ_TIMEOUT, TimeUnit.SECONDS) .retryOnConnectionFailure(false) .connectionPool(new ConnectionPool()) .build();
addInterceptor(httpLoggingInterceptor) Interceptor for Adding Log Printing
addInterceptor(new PublicParamsInterceptor())Interceptors with Common Parameters
//Look at get, post (key-vaule, json), upload, Download
/**
* get Request interfaces are not uniform and can only be parsed one by one.
*
* @param url
* @param params
* @param observer
*/
public void get(String url, Map<String, String> params, Observer observer) {
getApiServer().get(url, params).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
}
/**
* post key-value request
*
* @param url
* @param params
* @param observer
*/
public void post(String url, Map<String, String> params, Observer observer) {
getApiServer().post(url, params).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
}
/**
* post json request
*
* @param url
* @param json
* @param observer
*/
public void json(String url, String json, Observer observer) {
RequestBody body = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), json);
getApiServer().post(url, body).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
}
/**
* Upload a single file
*
* @param url
* @param file
* @param progress
*/
public void uploadFile(String url, File file, @NonNull final ProgressListener progress, Observer observer) {
OkHttpClient.Builder newBuilder = mOkhttp.newBuilder();
List<Interceptor> networkInterceptors = newBuilder.networkInterceptors();
Interceptor it = new Interceptor() {
@Override
public Response intercept(Chain arg0) throws IOException {
Request request = arg0.request();
Request build = request.newBuilder().method(request.method(), new ProgressRequestBody(request.body(), progress)).build();
return arg0.proceed(build);
}
};
networkInterceptors.add(it);
ApiServer apiServer = mRetrofit.newBuilder().client(newBuilder.build()).build().create(ApiServer.class);
RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part part = MultipartBody.Part.createFormData("image", file.getName(), body);
RequestBody des = RequestBody.create(MediaType.parse("multipart/form-data"), "des");
apiServer.uploadFile(url, des, part).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
}
/**
* Download File
*
* @param url
* @param listener
*/
public void downLoadFile(String url, @NonNull final ProgressListener listener, @NonNull final retrofit2.Callback<ResponseBody> call) {
OkHttpClient.Builder newBuilder = mOkhttp.newBuilder();
List<Interceptor> networkInterceptors = newBuilder.networkInterceptors();
Interceptor it = new Interceptor() {
@Override
public Response intercept(Chain arg0) throws IOException {
Response proceed = arg0.proceed(arg0.request());
ProgressResponseBody body = new ProgressResponseBody(proceed.body(), listener);
return proceed.newBuilder().body(body).build();
}
};
networkInterceptors.add(it);
Retrofit build = mRetrofit.newBuilder().client(newBuilder.build()).build();
ApiServer apiServer = build.create(ApiServer.class);
apiServer.downloadFile(url).enqueue(call);
}
Users can call directly, which may not be well encapsulated. They are the first time to use these frameworks themselves. If you have problems, please ask.
3.StringObserver.java
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
try {
onSuccess(s);
}catch (Exception e){
e.printStackTrace();
ToastUtils.showMsg("Error occurred. Please try again.!");
onComplete();
}
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
onFaild(e);
onComplete();
}
protected abstract void onSuccess(String json) throws Exception;
protected abstract void onFaild(Throwable e);
}
4.BaseObserver.java
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(BaseBean baseBean) {
try{
if(baseBean != null && baseBean.isSuccess()){
onSuccess(baseBean);
}else{
baseBean.showErrorMsg();
}
}catch (Exception e){
e.printStackTrace();
ToastUtils.showMsg("Error occurred. Please try again.!");
onComplete();
}
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
onFail();
onComplete();
}
@Override
public void onComplete() {
}
public abstract void onSuccess(BaseBean baseBean);
public abstract void onFail();
}
The simple encapsulation of callbacks will be more convenient to use if the interface document is standardized.
Two, MVP:
If you look at Google's official demo, you will find a contract that links view to presenter, so you follow Google's practice here. Each interface corresponds to three classes: presenter, constract, task.
This should be the most basic mvp Demo. In the face of so many interfaces, I can't do it at first, but we should learn to accept new things, keep learning, and make progress.
Here's a strong recommendation: Is it really convenient or cumbersome to use traditional MVP in projects?
address http://www.jianshu.com/p/ac51c9b88af3
Well, welcome to correct your questions.
Github: https://github.com/andmizi/Rxjava-Retrofit-Okhttp-Mvp
Jane book: http://www.jianshu.com/p/a6482b199e81