zoukankan      html  css  js  c++  java
  • okhttputils【 Android 一个改善的okHttp封装库】使用(三)

    版权声明:本文为HaiyuKing原创文章,转载请注明出处!

    前言

    这一篇主要讲一下将OkHttpUtils运用到mvp模式中。

    数据请求地址:http://www.wanandroid.com/tools/mockapi/418/version

    效果图

    代码分析

    1、集成OKHttpUtils开源库参考《okhttputils【 Android 一个改善的okHttp封装库】使用(一)》;

    2、使用mvp模式封装网络请求。

    使用步骤

    一、项目组织结构图

    注意事项:

    1、  导入类文件后需要change包名以及重新import R文件路径

    2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

    二、导入步骤

    集成OKHttpUtils

    参考《okhttputils【 Android 一个改善的okHttp封装库】使用(一)

    mvp模式下修改和新增的类文件

    LoginLogic.java【调用的方法需要传入tag值,且注意方法命名规则:xxxApi】

    package com.why.project.okhttputilsmvpdemo.logic;
    
    import com.why.project.okhttputilsmvpdemo.MyApplication;
    import com.zhy.http.okhttp.OkHttpUtils;
    import com.zhy.http.okhttp.callback.StringCallback;
    
    /**
     * Created by HaiyuKing
     * Used
     */
    
    public class LoginLogic extends BaseLogic {
    
        private static LoginLogic _Instance = null;
    
        public static LoginLogic Instance() {
            if (_Instance == null)
                _Instance = new LoginLogic();
            return _Instance;
        }
        private LoginLogic() {
            this.context = MyApplication.getAppContext();//防止了内存泄漏
        }
    
        /**
         * 发现新版本接口
         */
        public String updateVersionApi(String tag, StringCallback callback)
                throws Exception {
            String result = "";
            OkHttpUtils
                    .get()
                    .url(getSpcyUrl(ServerApi.UPDATE_VERSION_URL))
                    .id(100)
                    .tag(tag)
                    .build()
                    .execute(callback);
            return result;
        }
    }

    UpdateVersionBean.java【一般项目中都是需要用到的】

    package com.why.project.okhttputilsmvpdemo.bean;
    
    /**
     * Created by HaiyuKing
     * Used 更新APP的实体类
     */
    
    public class UpdateVersionBean {
    
        private String versionName;//服务器上的版本号,比如3.0
        private String forceUpdate;//是否强制更新
        private String title;//标题,如果为空,则默认显示发现新版本
        private String content;//更新内容,如果为空,则不显示
        private String downloadurl;//下载地址
        private String fileSize;//文件大小
    
        public String getVersionName() {
            return versionName;
        }
    
        public void setVersionName(String versionName) {
            this.versionName = versionName;
        }
    
        public String getForceUpdate() {
            return forceUpdate;
        }
    
        public void setForceUpdate(String forceUpdate) {
            this.forceUpdate = forceUpdate;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        public String getDownloadurl() {
            return downloadurl;
        }
    
        public void setDownloadurl(String downloadurl) {
            this.downloadurl = downloadurl;
        }
    
        public String getFileSize() {
            return fileSize;
        }
    
        public void setFileSize(String fileSize) {
            this.fileSize = fileSize;
        }
    }

     UpdateVersionModel.java【命名规则:bean类的前缀+Model】【用于封装网络请求,然后通过callback回调】

    package com.why.project.okhttputilsmvpdemo.model;
    
    import android.content.Context;
    
    import com.why.project.okhttputilsmvpdemo.MyApplication;
    import com.why.project.okhttputilsmvpdemo.R;
    import com.why.project.okhttputilsmvpdemo.bean.UpdateVersionBean;
    import com.why.project.okhttputilsmvpdemo.logic.LoginLogic;
    import com.zhy.http.okhttp.callback.StringCallback;
    
    import org.json.JSONException;
    import org.json.JSONObject;
    
    import okhttp3.Call;
    import okhttp3.Request;
    
    /**
     * Created by HaiyuKing
     * Used 发现新版本的请求类
     */
    
    public class UpdateVersionModel {
    
        /**获取新版本的信息*/
        public void updateVersionInfo(String tag,
                                   final LoadingDataCallBack<UpdateVersionBean> callBack) {
            final Context mContext = MyApplication.getAppContext();
            //执行请求任务
            try {
                LoginLogic.Instance().updateVersionApi(tag,new StringCallback() {
                    @Override
                    public void onBefore(Request request, int id)
                    {
                        callBack.onBefore("");//回调
                    }
                    @Override
                    public void onAfter(int id)
                    {
                        callBack.onAfter();//回调
                    }
                    @Override
                    public void onError(Call call, Exception e, int id)
                    {
                        callBack.onError("");//回调
                    }
                    @Override
                    public void onResponse(String response, int id)
                    {
                        switch (id)
                        {
                            case 100://http
                                try {
                                    if (response != null && !"".equals(response)){
                                        JSONObject versionInfoObj = new JSONObject(response);
    
                                        UpdateVersionBean updateVersionBean = new UpdateVersionBean();
                                        updateVersionBean.setVersionName(versionInfoObj.getString("versionName"));
                                        updateVersionBean.setForceUpdate(versionInfoObj.getString("forceUpdate"));
                                        updateVersionBean.setTitle(versionInfoObj.getString("title"));
                                        updateVersionBean.setContent(versionInfoObj.getString("content"));
                                        updateVersionBean.setDownloadurl(versionInfoObj.getString("downloadurl"));
                                        updateVersionBean.setFileSize(versionInfoObj.getString("fileSize"));
    
                                        callBack.onSuccess(updateVersionBean);
                                    }else {
                                        //提示失败
                                        callBack.onFailure("");//回调
                                    }
                                }catch (JSONException e) {
                                    callBack.onError(mContext.getResources().getString(R.string.login_json_exception));//回调
                                }catch (Exception e) {
                                    callBack.onError(mContext.getResources().getString(R.string.login_json_exception));//回调
                                }
                                break;
                            case 101://https
                                break;
                        }
                    }
                    @Override
                    public void inProgress(float progress, long total, int id)
                    {
                        //callBack.onProgress(progress,total,id);//回调
                    }
                });
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    LoadingDataCallBack.java【网路请求的回调】

    package com.why.project.okhttputilsmvpdemo.model;
    
    /**
     * Used 常规接口请求的回调【请求发现新版本接口】
     */
    
    public interface LoadingDataCallBack<T> {
    
        /**
         * 数据请求前的操作
         * @ TODO 一般用于显示加载对话框
         */
        void onBefore(String msg);
    
        /**
         * 当请求数据结束时,无论请求结果是成功,失败或是抛出异常都会执行此方法给用户做处理
         * @ TODO 请求结束,一般隐藏加载提示对话框,或者执行下一步操作
         */
        void onAfter();
    
        /**
         * 数据请求成功
         * @param response 请求到的数据
         * @ TODO 请求成功,一般执行下一步的操作(继续请求接口,或者显示)
         */
        void onSuccess(T response);
    
        /**
         * 数据请求成功的提示语
         * @param msg 提示语
         * @ TODO 请求成功,一般用来提示msg
         */
        void onSuccessToast(String msg);
    
        /**
         *  请求失败
         *  使用网络API接口请求方式时,虽然已经请求成功但是由于{@code msg}的原因无法正常返回数据。
         *  @ TODO 请求失败,一般用来提示msg状态值以及提示语,或者显示无数据的区域【所以需要跟onError方法区别开来】
         */
        void onFailure(String msg);
    
        /**
         * 请求数据错误,指在请求网络API接口请求方式时,出现无法联网、缺少权限,内存泄露等原因导致无法连接到请求数据源。
         * @ TODO 请求错误,一般隐藏加载提示对话框,提示服务器返回的失败信息等
         */
        void onError(String msg);
    
        /**
         * 无网络时返回
         * @ TODO 一般隐藏加载提示对话框,提示当前网络不可用,或者显示无网络的区域【所以需要跟onError方法区别开来】
         */
        void onNoNetWork(String msg);
    }

    IBaseView.java【提取出来通用的抽象方法】

    package com.why.project.okhttputilsmvpdemo.iview;
    
    /**
     * Created by HaiyuKing
     * Used IView基类接口(含有通用的抽象方法声明)
     */
    
    public interface IBaseView {
        /** 显示正在加载进度框【通用】*/
        void showLoading(String msg);
    
        /** 隐藏正在加载进度框【通用】*/
        void hideLoading();
    
        /**显示提示信息【通用】*/
        void showToast(String msg);
    
        /** 获取OkHttpUtil用到的tag,一般使用当前类的类名即可。比如:this.getClass().getSimpleName()【通用】*/
        String getOkHttpUtilTag();
    
        /** 处理失败的情况【应该每一个接口对应一个,不过此处省略了】【主要用于第一次请求的时候,显示提示区域,一般情况下可以直接showToast即可】*/
        void showFail(String msg);
    
        /**
         * 处理无网络的情况【应该每一个接口对应一个,不过此处省略了】【主要用于第一次请求的时候,显示提示区域,一般情况下可以直接showToast即可】*/
        void showNotNetWork(String msg);
    }

    IUpdateAppView.java【如果跟某个activity或者fragment耦合度很高,那么可以命名为MainActivityView.java(也就是以这个activity或者fragment命名)】【命名规则:I{xxx}View】

    package com.why.project.okhttputilsmvpdemo.iview;
    
    
    import com.why.project.okhttputilsmvpdemo.bean.UpdateVersionBean;
    
    /**
     * Created by HaiyuKing
     * Used 更新APP的view
     */
    
    public interface IUpdateAppView extends IBaseView{
    
        /** 打开发现新版本对话框*/
        void showUpdateDialog(UpdateVersionBean updateVersionBean);
    
    }

    UpdateAppPresenter.java【如果跟某个activity或者fragment耦合度很高,那么可以命名为MainActivityPresenter.java(也就是以这个activity或者fragment命名)】【命名规则:xxxxPresenter】

    package com.why.project.okhttputilsmvpdemo.presenter;
    
    import android.text.TextUtils;
    
    import com.why.project.okhttputilsmvpdemo.bean.UpdateVersionBean;
    import com.why.project.okhttputilsmvpdemo.iview.IUpdateAppView;
    import com.why.project.okhttputilsmvpdemo.model.LoadingDataCallBack;
    import com.why.project.okhttputilsmvpdemo.model.UpdateVersionModel;
    
    /**
     * Created by HaiyuKing
     * Used 更新APP的presenter
     */
    
    public class UpdateAppPresenter {
        private IUpdateAppView mvpView;//view接口类
        private UpdateVersionModel mUpdateVersionModel;//发现新版本接口请求的model类
    
        public UpdateAppPresenter(){
            mUpdateVersionModel = new UpdateVersionModel();
        }
    
        /**
         * 绑定view,一般在初始化中调用该方法
         */
        public void attachView(IUpdateAppView view){
            mvpView = view;
        }
    
        /**
         * 断开view,一般在onDestroy中调用
         */
        public void detachView() {
            mvpView = null;
        }
    
        /**
         * 是否与View建立连接
         * 每次调用业务请求的时候都要出先调用方法检查是否与View建立连接
         */
        public boolean isViewAttached(){
            return mvpView != null;
        }
    
        /**发现新版本接口数据*/
        public void updateVersion() {
            if (!TextUtils.isEmpty(mvpView.getOkHttpUtilTag())) {
                mUpdateVersionModel.updateVersionInfo(mvpView.getOkHttpUtilTag(),
                        new LoadingDataCallBack<UpdateVersionBean>() {
                            @Override
                            public void onBefore(String msg) {
                                if (isViewAttached()) {
                                    mvpView.showLoading(msg);
                                }
                            }
    
                            @Override
                            public void onAfter() {
                                if (isViewAttached()) {
                                    mvpView.hideLoading();
                                }
                            }
    
                            @Override
                            public void onSuccess(UpdateVersionBean response) {
                                if (isViewAttached()) {
                                    mvpView.showUpdateDialog(response);
                                }
                            }
    
                            @Override
                            public void onSuccessToast(String msg) {
                                if (isViewAttached()) {
                                    mvpView.showToast(msg);
                                }
                            }
    
                            @Override
                            public void onFailure(String msg) {
                                if (isViewAttached()) {
                                    mvpView.showFail(msg);
                                }
                            }
    
                            @Override
                            public void onError(String msg) {
                                if (isViewAttached()) {
                                    mvpView.showToast(msg);
                                }
                            }
    
                            @Override
                            public void onNoNetWork(String msg) {
    
                            }
                        });
            }
        }
    }

    三、使用方法

    Activity下的使用

    package com.why.project.okhttputilsmvpdemo;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    import com.why.project.okhttputilsmvpdemo.bean.UpdateVersionBean;
    import com.why.project.okhttputilsmvpdemo.iview.IUpdateAppView;
    import com.why.project.okhttputilsmvpdemo.presenter.UpdateAppPresenter;
    import com.why.project.okhttputilsmvpdemo.utils.ToastUtil;
    import com.why.project.okhttputilsmvpdemo.utils.httputil.HttpUtil;
    import com.zhy.http.okhttp.OkHttpUtils;
    
    public class MainActivity extends AppCompatActivity implements IUpdateAppView{
    
        private static final String TAG = MainActivity.class.getSimpleName();
    
        private UpdateAppPresenter mvpUpdateAppPresenter;//发现新版本
        private String okHttpTag = "";//网络请求用到的tag
    
        private Button btn_get;
        private TextView tv_show;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //presenter绑定view{1}
            if(mvpUpdateAppPresenter == null){
                mvpUpdateAppPresenter = new UpdateAppPresenter();
            }
            //presenter绑定view{2}
            if(mvpUpdateAppPresenter != null) {
                mvpUpdateAppPresenter.attachView(this);
            }
    
            initViews();
            initData();
            initEvents();
        }
    
        @Override
        public void onPause() {
            // TODO Auto-generated method stub
            super.onPause();
            //取消网络请求,根据tag取消请求
            OkHttpUtils.getInstance().cancelTag(okHttpTag);
        }
    
        protected void onDestroy() {
            //取消网络请求
            Log.w(TAG,"this.getClass().getSimpleName()="+this.getClass().getSimpleName());
            OkHttpUtils.getInstance().cancelTag(okHttpTag);
            super.onDestroy();
    
            //presenter解绑view{3}
            if(mvpUpdateAppPresenter != null){
                mvpUpdateAppPresenter.detachView();
            }
        }
    
        private void initViews() {
            btn_get = (Button) findViewById(R.id.btn_get);
            tv_show = (TextView) findViewById(R.id.tv_show);
        }
    
        /**初始化数据*/
        private void initData() {
            okHttpTag = this.getClass().getSimpleName();
        }
    
        private void initEvents() {
            btn_get.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (HttpUtil.isNetworkAvailable(MainActivity.this)) {
                        //执行网络请求接口
                        try {
                            mvpUpdateAppPresenter.updateVersion();//请求发现新版本接口
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }else{
                        ToastUtil.showShortToast(MyApplication.getAppContext().getResources().getString(R.string.network_enable));
                    }
                }
            });
        }
    
        @Override
        public void showLoading(String msg) {
            //showProgressDialog("");//显示进度加载框
        }
    
        @Override
        public void hideLoading() {
            //dismissProgressDialog();//隐藏进度加载框
        }
    
        @Override
        public void showToast(String msg) {
            ToastUtil.showShortToast(msg);
        }
    
        @Override
        public String getOkHttpUtilTag() {
            return okHttpTag;
        }
    
        @Override
        public void showFail(String msg) {
            ToastUtil.showShortToast(msg);
        }
    
        @Override
        public void showNotNetWork(String msg) {
            ToastUtil.showShortToast(msg);
        }
    
        @Override
        public void showUpdateDialog(UpdateVersionBean updateVersionBean) {
            String showText = "新版本号:" + updateVersionBean.getVersionName() +
                    "
    是否强制更新:" + updateVersionBean.getForceUpdate() +
                    "
    标题:" + updateVersionBean.getTitle() +
                    "
    内容:" + updateVersionBean.getContent().replace("\n", "
    ") +
                    "
    文件大小:" + updateVersionBean.getFileSize() +
                    "
    下载地址:" + updateVersionBean.getDownloadurl();
            tv_show.setText(showText);
        }
    }

    Fragment下的使用

    package com.why.project.okhttputilsmvpdemo;
    
    import android.content.Context;
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.TextView;
    
    import com.why.project.okhttputilsmvpdemo.bean.UpdateVersionBean;
    import com.why.project.okhttputilsmvpdemo.iview.IUpdateAppView;
    import com.why.project.okhttputilsmvpdemo.presenter.UpdateAppPresenter;
    import com.why.project.okhttputilsmvpdemo.utils.ToastUtil;
    import com.why.project.okhttputilsmvpdemo.utils.httputil.HttpUtil;
    import com.zhy.http.okhttp.OkHttpUtils;
    
    /**
     * Created by HaiyuKing
     * Used
     */
    
    public class MainFragment extends Fragment implements IUpdateAppView{
        private static final String TAG = MainFragment.class.getSimpleName();
    
        private UpdateAppPresenter mvpUpdateAppPresenter;//发现新版本
        private String okHttpTag = "";//网络请求用到的tag
    
        /**View实例*/
        private View myView;
        private Context mContext;
    
        private Button btn_get;
        private TextView tv_show;
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //presenter绑定view{1}
            if(mvpUpdateAppPresenter == null){
                mvpUpdateAppPresenter = new UpdateAppPresenter();
            }
        }
    
        //重写
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            //presenter绑定view【适用presenter调用代码在onCreateView方法中执行的情况】{2}
            /*if(mvpPresenter != null) {
                mvpPresenter.attachView(this);
            }*/
            myView = inflater.inflate(R.layout.activity_main, container, false);
            return myView;
        }
    
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onActivityCreated(savedInstanceState);
            //由于fragment生命周期比较复杂,所以Presenter在onCreateView创建视图之后再进行绑定,不然会报空指针异常
            //presenter绑定view【如果presenter调用的代码是在onCreateView中执行的话,那么此处不合适执行绑定的方法】{2"}
            if(mvpUpdateAppPresenter != null) {
                mvpUpdateAppPresenter.attachView(this);
            }
    
            mContext = getActivity();
    
            //初始化控件以及设置
            initViews();
            //初始化数据
            initData();
            initEvents();
        }
    
        @Override
        public void onResume() {
            super.onResume();
        }
    
        @Override
        public void onPause() {
            super.onPause();
        }
    
        @Override
        public void onDestroyView() {
            //presenter解绑view{3}
            if(mvpUpdateAppPresenter != null){
                mvpUpdateAppPresenter.detachView();
            }
            super.onDestroyView();
        }
    
        @Override
        public void onDestroy() {
            //取消网络请求
            OkHttpUtils.getInstance().cancelTag(okHttpTag);
            super.onDestroy();
        }
    
        private void initViews() {
            btn_get = (Button) myView.findViewById(R.id.btn_get);
            tv_show = (TextView) myView.findViewById(R.id.tv_show);
        }
    
        /**初始化数据*/
        private void initData() {
            okHttpTag = this.getClass().getSimpleName();
        }
    
        private void initEvents() {
            btn_get.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (HttpUtil.isNetworkAvailable(mContext)) {
                        //执行网络请求接口
                        try {
                            mvpUpdateAppPresenter.updateVersion();//请求发现新版本接口
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }else{
                        ToastUtil.showShortToast(MyApplication.getAppContext().getResources().getString(R.string.network_enable));
                    }
                }
            });
        }
    
        @Override
        public void showLoading(String msg) {
            //showProgressDialog("");//显示进度加载框
        }
    
        @Override
        public void hideLoading() {
            //dismissProgressDialog();//隐藏进度加载框
        }
    
        @Override
        public void showToast(String msg) {
            ToastUtil.showShortToast(msg);
        }
    
        @Override
        public String getOkHttpUtilTag() {
            return okHttpTag;
        }
    
        @Override
        public void showFail(String msg) {
            ToastUtil.showShortToast(msg);
        }
    
        @Override
        public void showNotNetWork(String msg) {
            ToastUtil.showShortToast(msg);
        }
    
        @Override
        public void showUpdateDialog(UpdateVersionBean updateVersionBean) {
            String showText = "新版本号:" + updateVersionBean.getVersionName() +
                    "
    是否强制更新:" + updateVersionBean.getForceUpdate() +
                    "
    标题:" + updateVersionBean.getTitle() +
                    "
    内容:" + updateVersionBean.getContent().replace("\n", "
    ") +
                    "
    文件大小:" + updateVersionBean.getFileSize() +
                    "
    下载地址:" + updateVersionBean.getDownloadurl();
            tv_show.setText(showText);
        }
    }

    混淆配置

    参考《okhttputils【 Android 一个改善的okHttp封装库】使用(一)

    参考资料

    暂时空缺

    项目demo下载地址

    https://github.com/haiyuKing/OkHttpUtilsMvpDemo

  • 相关阅读:
    1025WHERE执行顺序以及MySQL查询优化器
    1025基础REDIS
    1025关于explain的补充1
    1021mysql 全外连接
    python开发进程:进程开启方式&多进程
    python开发面向对象进阶:反射&内置函数
    python开发socket套接字:粘包问题&udp套接字&socketserver
    python开发面向对象基础:封装
    python开发模块基础:异常处理&hashlib&logging&configparser
    python开发面向对象基础:接口类&抽象类&多态&钻石继承
  • 原文地址:https://www.cnblogs.com/whycxb/p/9184505.html
Copyright © 2011-2022 走看看