public abstract class BaseActivity extends AppCompatActivity {

/**

  • 绑定生命周期

*/

protected LifecycleProvider<Lifecycle.Event> rxLifecycle = AndroidLifecycle.createLifecycleProvider(this);

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

}

@Override

protected void onDestroy() {

super.onDestroy();

}

}

  • 调用

package cc.network.rxjava;

import android.content.Intent;

import android.nfc.Tag;

import android.os.Bundle;

import android.util.ArrayMap;

import android.util.Log;

import android.view.View;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.ListView;

import android.widget.Toast;

import androidx.lifecycle.Lifecycle;

import com.alibaba.fastjson.JSON;

import com.yumakeji.rxjava.network.RetrofitClient;

import com.yumakeji.rxjava.network.bean.Result;

import com.yumakeji.rxjava.network.callback.ConsumerCallback;

import com.yumakeji.rxjava.network.callback.ObserverCallback;

import com.yumakeji.rxjava.network.callback.ThrowableCallback;

import com.yumakeji.rxjava.network.error.HttpThrowable;

import com.yumakeji.rxjava.network.handler.RetryWithDelay;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.CopyOnWriteArrayList;

import java.util.concurrent.TimeUnit;

import cc.network.rxjava.rxjava.ServiceApi;

import cc.network.rxjava.textbean.LoginBean;

import cc.network.rxjava.textbean.Top250Bean;

import cc.network.rxjava.viewmodel.RxjavaViewModel;

import cn.yumakeji.jetpackroomstudy.R;

import cn.yumakeji.lib_common.global.AppGlobals;

import cn.yumakeji.lib_common.utils.AppUtils;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;

import io.reactivex.rxjava3.annotations.NonNull;

import io.reactivex.rxjava3.core.Observable;

import io.reactivex.rxjava3.core.ObservableEmitter;

import io.reactivex.rxjava3.core.ObservableOnSubscribe;

import io.reactivex.rxjava3.core.ObservableSource;

import io.reactivex.rxjava3.core.Observer;

import io.reactivex.rxjava3.disposables.Disposable;

import io.reactivex.rxjava3.functions.Action;

import io.reactivex.rxjava3.functions.BiFunction;

import io.reactivex.rxjava3.functions.Consumer;

import io.reactivex.rxjava3.functions.Function;

import io.reactivex.rxjava3.schedulers.Schedulers;

/**

  • 防止多次点击

  • https://www.jianshu.com/p/ea45670a364f,

  • Retrofit

  • https://blog.csdn.net/huangxiaoguo1/article/details/65627293

  • Rxjava

  • https://www.jianshu.com/p/092452f287db

  • 不继承RxAppCompatActivity的情况下使用RxLifeCycle

  • https://blog.csdn.net/kevinscsdn/article/details/78980010

*/

public class RxjavaActivity extends BaseActivity {

private ListView mListView;

private List strings = new CopyOnWriteArrayList<>();

private final String TAG = “Rxjava”;

private RxjavaViewModel viewModel;

@Override

public void onDetachedFromWindow() {

super.onDetachedFromWindow();

getLifecycle().removeObserver(viewModel);

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_rxjava);

mListView = findViewById(R.id.list_item);

strings.add("Get方法 @Query ");

strings.add("Post方法 @Body ");

strings.add(“使用Rxjava切换线程”);

strings.add(“Rxjava(一)emitter”);

strings.add(“Rxjava(二)变换操作符Map”);

strings.add(“Rxjava(三)FlatMap”);

strings.add(“Rxjava(四)concatMap”);

strings.add(“Rxjava(五)接口顺序调用”);

strings.add(“Rxjava(六)接口顺序调用(内部发生错误)”);

strings.add(“Rxjava(七)Zip来打包”);

}

/**

  • 去体验Retrofit

  • @param view

*/

public void onRetrofitClick(View view) {

startActivity(new Intent(this, RetrofitActivity.class));

}

@Override

public void onAttachedToWindow() {

super.onAttachedToWindow();

viewModel = new RxjavaViewModel(this);

getLifecycle().addObserver(viewModel);

mListView.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, strings));

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

@Override

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

switch (position) {

case 0://Get方法 @Query

RetrofitClient.getInstance()

.create(ServiceApi.class)// 创建服务

.getSearchContent("", 5)//调用接口

.subscribeOn(Schedulers.io())// 指定被观察者的操作在io线程中完成

.doOnSubscribe(disposable -> viewModel.showProgressDialog(“正在请求中”))

.observeOn(AndroidSchedulers.mainThread())//指定观察者接收到数据,然后在Main线程中完成

.retryWhen(new RetryWithDelay(1, 1))//遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔

.doAfterTerminate(() -> viewModel.hintProgressDialog())

.compose(rxLifecycle.bindUntilEvent(Lifecycle.Event.ON_DESTROY))//生命周期

.subscribe(new ConsumerCallback() {

@Override

public void onSucceed(Top250Bean result) {

// 成功获取数据

Toast.makeText(AppGlobals.getApplication().getApplicationContext(),

“成功了” + result, Toast.LENGTH_LONG).show();

}

@Override

public void onError(int code, String msg) {

// 获取数据失败

Toast.makeText(AppGlobals.getApplication().getApplicationContext(),

msg, Toast.LENGTH_LONG).show();

}

}, new ThrowableCallback() {

@Override

public void onError(HttpThrowable httpThrowable) {

// 获取数据失败

Log.i(TAG, httpThrowable.message);

}

});

break;

case 1://POST方法 @Body

ArrayMap<String, Object> map = new ArrayMap<>();

map.put(“jsCode”, “033sHaaK03pRwa2Bic9K0EmcaK0sHaaq”);

RetrofitClient.getInstance()

.create(ServiceApi.class)

.postCode2Session(map)

.subscribeOn(Schedulers.io())

.doOnSubscribe(disposable -> viewModel.showProgressDialog(“正在请求中”))

.observeOn(AndroidSchedulers.mainThread())

.compose(rxLifecycle.bindUntilEvent(Lifecycle.Event.ON_DESTROY))

.retryWhen(new RetryWithDelay(1, 1))//遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔

.doAfterTerminate(() -> viewModel.hintProgressDialog())

.subscribe(new ObserverCallback() {

@Override

public void onSucceed(LoginBean result) {

// 成功获取数据

Toast.makeText(AppGlobals.getApplication().getApplicationContext(),

“成功了” + result, Toast.LENGTH_LONG).show();

}

@Override

public void onFail(int code, String msg) {

// 获取数据失败

Toast.makeText(AppGlobals.getApplication().getApplicationContext(),

msg, Toast.LENGTH_LONG).show();

}

@Override

public void onComplete() {

super.onComplete();

}

});

break;

case 2://使用Rxjava切换线程

Observable.empty().observeOn(Schedulers.io())

.doOnComplete(new Action() {

@Override

public void run() throws Throwable {

Log.i(TAG, “我是子线程:” + AppUtils.isMainThread());

Observable.timer(3, TimeUnit.SECONDS)

.observeOn(AndroidSchedulers.mainThread())

.doOnComplete(() -> msgManagement(10))

.subscribe();

Observable.empty().observeOn(AndroidSchedulers.mainThread())

.doOnComplete(() -> msgManagement(20)

).subscribe();

}

}).subscribe();

break;

case 3:

//Rxjava(一)emitter 发射器

/**

  • 借鉴:给初学者的RxJava2.0教程(一)

  • https://www.jianshu.com/p/464fa025229e

  • 规则:

  • 1、上游可以发送无限个onNext, 下游也可以接收无限个onNext.

  • 2、当上游发送了一个onComplete后, 上游onComplete之后的事件将会继续发送, 而下游收到onComplete事件之后将不再继续接收事件.

  • 3、当上游发送了一个onError后, 上游onError之后的事件将继续发送, 而下游收到onError事件之后将不再继续接收事件.

  • 4、上游可以不发送onComplete或onError.

  • 5、最为关键的是onComplete和onError必须唯一并且互斥, 即不能发多个onComplete, 也不能发多个onError,

  • 也不能先发一个onComplete, 然后再发一个onError, 反之亦然

  • 注: 关于onComplete和onError唯一并且互斥这一点, 是需要自行在代码中进行控制, 如果你的代码逻辑中违背了这个规则,

  • **并不一定会导致程序崩溃. ** 比如发送多个onComplete是可以正常运行的, 依然是收到第一个onComplete就不再接收了,

  • 但若是发送多个onError, 则收到第二个onError事件会导致程序会崩溃.

*/

Observable.create(new ObservableOnSubscribe() {

@Override

public void subscribe(@NonNull ObservableEmitter emitter) throws Throwable {

Log.e(TAG, “是否是主线程=>” + AppUtils.isMainThread());

emitter.onNext(“huangxiaoguo1”);

emitter.onNext(“huangxiaoguo2”);

emitter.onNext(“huangxiaoguo3”);

emitter.onComplete();

}

})

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Observer() {

private Disposable mDisposable;

/**

  • 不带任何参数的subscribe() 表示下游不关心任何事件,你上游尽管发你的数据去吧, 老子可不管你发什么.

  • 带有一个Consumer参数的方法表示下游只关心onNext事件, 其他的事件我假装没看见,

  • @param d

*/

@Override

public void onSubscribe(@NonNull Disposable d) {

Log.d(TAG, “subscribe”);

mDisposable = d;

}

@Override

public void onNext(@NonNull String s) {

/**

  • 当调用它的dispose()方法时, 它就会将两根管道切断, 从而导致下游收不到事件.

  • 调用dispose()并不会导致上游不再继续发送事件, 上游会继续发送剩余的事件

*/

Log.e(TAG, “onNext 是否是主线程 ==>” + AppUtils.isMainThread());

Log.d(TAG, “onNext==>” + s);

if (s.equals(“huangxiaoguo2”)) {

mDisposable.dispose();

}

}

@Override

public void onError(@NonNull Throwable e) {

Log.d(TAG, “onError”);

}

@Override

public void onComplete() {

Log.d(TAG, "onComplete ");

}

});

break;

case 4:

//Rxjava(二)变换操作符Map

Observable.create(new ObservableOnSubscribe() {

@Override

public void subscribe(@NonNull ObservableEmitter emitter) throws Throwable {

Log.e(TAG, “subscribe 是否是主线程 ==>” + AppUtils.isMainThread());

emitter.onNext(1);

emitter.onNext(2);

emitter.onNext(3);

}

})

.subscribeOn(Schedulers.io())

.map(new Function<Integer, String>() {

@Override

public String apply(Integer integer) throws Throwable {

Log.e(TAG, “map 是否是主线程 ==>” + AppUtils.isMainThread());

return “我是在map中处理过了的===>” + String.valueOf(integer);

}

})

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Consumer() {

@Override

public void accept(String s) throws Throwable {

Log.e(TAG, “accept 是否是主线程 ==>” + AppUtils.isMainThread());

Log.i(TAG, “accept===>” + s);

}

});

break;

case 5:

//flatMap 并不保证事件的顺序

Observable.create(new ObservableOnSubscribe() {

@Override

public void subscribe(@NonNull ObservableEmitter emitter) throws Throwable {

emitter.onNext(1);

emitter.onNext(2);

emitter.onNext(3);

}

}).flatMap(new Function<Integer, ObservableSource>() {

@Override

public ObservableSource apply(Integer integer) throws Throwable {

ArrayList strings = new ArrayList<>();

for (int i = 0; i < 3; i++) {

strings.add("I am value " + integer);

}

return Observable.fromIterable(strings).delay(2, TimeUnit.SECONDS);

}

}).subscribe(new Consumer() {

@Override

public void accept(String s) throws Throwable {

Log.d(TAG, s);

}

});

break;

case 6:

//concatMap 保证顺序

Observable.create(new ObservableOnSubscribe() {

@Override

public void subscribe(@NonNull ObservableEmitter emitter) throws Throwable {

emitter.onNext(1);

emitter.onNext(2);

emitter.onNext(3);

}

}).concatMap(new Function<Integer, ObservableSource>() {

@Override

public ObservableSource apply(Integer integer) throws Throwable {

ArrayList strings = new ArrayList<>();

for (int i = 0; i < 3; i++) {

strings.add("I am value " + integer);

}

return Observable.fromIterable(strings).delay(2, TimeUnit.SECONDS);

}

}).subscribe(new Consumer() {

@Override

public void accept(String s) throws Throwable {

Log.d(TAG, s);

}

});

break;

case 7:

//Rxjava(五)接口顺序调用

RetrofitClient.getInstance()

.create(ServiceApi.class)// 创建服务

.getSearchContent("", 5)//调用接口

.subscribeOn(Schedulers.io())// 指定被观察者的操作在io线程中完成

.doOnSubscribe(disposable -> viewModel.showProgressDialog(“正在请求中”))

.observeOn(AndroidSchedulers.mainThread())//指定观察者接收到数据,然后在Main线程中完成

.doOnNext(new ConsumerCallback() {

@Override

public void onSucceed(Top250Bean result) {

Log.e(TAG, result.toString());

}

@Override

public void onError(int code, String msg) {

}

})

.observeOn(Schedulers.io())

.flatMap(new Function<Result, Observable<Result>>() {

@Override

public Observable<Result> apply(Result result) throws Throwable {

Log.e(TAG, result.getMessage());

ArrayMap<String, Object> map = new ArrayMap<>();

map.put(“jsCode”, “033sHaaK03pRwa2Bic9K0EmcaK0sHaaq”);

return RetrofitClient.getInstance().create(ServiceApi.class).postCode2Session(map);

}

})

.retryWhen(new RetryWithDelay(1, 1))//遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔

.compose(rxLifecycle.bindUntilEvent(Lifecycle.Event.ON_DESTROY))//生命周期

.observeOn(AndroidSchedulers.mainThread())

.doAfterTerminate(() -> viewModel.hintProgressDialog())

.subscribe(new ConsumerCallback() {

@Override

public void onSucceed(LoginBean result) {

Log.e(TAG, result.toString());

}

@Override

public void onError(int code, String msg) {

Log.e(TAG, msg);

}

}, new ThrowableCallback() {

@Override

public void onError(HttpThrowable httpThrowable) {

super.onError(httpThrowable);

}

});

break;

case 8:

//Rxjava(六)接口顺序调用(内部发生错误)

ArrayMap<String, Object> map1 = new ArrayMap<>();

map1.put(“jsCode”, “033sHaaK03pRwa2Bic9K0EmcaK0sHaaq”);

RetrofitClient.getInstance()

.create(ServiceApi.class)// 创建服务

.postCode2Session(map1)//调用接口

.subscribeOn(Schedulers.io())// 指定被观察者的操作在io线程中完成

.doOnSubscribe(disposable -> viewModel.showProgressDialog(“正在请求中”))

.observeOn(AndroidSchedulers.mainThread())//指定观察者接收到数据,然后在Main线程中完成

.doOnNext(new ConsumerCallback() {

@Override

public void onSucceed(LoginBean result) {

Log.e(TAG, result.toString());

}

@Override

public void onError(int code, String msg) {

Log.e(TAG, msg);

}

})

.observeOn(Schedulers.io())

.flatMap(new Function<Result, Observable<Result>>() {

@Override

public Observable<Result> apply(Result result) throws Throwable {

if (!result.isOk()) {

return null;

}

return RetrofitClient.getInstance().create(ServiceApi.class).getSearchContent("", 5);

}

})

.retryWhen(new RetryWithDelay(1, 1))//遇到错误时重试,第一个参数为重试的间隔,第二个参数为重试几次

.compose(rxLifecycle.bindUntilEvent(Lifecycle.Event.ON_DESTROY))//生命周期

.observeOn(AndroidSchedulers.mainThread())

.doAfterTerminate(() -> viewModel.hintProgressDialog())

.subscribe(new ConsumerCallback() {

@Override

public void onSucceed(Top250Bean result) {

Log.e(TAG, result.toString());

}

@Override

public void onError(int code, String msg) {

Log.e(TAG, msg);

}

}, new ThrowableCallback() {

@Override

public void onError(HttpThrowable httpThrowable) {

super.onError(httpThrowable);

}

});

break;

case 9:

//Rxjava(七)Zip来打包请求

Observable.zip(RetrofitClient.getInstance()

.create(ServiceApi.class)

.getSearchContent("", 1)

.subscribeOn(Schedulers.io()),

RetrofitClient.getInstance()

.create(ServiceApi.class)

.getSearchContent2("", 1)

.subscribeOn(Schedulers.io()),

new BiFunction<Result, Result, Top250Bean>() {

@Override

public Top250Bean apply(Result result, Result result2) throws Throwable {

Top250Bean data1 = JSON.parseObject(JSON.toJSONString(result.data), Top250Bean.class);

Top250Bean data2 = JSON.parseObject(JSON.toJSONString(result.data), Top250Bean.class);

data1.getRecords().addAll(data2.getRecords());

return data1;

}

}).observeOn(AndroidSchedulers.mainThread())

.subscribe(new Consumer() {

@Override

public void accept(Top250Bean result) throws Throwable {

Log.e(TAG, result.toString());

Log.e(TAG, result.getRecords().size()+"—");

}

});

break;

}

}

});

}

/**

  • 代替Handler

  • @param what

*/

private void msgManagement(int what) {

if (what == 10) {

Log.i(TAG, “我是代替Handler 有延时” + AppUtils.isMainThread());

} else {

Log.i(TAG, “我是代替Handler 没有延时” + AppUtils.isMainThread());

}

}

}

  • MVVM中管理Rxjava的生命周期

可直接使用开源框架:rxjava-RxLife

//使用rxlife对viewModel生命周期执行支持(rxlifecycle在google jetpack的videModel中不太好用,针对的是MVP)

api ‘com.ljx.rxlife3:rxlife-rxjava:3.0.0’

注意: 一定要在Activity/Fragment通过以下方式获取ViewModel对象,否则RxLife接收不到生命周期的回调

viewModel = new ViewModelProvider(this).get(RxjavaViewModel.class);

Observable.interval(2, TimeUnit.SECONDS)

.observeOn(AndroidSchedulers.mainThread())

.to(RxLife.to(this))

.subscribe(new Consumer() {

@Override

public void accept(Long aLong) throws Throwable {

Log.e(“huangxiaoguo”, “接口轮询”);

}

});


其他设计到的类

  • error

package com.yumakeji.rxjava.network.error;

public class HttpThrowable extends Exception {

public int errorType;

public String message;

public Throwable throwable;

/**

  • 未知错误

*/

public static final int UNKNOWN = 1000;

/**

  • 解析错误

*/

public static final int PARSE_ERROR = 1001;

/**

  • 连接错误

*/

public static final int CONNECT_ERROR = 1002;

/**

  • DNS解析失败(无网络)

*/

public static final int NO_NET_ERROR = 1003;

/**

  • 连接超时错误

*/

public static final int TIME_OUT_ERROR = 1004;

/**

  • 网络(协议)错误

*/

public static final int HTTP_ERROR = 1005;

/**

  • 证书错误

*/

public static final int SSL_ERROR = 1006;

public HttpThrowable(int errorType, String message, Throwable throwable) {

super(throwable);

this.errorType = errorType;

this.message = message;

this.throwable = throwable;

}

}

import com.alibaba.fastjson.JSONException;

import com.google.gson.JsonParseException;

import java.net.ConnectException;

import java.net.SocketTimeoutException;

import java.net.UnknownHostException;

import retrofit2.HttpException;

public class ThrowableHandler {

public static HttpThrowable handleThrowable(Throwable throwable) {

if (throwable instanceof HttpException) {

return new HttpThrowable(HttpThrowable.HTTP_ERROR, “网络(协议)异常”, throwable);

} else if (throwable instanceof JsonParseException || throwable instanceof JSONException || throwable instanceof ParseException) {

return new HttpThrowable(HttpThrowable.PARSE_ERROR, “数据解析异常”, throwable);

} else if (throwable instanceof UnknownHostException) {

return new HttpThrowable(HttpThrowable.NO_NET_ERROR, “网络连接失败,请稍后重试”, throwable);

} else if (throwable instanceof SocketTimeoutException) {

return new HttpThrowable(HttpThrowable.TIME_OUT_ERROR, “连接超时”, throwable);

} else if (throwable instanceof ConnectException) {

return new HttpThrowable(HttpThrowable.CONNECT_ERROR, “连接异常”, throwable);

} else if (throwable instanceof javax.net.ssl.SSLHandshakeException) {

return new HttpThrowable(HttpThrowable.SSL_ERROR, “证书验证失败”, throwable);

} else {

return new HttpThrowable(HttpThrowable.UNKNOWN, throwable.getMessage(), throwable);

}

}

}

  • 误时重试

public class RetryWithDelay implements Function<Observable, ObservableSource<?>> {

private int retryDelaySeconds;//延迟重试的时间

private int retryCount;//记录当前重试次数

private int retryCountMax;//最大重试次数

public RetryWithDelay(int retryDelaySeconds, int retryCountMax) {

this.retryDelaySeconds = retryDelaySeconds;

this.retryCountMax = retryCountMax;

}

@Override

public ObservableSource<?> apply(Observable throwableObservable) throws Exception {

//方案一:使用全局变量来控制重试次数,重试3次后不再重试,通过代码显式回调onError结束请求

return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {

@Override

public ObservableSource<?> apply(Throwable throwable) throws Exception {

//如果失败的原因是UnknownHostException(DNS解析失败,当前无网络),则没必要重试,直接回调error结束请求即可

if (throwable instanceof UnknownHostException) {

return Observable.error(throwable);

}

//没超过最大重试次数的话则进行重试

if (++retryCount <= retryCountMax) {

//延迟retryDelaySeconds后开始重试

return Observable.timer(retryDelaySeconds, TimeUnit.SECONDS);

}

return Observable.error(throwable);

}

});

}

}

  • 拦截器

public class CacheIntercepter implements Interceptor {

@NotNull

@Override

public Response intercept(@NotNull Chain chain) throws IOException {

//对request的设置用来指定有网/无网下所走的方式

//对response的设置用来指定有网/无网下的缓存时长

Request request = chain.request();

if (!NetworkUtils.isNetWorkAvailable(AppGlobals.getApplication())) {

//无网络下强制使用缓存,无论缓存是否过期,此时该请求实际上不会被发送出去。

//有网络时则根据缓存时长来决定是否发出请求

request = request.newBuilder()

.cacheControl(CacheControl.FORCE_CACHE).build();

}

Response response = chain.proceed(request);

if (NetworkUtils.isNetWorkAvailable(AppGlobals.getApplication())) {

//有网络情况下,超过1分钟,则重新请求,否则直接使用缓存数据

int maxAge = 60; //缓存一分钟

String cacheControl = “public,max-age=” + maxAge;

//当然如果你想在有网络的情况下都直接走网络,那么只需要

//将其超时时间maxAge设为0即可

return response.newBuilder()

.header(“Cache-Control”, cacheControl)

.removeHeader(“Pragma”).build();

} else {

//无网络时直接取缓存数据,该缓存数据保存3天

int maxStale = 60 * 60 * 24 * 3; //无网络时,设置超时为3天

return response.newBuilder()

.header(“Cache-Control”, “public,only-if-cached,max-stale=” + maxStale)

.removeHeader(“Pragma”).build();

}

}

}

public class HeaderInterceptor implements Interceptor {

@NotNull

@Override

public Response intercept(@NotNull Chain chain) throws IOException {

Request originalRequest = chain.request();

Request.Builder builder = originalRequest.newBuilder();

//设置具体的header内容

builder.addHeader(“Content-Type”, “text/html;charset=UTF-8”);

builder.addHeader(“token”, “123456789”);

Request.Builder requestBuilder =

builder.method(originalRequest.method(), originalRequest.body());

Request request = requestBuilder.build();

return chain.proceed(request);

}

}

  • 绕过所有的证书

/**

  • 绕过所有的证书

*/

public class TrustAllCerts implements X509TrustManager {

@Override

public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

}

@Override

public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

}

@Override

public X509Certificate[] getAcceptedIssuers() {

return new X509Certificate[0];

}

public static SSLSocketFactory createSSLSocketFactory() {

SSLSocketFactory factory = null;

try {

SSLContext context = SSLContext.getInstance(“TLS”);

context.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());

factory = context.getSocketFactory();

} catch (Exception e) {

}

return factory;

}

public static class TrustAllHostnameVerifier implements HostnameVerifier {

面试复习笔记:

这份资料我从春招开始,就会将各博客、论坛。网站上等优质的Android开发中高级面试题收集起来,然后全网寻找最优的解答方案。每一道面试题都是百分百的大厂面经真题+最优解答。包知识脉络 + 诸多细节。
节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
给文章留个小赞,就可以免费领取啦~

戳我领取:GitHub

《960页Android开发笔记》

《1307页Android开发面试宝典》

包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

ass TrustAllCerts implements X509TrustManager {

@Override

public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

}

@Override

public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

}

@Override

public X509Certificate[] getAcceptedIssuers() {

return new X509Certificate[0];

}

public static SSLSocketFactory createSSLSocketFactory() {

SSLSocketFactory factory = null;

try {

SSLContext context = SSLContext.getInstance(“TLS”);

context.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());

factory = context.getSocketFactory();

} catch (Exception e) {

}

return factory;

}

public static class TrustAllHostnameVerifier implements HostnameVerifier {

面试复习笔记:

这份资料我从春招开始,就会将各博客、论坛。网站上等优质的Android开发中高级面试题收集起来,然后全网寻找最优的解答方案。每一道面试题都是百分百的大厂面经真题+最优解答。包知识脉络 + 诸多细节。
节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
给文章留个小赞,就可以免费领取啦~

戳我领取:GitHub

《960页Android开发笔记》

[外链图片转存中…(img-gio5XUFO-1644043694194)]

《1307页Android开发面试宝典》

包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

[外链图片转存中…(img-D3kG1xcN-1644043694195)]

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

RxJava+Retrofit使用,详细解说相关推荐

  1. 动态代理之Rxjava/Retrofit应用实战

    一.前言 今天这篇文章,是对项目中用到的MVP + RxJava + Retrofit的整个架构做了一个简化,抽离出其中最核心的部分编写的读取 Gank 中拉取新闻资讯的例子. 下面我们先介绍一个整个 ...

  2. Rxjava+Retrofit+Mvp的使用实例(基于retrofit2.1.0)

    1.MVP介绍 在Android项目中,Activity和Fragment占据了大部分的开发工作.如果有一种设计模式(或者说代码结构)专门是为优化Activity和Fragment的代码而产生的,你说 ...

  3. Rxjava+Retrofit的使用实例(基于retrofit2.1.0)

    1.RxJava 到底是什么 一个词:异步. RxJava 在 GitHub 主页上的自我介绍是 "a library for composing asynchronous and even ...

  4. RxJava+Retrofit+MVP+Dagger2

    传说中的谷歌四件套,按顺序来哈~ 2017.2.20更新:对于用了一段时间的谷歌四件套的开发者们来说,基础应该都已经掌握的差不多了,但是四件套确实很博大精深,要想完全掌握,一是要学习使用技巧,二是要在 ...

  5. android小说阅读、MVP + RxJava + Retrofit项目、证件拍照裁剪、蓝牙锁等源码

    Android精选源码 完全防美团设置支付密码,页面与细节完全一致,如不能... android智能选股应用源码 android开源小说阅读app源码(Kotlin) Android模仿Duoling ...

  6. android小说阅读、MVP + RxJava + Retrofit项目、证件拍照裁剪、蓝牙锁等源码器

    Android精选源码 完全防美团设置支付密码,页面与细节完全一致,如不能- android智能选股应用源码 android开源小说阅读app源码(Kotlin) Android模仿Duolingo的 ...

  7. android如何获取网络的状态码,Android RxJava+Retrofit网络异常、状态码统一处理

    Android RxJava+Retrofit 网络异常捕获.状态码统一处理 前言 近来使用RxJava+Retrofit进行开发,在项目中遇到这样一个需求,联网请求获得数据异常时,需要将对应的Mes ...

  8. java使用bks双向认证_GitHub - wanglijun93/RxHttpUtils: Rxjava+Retrofit封装,便捷使用

    重磅推出 RxHttpUtils 2.x 版本 RxJava+Retrofit封装,基于RxJava2和Retrofit2重构,便捷使用 上次封装的是基于RxJava1版本的,时隔半年多之后现在推出基 ...

  9. 一款在线视频 App,基于 Material Design + MVP + RxJava + Retrofit + Realm + Glide

    Ghost 项目地址:GeekGhost/Ghost 简介:一款在线视频 App,基于 Material Design + MVP + RxJava + Retrofit + Realm + Glid ...

  10. TLint for 虎扑体育 基于Dagger2+RxJava+Retrofit开发,采用MVP模式

    TLint 类别: 完整源码 打分: ★★★★★ 更新: 2016-05-12 09:54 大小: 6976 kb 开发环境: Android Studio 浏览: 484 次 下载: 83 次 项目 ...

最新文章

  1. EasyUI –tree、combotree学习总结
  2. 如何从字符串中删除最后一个字符?
  3. 1. Action 实现 ModelDriven 接口后的运行流程
  4. kdj超卖_三分钟学会KDJ三大买卖绝技,简单高效,把握最佳买卖点,不懂KDJ的股民值得一看!...
  5. spring boot+mybatis整合
  6. 哈希表-拉链法及应用举例
  7. SpringBoot FK-关联表查询(三)
  8. SQLite-database disk image is malformed问题的解决
  9. iOS开发编译错误:std::terminate(), referenced from:
  10. windows下编译Chrome浏览器
  11. 锐起无盘系统菜鸟教程
  12. 小菜鸟的Python笔记002:如何识别Word文档中的复选框
  13. 0-day漏洞,1-day漏洞,n-day漏洞各自是什么意思?
  14. WiMAX与Wi-Fi、DSL和3G的竞合关系
  15. c++win32项目 如何显示后再删除一个绘图_Golden Software Surfer(三维绘图软件) 中文版分享...
  16. JavaScript(JS)的基本语法
  17. 知网文献免费下载方法
  18. 个人购买云服务器的必要性和最常见几个用途?细节考虑
  19. 用esp8266驱动0.96寸OLED屏幕 太空人动画
  20. Every derived table must have its own alias(sql语句错误解决方法)

热门文章

  1. 城市公园智能化中的5G千兆网关应用
  2. 随机规划及其Recourse(追索/补偿)问题
  3. python描述性统计工作日上班时代码_数据的描述性统计以及用Python代码实现
  4. Go语言核心36讲(Go语言实战与应用十二)--学习笔记
  5. wp load.php下载,wordpress网站打开首页出现下载页面解决方法
  6. rabbitmq 消息推送问题记录
  7. set-script是什么?
  8. 利用Python将WEBVTT格式的视频字幕文件转为SRT格式
  9. Beyond 海阔天空 翻唱
  10. ubuntu下新建txt文档的快捷方式