专栏首页码客Android OkGo网络请求库 自定义回调支持带泛型的对象

Android OkGo网络请求库 自定义回调支持带泛型的对象

前言

这里写了两种方式请求接口 (文中用了Java和Kotlin两种语言 没有特殊标示的都是Java)

  • 普通方式
  • Rx方式

建议是用Rx方式

常用调用方式

依赖

名称

引用方式

作用

okhttp-OkGo

compile 'com.lzy.net:okgo:3.0.4'

HTTP请求

fastjson

compile 'com.alibaba:fastjson:1.2.46'

回调转JSON

涉及的实体类

public class ResultVo<T> {
	private int code = 0;// 返回是否成功  0成功 1失败  2token不存在
	private String msg = "";// 返回提示信息
	private T obj;// 返回对象或者对象列表

	public ResultVo() {
	}

	public ResultVo(int code, String msg, T list) {
		super();
		this.code = code;
		this.msg = msg;
		this.obj = list;
	}

	public int getCode() {
		return code;
	}

	public void setCode(int code) {
		this.code = code;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public Object getObj() {
		return obj;
	}

	public void setObj(T obj) {
		this.obj = obj;
	}

	@Override
	public String toString() {
		return "ResultVo [code=" + code + ", msg=" + msg + ", obj=" + obj + "]";
	}
}

自定义回调

ZJJsonCallback

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.view.Window;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.lzy.okgo.callback.AbsCallback;
import com.lzy.okgo.request.base.Request;
import com.saitongedu.saitongplatformpad.config.ApiConfig;
import com.saitongedu.saitongplatformpad.model.ResultVo;
import com.saitongedu.saitongplatformpad.model.TUserBean;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import okhttp3.Response;
import okhttp3.ResponseBody;

public abstract class ZJJsonCallback<T> extends AbsCallback<T> {

    private ProgressDialog dialog;
    Context mContext = null;
    private Boolean showProgress = true;
    TypeReference<T> type;

    public ZJJsonCallback() {
    }

    public ZJJsonCallback(Activity activity, Boolean showProgress, TypeReference<T> type) {
        this.showProgress = showProgress;
        this.type = type;
        mContext = activity;
        dialog = new ProgressDialog(activity);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setMessage("请求网络中...");
    }

    @Override
    public void onFinish() {
        if (dialog != null && dialog.isShowing()) {
            dialog.dismiss();
        }
    }

    @Override
    public void onStart(Request<T, ? extends Request> request) {
        super.onStart(request);

        if (dialog != null && !dialog.isShowing()) {
            if (this.showProgress) {
                dialog.show();
            }
        }
        // 主要用于在所有请求之前添加公共的请求头或请求参数
        // 例如登录授权的 token
        Object spusermodel = SPUtils.get(mContext, "spusermodel", "");
        if (!"".equals(spusermodel)) {
            TUserBean user = JSON.parseObject(spusermodel.toString(), TUserBean.class);
            request.params("token", user.getToken());
        }

    }
    
    @Override
    public T convertResponse(Response response) throws Throwable {

        if (response.isSuccessful()) {
            String bodyInfo = "";
            //防止OOM
            try {
                ResponseBody body = response.body();
                bodyInfo = inputStream2String(body.byteStream());
                body.close();

                return JSON.parseObject(bodyInfo, type);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return null;
    }

    public String inputStream2String(InputStream in) throws IOException {
        StringBuffer out = new StringBuffer();
        byte[] b = new byte[4096];
        for (int n; (n = in.read(b)) != -1; ) {
            out.append(new String(b, 0, n));
        }
        return out.toString();
    }
}

ZJStringCallback

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.view.Window;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.lzy.okgo.callback.AbsCallback;
import com.lzy.okgo.request.base.Request;
import com.saitongedu.saitongplatformpad.model.TUserBean;

import java.io.IOException;
import java.io.InputStream;

import okhttp3.Response;
import okhttp3.ResponseBody;

public abstract class ZJStringCallback extends AbsCallback<String> {

    private ProgressDialog dialog;
    Context mContext = null;
    private Boolean showProgress = true;

    public ZJStringCallback() {
    }

    public ZJStringCallback(Activity activity, Boolean showProgress) {
        this.showProgress = showProgress;
        mContext = activity;
        dialog = new ProgressDialog(activity);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setMessage("请求网络中...");
    }

    @Override
    public void onFinish() {
        if (dialog != null && dialog.isShowing()) {
            dialog.dismiss();
        }
    }

    @Override
    public void onStart(Request<String, ? extends Request> request) {
        super.onStart(request);

        if (dialog != null && !dialog.isShowing()) {
            if (this.showProgress) {
                dialog.show();
            }
        }
        // 主要用于在所有请求之前添加公共的请求头或请求参数
        // 例如登录授权的 token
        Object spusermodel = SPUtils.get(mContext, "spusermodel", "");
        if (!"".equals(spusermodel)) {
            TUserBean user = JSON.parseObject(spusermodel.toString(), TUserBean.class);
            request.params("token", user.getToken());
        }

    }

    /**
     * 该方法是子线程处理,不能做ui相关的工作
     * 主要作用是解析网络返回的 response 对象,生产onSuccess回调中需要的数据对象
     * 这里的解析工作不同的业务逻辑基本都不一样,所以需要自己实现,以下给出的时模板代码,实际使用根据需要修改
     */
    @Override
    public String convertResponse(Response response) throws Throwable {

        if (response.isSuccessful()) {
            String bodyInfo = "";
            //防止OOM
            try {
                ResponseBody body = response.body();
                bodyInfo = inputStream2String(body.byteStream());
                body.close();
                response.close();
                return bodyInfo;
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return null;
    }

    public String inputStream2String(InputStream in) throws IOException {
        StringBuffer out = new StringBuffer();
        byte[] b = new byte[4096];
        for (int n; (n = in.read(b)) != -1; ) {
            out.append(new String(b, 0, n));
        }
        return out.toString();
    }
}

调用方式

JsonCallback

OkGo.post<ResultVo<String>>(ApiConfig.userapi_login)
    .params("loginname", "zhangjian")
    .params("loginpwd", "wangning")
    .params("device", "pad")
    .execute(object : ZJJsonCallback<ResultVo<String>>(
        this,
        true,
        object : TypeReference<ResultVo<String>>(){}
    ) {
        override fun onSuccess(response: Response<ResultVo<String>>) {
            val result = response.body()
            if (result.code == 0) {

            }
        }
    })

StringCallback

OkGo.post<String>(ApiConfig.userapi_login)
    .params("loginname", "zhangjian")
    .params("loginpwd", "wangning")
    .params("device", "pad")
    .execute(object : ZJStringCallback(this,true){
        override fun onSuccess(response: Response<String>?) {
            L.i(response!!.body())
        }
    })

Rx方式

依赖

名称

引用方式

作用

Okhttp-OkGo

compile 'com.lzy.net:okgo:3.0.4'compile 'com.lzy.net:okrx2:2.0.2'

HTTP请求

Fastjson

compile 'com.alibaba:fastjson:1.2.46'

回调转JSON

Rxjava

implementation 'io.reactivex.rxjava2:rxjava:2.1.10'

Rx

RxAndroid

implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'

Rx

转换器

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.lzy.okgo.convert.Converter;

import okhttp3.Response;
import okhttp3.ResponseBody;


public class ZJJsonConvert<T> implements Converter<T> {

    TypeReference<T> type;

    public ZJJsonConvert(TypeReference<T> type) {
        this.type = type;
    }

    @Override
    public T convertResponse(Response response) throws Throwable {
        ResponseBody body = response.body();
        if (body == null) return null;
        String bodyStr = body.string();
        return JSON.parseObject(bodyStr, type);
    }
}

封装接口

import com.alibaba.fastjson.TypeReference;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.convert.StringConvert;
import com.lzy.okrx2.adapter.ObservableBody;

import io.reactivex.Observable;
import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;


public class ZJUserApi {
    public static Observable<ResultVo<TUserBean>> userapi_login(
        String loginname,
        String loginpwd
    ) {
        Observable<ResultVo<TUserBean>> obs =
            OkGo.<ResultVo<TUserBean>>post(ApiConfig.userapi_login)
            .params("loginname", loginname)
            .params("loginpwd", loginpwd)
            .params("device", "pad")
            .converter(
                new ZJJsonConvert<>(
                    new TypeReference<ResultVo<TUserBean>>() {}
                )
            )
            .adapt(new ObservableBody<ResultVo<TUserBean>>())
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
        return obs;
    }
}

调用方式

Kotlin

ZJUserApi.userapi_login("zhangjian", "123456")
    .subscribe {
        L.i(it.msg)
    }

页面销毁取消请求

要想页面销毁时取消网络请求 就要做如下修改

定义Activity的基类(请忽略onCreate中的方法 只是用来去掉状态栏的背景)

Kotlin

open class SBaseActivity : AppCompatActivity() {

    var compositeDisposable: CompositeDisposable? = null

    fun addDisposable(disposable: Disposable) {
        if (null == compositeDisposable) {
            compositeDisposable = CompositeDisposable()
        }
        compositeDisposable?.add(disposable)
    }

    fun dispose(){
        compositeDisposable?.dispose()
    }

    override fun onDestroy() {
        super.onDestroy()
        dispose()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            val window = window
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
            window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
            window.statusBarColor = Color.TRANSPARENT
        }
    }
}

调用的方法改成如下(Kotlin)

var disposable = ZJUserApi.userapi_login(
    "zhangjian",
    "wangning")
    .subscribe {
        L.i(it.msg)
    }
addDisposable(disposable)

这样页面在销毁时 就会取消请求了

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java之ArrayList解剖学

    回归基础,回归原理,你会有更深的领悟。今天来聊一聊在Java当中常用的一个集合类:ArrayList。

    23号杂货铺
  • 年后跳槽,你急需的装X技能图谱

    年后陆陆续续的小伙伴都各自回到各自的岗位开始上班,经过了18年的“寒冬”,马上就要进入新的节奏。

    23号杂货铺
  • JVM之GC与对象的引用(三)

    GC,从当下的企业级应用开发来看,是大多数攻城狮必须具备和get的技能。但又有很多人不愿意去面对它(比如我

    23号杂货铺
  • Go学习之懒人速成 - 基础篇(二)

    在上一篇《入门篇》,已经提高了Go的安装和使用,接下来我们一起学习一下Golang的基础语法

    23号杂货铺
  • JVM之调优工具详解 - jps、jstack、jmap、jhat、jstat、hprof

    这些问题在日常开发中可能被很多人忽视(比如有的人遇到上面的问题只是重启服务器或者调大内存,而不会深究问题根源),但能够理解并解决这些问题是Java程序员...

    23号杂货铺
  • Go学习之新奇视角 - 入门篇(一)

    最近工作中,需要研究Go语言的区块链项目,作为一个Java出身的程序汪,不得不开始走向新的火热学习当中去。

    23号杂货铺
  • Go学习之基础进阶 - 理解篇(三)

    在《基础篇》和《入门篇》当中,我们已经知道了Golang的基本属性、方法等知识,接下来,在本文当中就详细介绍一下Go中的一些常用操作和语法函数,包含下面几个内容...

    23号杂货铺
  • JVM之内存管理(一)

    现如今的企业级Java应用开发已经日渐成熟,而越来越多的系统应用变得更加庞大而难以发现问题,JVM就是一个必须去重视和关注的难点,今天我们就开始对此进行认识、了...

    23号杂货铺
  • JVM之GC算法解读(四)

    在上一文《GC与类的生命周期》中,我简单介绍了与垃圾回收相关的一些知识概念,在本文当中,就来对GC所依赖和实现的算法进行深入的解读和理解。希望对大家有所帮助~

    23号杂货铺
  • JAVA之常用开发工具

    工欲善其事必先利其器,要想学好java这门语言,选择一款好用顺手的开发工具是必不可少的。另外面试Java工作时开发工具的使用也是一个重要的考核点。

    23号杂货铺

扫码关注云+社区

领取腾讯云代金券