Android LiveData + Retrofit 取消请求(二)
接着继续之前,我们来看
Retrofit + RxJava 取消请求
添加RxJava2的CallAdapter
private static final Retrofit RETROFIT_CLIENT =
new Retrofit.Builder().baseUrl(BASE_URL).
addConverterFactory(ScalarsConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()).
client(OkHttpHolder.OK_HTTP_CLIENT).build();
public interface RequestService {
@FormUrlEncoded
@POST
Observable<String> post( @Url String url, @FieldMap Map<String, Object> params);
}
发起请求
public final String TAG = "RetrofitRxJava";
//创建disposable容器
CompositeDisposable mCompositeDisposable = new CompositeDisposable();
RequestCreator.getRequestService().post("http://",...).
subscribeOn(Schedulers.io()).
observeOn(AndroidSchedulers.mainThread()).
subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.d(TAG,"onSubscribe=="+d.toString());
// d.dispose();
//添加disposable
mCompositeDisposable.add(d);
}
@Override
public void onNext(@NonNull String s) {
Log.d(TAG,"onNext --"+s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.d("onError",e.toString());
}
@Override
public void onComplete() {
Log.d(TAG,"onComplete");
}
}) ;
//清除容器,处理所有先前包含的Disposable
mCompositeDisposable.clear();
关于RxJava为何能解除请求,需要看RxJava2CallAdapterFactory中的RxJava2CallAdapter中的CallEnqueueObservable类
在CallEnqueueObservable 中CallCallback implement Disposable, Callback ,而在dispose 方法中调用了call.cancel()
RxJava 特点是链式调用,响应时框架
有上游的被观察者去订阅下游观察者及观察者的包装类,订阅后再依次调用上游的subscribeActual(),而 onNext,onComplete等由最上层被观察者回调所订阅的下游观察者,然后下游观察者在依次调用其所持有的下游观察者
太绕了… 难受
最终章,赶紧结束吧
LiveData + Retrofit 取消请求
创建LiveDataCallAdapterFactory
public final class LiveDataCallAdapterFactory extends CallAdapter.Factory {
static final String TAG = "LiveDataAdapterFactory";
public static LiveDataCallAdapterFactory create() {
return new LiveDataCallAdapterFactory();
}
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
/* returnType 是这样的类型
LiveData<ApiResponse<Data>>
LiveData<BaseResult<Data>> */
/* for (int i = 0; i < annotations.length; i++) {
Log.d(TAG,annotations[i].toString());
Log.d(TAG,"Type=="+annotations[i].annotationType());
}*/
//LiveData.class
Class<?> rawType = getRawType(returnType);
Log.d(TAG,rawType.toString());
//添加的判断,其中CallLiveData 是LiveData的实现类
if (!(rawType == LiveData.class || rawType == CallLiveData.class)){
return null;
}
boolean isResponse = false;
boolean isResult = false;
boolean isBody = false;
//observableType ApiResponse<Data>
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Log.d(TAG,"observableType=="+observableType.toString());
//ApiResponse
Class<?> rawObservableType = getRawType(observableType);
Log.d(TAG,"rawObservableType=="+ rawObservableType.toString());
//下面是根据返回参数类型的不同进行处理
if (rawObservableType == BaseResult.class){
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException(" must be parameterized");
}
isResult = true;
}else if(rawObservableType == ApiResponse.class){
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException(" must be parameterized");
}
isResponse = true;
}else {
isBody = true;
}
Log.d(TAG,"isResponse=="+isResponse+"=isResult="+isResult+"==isBody==="+isBody);
/**
* 类似这样的参数 ApiResponse<Info> 取的是Info
*/
Type bodyType = getParameterUpperBound(0, (ParameterizedType) observableType);
Log.d(TAG,"BodyType====="+bodyType);
return new LiveDataCallAdapter<>(bodyType,isResult,isResponse,isBody);
}
}
CallAdapter的实现
public class LiveDataCallAdapter<R> implements CallAdapter<R, Object> {
private static final String TAG = LiveDataCallAdapter.class.getSimpleName();
private final Type responseType;
private final boolean isResult;
private final boolean isResponse;
private final boolean isBody;
public LiveDataCallAdapter(Type responseType, boolean isResult, boolean isResponse, boolean isBody) {
this.responseType = responseType;
this.isResponse = isResponse;
this.isResult = isResult;
this.isBody = isBody;
}
@NotNull
@Override
public Type responseType() {
return responseType;
}
@NotNull
@Override
public LiveData<R> adapt(@NotNull Call<R> call) {
LiveData<R> response;
if (isResult){
response = new LiveDataBody<>(call);
}else if (isResponse){
// response = new LiveDataResponse<>(call);
response = new LiveDataRe<>(call);
}else{
response = new LiveDataBody<>(call);
}
return response;
}
}
请求进行数据处理
public class LiveDataRe<T> extends CallLiveData<T>{
public LiveDataRe(Call<T> call) {
super(call);
}
@Override
protected void onActive() {
super.onActive();
Log.d(TAG,"onActive");
if (isAccess()) {
CallCallback<T> callback = new CallCallback<>(this);
call.enqueue(callback);
}
}
@Override
protected void onInactive() {
super.onInactive();
Log.d(TAG,"onInactive ===" + call.isCanceled() + " "+ "===="+ hasActiveObservers());
}
private static final class CallCallback<T> implements Callback<T> {
private final CallLiveData<T> liveDataResponse;
private final String TAG = getClass().getSimpleName();
public CallCallback(CallLiveData<T> tLiveDataResponse) {
this.liveDataResponse = (LiveDataRe<T>) tLiveDataResponse;
}
@Override
public void onResponse(Call<T> call, Response<T> response) {
Logger.i("LiveDataResponse body=",""+response.body());
// call.cancel();
// liveDataResponse.postValue(ApiResponse.create(response));
liveDataResponse.postValue((T) ApiResponse.create(response));
}
@Override
public void onFailure(Call<T> call, Throwable t) {
if (call.isCanceled()){
liveDataResponse.postValue((T) ApiResponse.create("request call is cancel"));
}else{
Logger.e("LiveDataResponse=ERROR=",t.toString()+"====="+ t.getMessage());
ExceptionHandler.ExceptionThrowable handler = ExceptionHandler.handleException(t);
liveDataResponse.postValue((T) ApiResponse.create(handler.getMessage()));
}
// liveDataResponse.postValue(ApiResponse.create(t));
}
}
}
关联Call
public class CallLiveData<T> extends LiveData<T> {
public String TAG = getClass().getSimpleName();
private final AtomicBoolean started = new AtomicBoolean(false);
public Call<T> call;
public CallLiveData(Call<T> call) {
this.call = call.clone();
}
public void cancel() {
Log.d("CallLiveData","call cancel");
call.cancel();
}
public boolean isAccess() {
return started.compareAndSet(false, true);
}
@Override
protected void postValue(T value) {
super.postValue(value);
}
}
创建请求方法
@Multipart
@POST()
CallLiveData<ApiResponse<Info>> uploadFile(@PartMap Map<String, RequestBody> params,
@Part MultipartBody.Part file);
传递标记Tag
public LiveData<Resource<Info>> getOSUrl(String tag,Map<String, Object> map , File file){
return (new TagCommonBoundResource<Info,Info>(tag){
@Override
protected LiveData<ApiResponse<Info>> createCall() {
return null;
}
@Override
protected CallLiveData<ApiResponse<Info>> createTag() {
return RequestCreator.getRequestService().uploadFile(RetrofitTransUtil.map2RequestBody(map),
RetrofitTransUtil.file2Part(file));
}
}).asLiveData();
}
添加管理Tag
此处的apiResponse 来源于CommonBoundResource
public abstract class TagCommonBoundResource<ResultType,RequestType> extends CommonBoundResource<ResultType,RequestType>{
private String tag;
public TagCommonBoundResource(String tag) {
super();
this.tag = tag;
if (apiResponse instanceof CallLiveData){
TagManager.getInstance().add(tag,apiResponse);
}
}
// protected abstract CallLiveData<ApiResponse<RequestType>> createCall();
}
CommonBoundResource
private MediatorLiveData<Resource<ResultType>> result;
public CommonBoundResource() {
result = new MediatorLiveData<Resource<ResultType>>();
if (isOnline()) {
result.setValue(Resource.<ResultType>loading(null));
fetchFromNetWork();
} else {
result.setValue(Resource.<ResultType>error("Net Invalid", null));
}
}
public void fetchFromNetWork() {
Log.d(TAG, "FromNet");
apiResponse = createCall();
if (apiResponse == null) {
apiResponse = createTag();
}
... //此处省略了 result.addSource(apiResponse,observe)的回调数据处理
}
...
TagManage类
public class TagManager implements ActionManager{
private static final TagManager ourInstance = new TagManager();
private static final String TAG = TagManager.class.getSimpleName();
public static TagManager getInstance() {
return ourInstance;
}
private ArrayMap<Object,LiveData> mSources = new ArrayMap();
private TagManager() {
}
public void add(Object tag, LiveData liveData) {
if (liveData instanceof CallLiveData) {
mSources.put(tag, (CallLiveData) liveData);
}else{
Log.d(TAG,"live is not MediatorLiveData");
}
/* if (liveData instanceof MediatorLiveData) {
mSources.put(tag, (TagLiveData) liveData);
}else{
Log.d(TAG,"live is not MediatorLiveData");
}*/
}
public void remove(Object tag) {
if (!mSources.isEmpty()) {
mSources.remove(tag);
}
}
public void removeAll() {
if (!mSources.isEmpty()) {
mSources.clear();
}
}
@Override
public void cancel(Object tag) {
if (mSources.isEmpty()) {
return;
}
// TagLiveData data = mSources.get(tag);
CallLiveData data = (CallLiveData) mSources.get(tag);
if (data == null) {
return;
}
data.cancel();
/* if (data.hasObservers()){
data.onInactive();
}*/
mSources.remove(tag);
}
@Override
public void cancelAll() {
if (mSources.isEmpty()) {
return;
}
Set<Object> keys = mSources.keySet();
for (Object key:keys){
cancel(key);
}
}
public boolean contains(LiveData data) {
if (mSources.isEmpty()) {
return false;
}
Set<Object> keys = mSources.keySet();
for (Object apiKey : keys) {
if (data == mSources.get(apiKey)){
return true;
}
}
return false;
}
}
public interface ActionManager {
void cancel(Object tag);
void cancelAll();
}