【Android】Retrolfit2+Rxjava2 + OkHttp请求网络+取消已发出网络请求

 

    近日老出现尴尬的事儿,自己写的app自己测试时遇不到的问题总是在同事要看时出现,像中了魔咒一样,于是下定决心,一定要搞了她,于是开始疯狂点击,不出所料出现了,NPE了,看了下原来是一个Butterknife注解的RecyclerView在调用时报的,具体原因是,进入一个页面进行了网络请求,在结果还没返回时就退出了该界面,但是好死不死的是界面没完全销毁时结果出来了,这个时候这个RecyclerView已经被销毁了,所以再在success方法中调用RecyclerView去操作时就会报NPE.

    这里记录一下Retrolfit2+Rxjava2 + Okhttp的使用及对上述问题的处理办法。

 

 0、首先封装Retrolfit

import com.nxt.harmlessmanagesys.constant.SwitchConstant;

import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * @author: LiuChaoya
 * @createTime: 2018/4/10 0010 14:45
 * @classDescription: 封装Retrolfit
 * @email: [email protected]
 */

public enum RetrofitClient {
    INSTANCE;

    private static String BASEURL = API.BASEURL;
    public RetrofitServicer getService() {
        return new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(BASEURL)
                .client(createOkhttpClient())
                .build()
                .create(RetrofitServicer.class);
    }

    private Boolean OKHTTP_LOG = SwitchConstant.NetRequestSet.OKHTTP_LOG;
    private HttpLoggingInterceptor.Level OKHTTP_LOG_LEVEL = SwitchConstant.NetRequestSet.OKHTTP_LOG_LEVEL;
    private Integer CONNECT_TIME_OUT = SwitchConstant.NetRequestSet.CONNECT_TIME_OUT;
    private Integer WRITE_TIME_OUT = SwitchConstant.NetRequestSet.WRITE_TIME_OUT;
    private Integer READ_TIME_OUT = SwitchConstant.NetRequestSet.READ_TIME_OUT;

    private OkHttpClient createOkhttpClient() {
        OkHttpClient.Builder okhttpBuilder = new OkHttpClient.Builder();
        if (OKHTTP_LOG) {
            okhttpBuilder.addNetworkInterceptor(
                    new HttpLoggingInterceptor().setLevel(OKHTTP_LOG_LEVEL));
        }
        if (CONNECT_TIME_OUT != null) {
            okhttpBuilder.connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS);
        }
        if (WRITE_TIME_OUT != null) {
            okhttpBuilder.writeTimeout(WRITE_TIME_OUT, TimeUnit.SECONDS);
        }
        if (READ_TIME_OUT != null) {
            okhttpBuilder.readTimeout(READ_TIME_OUT, TimeUnit.SECONDS);
        }
        return okhttpBuilder.build();
    }
}

 

1、service类构建

import java.util.Map;

import io.reactivex.Observable;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.PartMap;
import retrofit2.http.Url;

/**
 * @author: LiuChaoya
 * @createTime: 2018/4/10 0010 14:50
 * @classDescription: service
 * @email: [email protected]
 */

public interface RetrofitServicer {

    /**
     * @param url      请求子地址
     * @return         Retrofit2 的Observable对象
     */
    @GET
    Observable getData(@Url String url);

    /**
     * @param url       请求子地址
     * @param params   请求参数
     * @return          Retrofit2 的Observable对象
     */
    @FormUrlEncoded
    @POST()
    Observable postData(@Url String url, @FieldMap(encoded = true) Map params);

    /**
     * 图片上传
     * @param url        请求子地址
     * @param partMap   请求参数
     * @param paramfile      上传的file文件
     * @return           Retrofit2 的Observable对象
     */
    @Multipart
    @POST()
    Observable uploadImg(@Url String url, @PartMap() Map partMap, @Part MultipartBody.Part paramfile);
}


2、model创建

import com.nxt.harmlessmanagesys.module.contract.Contract;
import com.nxt.harmlessmanagesys.module.data.net.RetrofitClient;
import com.nxt.harmlessmanagesys.utils.gson.GsonUtil;
import com.orhanobut.logger.Logger;

import java.util.HashMap;

import io.reactivex.Observable;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;

/**
 * @author: LiuChaoya
 * @createTime: 2018/4/10 0010 14:55
 * @classDescription: 
 * @email: [email protected]
 */

public class CommonModel implements Contract.Model {

    @Override
    public Observable postData(String url, HashMap params) {
        Observable data = RetrofitClient.INSTANCE.getService().postData(url, params);
        Logger.d("网路请求参数↓↓↓(请求地址==>" + url + "<==)");
        Logger.json(GsonUtil.INSTANCE.objectToString(params));
        return data;
    }
}
Contract是一个契约类,自己随便写写就出来了,这里也仅仅示范一个post请求的调用

3、presenter创建

import com.nxt.harmlessmanagesys.R;
import com.nxt.harmlessmanagesys.base.BaseActivity;
import com.nxt.harmlessmanagesys.base.BasePresenter;
import com.nxt.harmlessmanagesys.base.IBaseView;
import com.nxt.harmlessmanagesys.module.data.net.CustomObserver;
import com.nxt.harmlessmanagesys.module.model.CommonModel;
import com.orhanobut.logger.Logger;

import java.util.HashMap;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

/**
 * @author: LiuChaoya
 * @createTime: 2018/4/10 0010 14:58
 * @classDescription: 常用的presenter
 * @email: [email protected]
 */

public class CommonPresenter extends BasePresenter {

    private CommonModel model;

    public CommonPresenter() {
        model = new CommonModel();
    }


    @Override
    public void postData(final BaseActivity activity, String url,
                         HashMap params, final int type, String tip) {
        if (mView != null && !checkNet(activity)) {
            mView.showNoNet();
            return;
        }
        activity.showProgressDialog(tip);
        model.postData(url, params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new CustomObserver() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        super.onSubscribe(d);
                        disposables.add(d);
                        //发起请求后将本次请求返回的Disposable对象保存,用于取消网络请求用,            
                        //CompositeDisposable对象在父类BasePresenter
                    }
 
                    @Override 
                    public void onSuccess(String s) { 
                        //网络请求成功的处理逻辑 
                    }

                    @Override 
                    public void mOnError(String msg, String code) { 
                        //网络请求失败的处理逻辑 
                    } 
        }); 
    }
} 

} @Override public void onSuccess(String s) { //网络请求成功的处理逻辑 } @Override public void mOnError(String msg, String code) { //网络请求失败的处理逻辑 } }); }}    父presenter

import android.content.Context;

import com.nxt.harmlessmanagesys.module.contract.Contract;
import com.nxt.harmlessmanagesys.utils.NetworkTool;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.disposables.Disposable;

/**
 * @author: LiuChaoya
 * @createTime: 2018/4/10 0010 15:07
 * @classDescription: 
 * @email: [email protected]
 */
public abstract class BasePresenter


4、activity中调用

import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.nxt.harmlessmanagesys.R;
import com.nxt.harmlessmanagesys.utils.ContextUtils;
import com.nxt.harmlessmanagesys.utils.DialogTools;
import com.nxt.harmlessmanagesys.utils.SPUtil;
import com.nxt.harmlessmanagesys.utils.gson.GsonUtil;
import com.nxt.harmlessmanagesys.widght.CustomDialog;
import com.nxt.harmlessmanagesys.widght.ImageCircleView;
import com.umeng.analytics.MobclickAgent;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import butterknife.ButterKnife;
import butterknife.Unbinder;
import io.reactivex.disposables.Disposable;

/**
 * @author: LiuChaoya
 * @createTime: 2018/4/10 0010 15:10
 * @classDescription: activity基类
 * @email: [email protected]
 */

public abstract class BaseActivity> 
        implements IBaseView, IBase {

    private View mRootView;
    protected T mPresenter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

        mPresenter = getPresenter();//子类实现

        if (mPresenter != null) {
            mPresenter.attach(this);
        }
        mRootView = createView(null, null, savedInstanceState);//初始化布局 和 ButterKnife
        setContentView(mRootView);
        unbinder = ButterKnife.bind(this, mRootView);
        myBindView(savedInstanceState);//在子类实现
    }

    @Override
    public View createView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return ContextUtils.inflate(this, getContentLayout());//getContentLayout()在子类实现
    }

    @Override
    public View getView() {
        return mRootView;
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (unbinder != null) {
            unbinder.unbind();//解绑
        }
        if (mPresenter != null) {
            mPresenter.detachView();//销毁view
            mPresenter.cancelAllRequest();//取消网络请求
        }
    }
}

 


5、示例子类activity

 

import android.content.Intent;
import android.os.Bundle;
import android.view.View;

import com.luck.picture.lib.tools.DoubleUtils;
import com.nxt.harmlessmanagesys.R;
import com.nxt.harmlessmanagesys.base.BaseListActivity;
import com.nxt.harmlessmanagesys.base.BaseRecyclerAdapter;
import com.nxt.harmlessmanagesys.module.data.net.API;
import com.nxt.harmlessmanagesys.module.entity.ReportListBean;
import com.nxt.harmlessmanagesys.module.presenter.CommonPresenter;
import com.nxt.harmlessmanagesys.module.views.supervisecenter.holder.SceneCollectHolder;
import com.nxt.harmlessmanagesys.utils.SPUtil;
import com.nxt.harmlessmanagesys.utils.gson.GsonUtil;

import java.util.ArrayList;

/**
 * @author: LiuChaoya
 * @createTime: 2018/3/30 0030 11:02
 * @classDescription: 监管中心--现场收集
 * @email: [email protected]
 */

public class SceneCollectActivity extends BaseListActivity {

    @Override
    public CommonPresenter getPresenter() {
        return new CommonPresenter();
    }

    @Override
    public int getContentLayout() {
        return R.layout.activity_list;
    }


    @Override
    public void myBindView(Bundle savedInstanceState) {
        getList("get");
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == SAVE_DETAIL && resultCode == RESULT_OK){
            // TODO: LiuChaoya 2018/4/9 0009 9:13 保存详情回来,要么数据带回来整合,要么刷新列表

        }
    }


    protected void getList(String tip) {
        HashMap mMapParams = new HashMap<>();
        mMapParams.clear();
        mMapParams.put("api_method", "c.findReportList");
        mMapParams.put("a_id", SPUtil.getUSERID());
        mPresenter.postData(this, API.REPORT_LIST, mMapParams, NET_INDEX_ONE, tip);
    }

    @Override
    public void showSuccess(String s, int type) {
        if (type == NET_INDEX_ONE) {
            
        }
    }
}


差不多了,看了下还算能看懂,就这吧

 

 

 

你可能感兴趣的:(android)