欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Android网络请求框架(四)Retrofit和RxJava的封装

程序员文章站 2022-03-27 21:39:57
昨天给大家介绍了Retrofit配合Rxjava使用,但是重复代码无比的多,所以今天给大家吧Retrofit封装一下,通过3行代码来请求网络数据实现单例模式创建接口,用于实现Retrofit封装Observer创建接口,实现成功与失败方法返回GET使用POST使用POST上传图片和参数Git地址: [langyangyang](https://github.com/langyangyangzzZ/Volley)实现单例模式package demo.ht.com.volley.retrofitHttp;...

昨天给大家介绍了Retrofit配合Rxjava使用,但是重复代码无比的多,所以今天给大家吧Retrofit封装一下,通过3行代码来请求网络数据

实现单例模式

package demo.ht.com.volley.retrofitHttp;

import android.text.TextUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.android.BuildConfig;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;


//        添加以下依赖::
////        Retrofit:
//          implementation 'com.squareup.retrofit2:retrofit:2.9.0'
//            implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
//
//
//            //glide4:		//用于图片处理
//            implementation 'com.github.bumptech.glide:glide:4.8.0'
//            annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
//
//            //RxJava:
//            implementation "io.reactivex.rxjava2:rxjava:2.1.3" // 必要rxjava2依赖
//            implementation "io.reactivex.rxjava2:rxandroid:2.0.1" // 必要rxandrroid依赖,切线程时需要用到
//            implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0' // 必要依赖,和Retrofit结合必须用到,下面会提到
//
//            /**
//             *      日志拦截器
//             */
//            implementation 'com.squareup.okhttp3:logging-interceptor:3.3.1'


/**
 *  20200721  szj
 */
public class NetManager {
    private static volatile NetManager sNetManager;

    private NetManager() {
    }

    public static NetManager getNetManager() {
        if (sNetManager == null) {//考虑效率问题
            synchronized (NetManager.class) {
                if (sNetManager == null) {//考虑多个线程问题
                    sNetManager = new NetManager();
                }
            }
        }
        return sNetManager;
    }

    /**
     *
     * @param t 传入接口前半段 注意以/结尾 返回 ApiServer  
     * @param <T>   
     * @return
     */
    public <T> ApiServer getNetService(T... t) {
        /**
         *      使用官方日志拦截器
         *      添加依赖:
         *      implementation 'com.squareup.okhttp3:logging-interceptor:3.3.1'
         */
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        if (BuildConfig.DEBUG) {
            // Log信息拦截器
            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);//这里可以选择拦截级别

            //设置 Debug Log 模式
            builder.addInterceptor(loggingInterceptor);
        }
        //日志拦截器
        OkHttpClient build = builder.build();

        ApiServer  service = new Retrofit.Builder()
                //传入可变参数是因为这里也可以使用默认接口ApiServer.BaseUri
                .baseUrl(t != null && t.length != 0 && !TextUtils.isEmpty((String) t[0]) ? (String) t[0] : ApiServer.BaseUri)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(build)
                .build().create(ApiServer.class);
        return service;
    }

    /**
     *
     * @param whichApi  ID编号 通过ID编号来区分当前请求的数据
     * @param pObservable      请求的接口
     * @param presenterCallBack 返回值
     * @param <T>
     */
    public <T> void method( final int whichApi,Observable<T> pObservable, final ICommonView presenterCallBack) {
        pObservable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new BaseObserver() {
                    @Override
                    public void onSuccess(Object value) {
                        presenterCallBack.onSuccess(whichApi, value);
                    }

                    @Override
                    public void onFailed(Throwable value) {
                        presenterCallBack.onFailed(whichApi, value);
                    }
                });
    }

    /**
     *
     * 用于POST请求 传入键值对 获取RequestBody
     * @param hashMap  hashMap键值对
     * @return
     */
    public  RequestBody getRequestBody(HashMap<String, String> hashMap) {
        StringBuffer data = new StringBuffer();
        if (hashMap != null && hashMap.size() > 0) {
            Iterator iter = hashMap.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                Object key = entry.getKey();
                Object val = entry.getValue();
                data.append(key).append("=").append(val).append("&");
            }
        }
        String jso = data.substring(0, data.length() - 1);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded; charset=utf-8"),jso);

        return requestBody;
    }
}

创建接口,用于实现Retrofit

/**
 * 用于定义Retrofit接口
 */
public interface ApiServer {

    public static String BaseUri = "https://gank.io/api/data/%E7%A6%8F%E5%88%A9/";
//    http://hn216.api.yesapi.cn/
    public static String GuoChuangYun_BaseUri = "http://hn216.api.yesapi.cn/";
}

封装Observer

public abstract class BaseObserver implements Observer {
    private Disposable d;

    @Override
    public void onSubscribe(Disposable d) {
        this.d = d;
    }

    @Override
    public void onNext(Object value) {
        onSuccess(value);
        dispose();
    }

    @Override
    public void onError(Throwable e) {
        onFailed(e);
        dispose();
    }

    @Override
    public void onComplete() {

    }

    public abstract void onSuccess(Object value);

    public abstract void onFailed(Throwable value);

    private void dispose() {
        if (!d.isDisposed())
            d.dispose();
    }
}

创建接口,实现成功与失败方法返回

public interface ICommonView<S> {
    void onSuccess(int whichApi, S successResult);
    void onFailed(int whichApi, Throwable failedResult);
}

GET使用

NetManager netManager = NetManager.getNetManager();

ApiServer netService = netManager.getNetService(ApiServer.BaseUri);
            
            //请求美女接口
netManager.method(ApiConfig.GET_DATA_MEINV, netService.getHttpMeiNvBean("8", "1"), this);


实现ICommonView接口,重写onSuccess()和onFailed()方法,通过whichApi判断当前接口


@Override
    public void onSuccess(int whichApi, Object successResult) {
        if (whichApi == ApiConfig.GET_DATA_MEINV) {
            MeiNvBean meiNvBean = (MeiNvBean) successResult;
            mTv.setText("使用成功:\n" + meiNvBean.toString());
        } 
    }

    @Override
    public void onFailed(int whichApi, Throwable failedResult) {
        mTv.setText("使用失败:\n" + whichApi + "\n" + failedResult.getMessage());
    }

POST使用

 			NetManager netManager = NetManager.getNetManager();
            ApiServer netService = netManager.getNetService(ApiServer.GuoChuangYun_BaseUri);

            
            /**     方法一:
             *      通过netManager.getRequestBody()   获取RequestBody对象
             */
            RequestBody requestBody = netManager.getRequestBody(stringHashMap);
            netManager.method(ApiConfig.POST_UP_DATA_GUOCHUANGYUN,netService.getPOSTBodyGuoCHuangYunBean(requestBody),this);

            
            /**     方法二:
             * @POST 配合 @Body 注解请求数据
             */
//            netManager.method(ApiConfig.POST_UP_DATA_GUOCHUANGYUN,netService.getPOSTBodyGuoCHuangYunBean(app_key),this);

            /**    方法三:
             * @FormUrlEncoded 配合 @FieldMap请求数据
             * 注意:要想使用@FiledMap 或者 @Filed就必须使用@FormUrlEncoded注解声明
             *      使用@FormUrlEncoded 就必须使用@FiledMap 或者 @Filed
             */
            // netManager.method(ApiConfig.POST_UP_DATA_GUOCHUANGYUN,netService.getPOSTGuoCHuangYunBean(stringHashMap),this);

注释写的很详细,这里写了3种POST请求数据的方法;就不一一讲解了
然后还是和GET一样,实现ICommonView接口,重写onSuccess()和onFailed()方法

@Override
    public void onSuccess(int whichApi, Object successResult) {
         if(whichApi == ApiConfig.POST_UP_DATA_GUOCHUANGYUN){
            GuoChuangYunBean guoChuangYunBean = (GuoChuangYunBean) successResult;
            mTv.setText("使用成功:\n" + guoChuangYunBean.toString());
        }
    }

    @Override
    public void onFailed(int whichApi, Throwable failedResult) {
        mTv.setText("使用失败:\n" + whichApi + "\n" + failedResult.getMessage());
    }

POST上传图片和参数

	 //方法一:
        RequestBody requestBody = new MultipartBody.Builder().
                setType(MultipartBody.FORM)
                .addFormDataPart("app_key", "74D2E724FE2B69EF7EA3F38E9400CF71")
                .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/png"), file))
                .build();

        //方法二:
        RequestBody fileRQ = RequestBody.create(MediaType.parse("image/png"), file);
        MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), fileRQ);
        RequestBody fb =RequestBody.create(MediaType.parse("text/plain"), "74D2E724FE2B69EF7EA3F38E9400CF71");
        

			 /**
             *      封装
             */
            NetManager netManager = NetManager.getNetManager();
            ApiServer netService = netManager.getNetService(ApiServer.GuoChuangYun_BaseUri);

            /** 方法一:
             *    使用 @Body 注解 实现图片+参数一起上传
             */
//            netManager.method(ApiConfig.UP_DATA_IMAEG, netService.getImageBean(requestBody), this);


            /**  方法二: 
             *    使用 @Multipart注解 配合@Part 实现单独上传参数   和  单独上传图片
             */
            netManager.method(ApiConfig.UP_DATA_IMAEG, netService.uploadFile(fb,part), this);

同样实现ICommonView接口,重写onSuccess()和onFailed()方法,通过whichApi来判断当前接口;

 @Override
    public void onSuccess(int whichApi, Object successResult) {
       if (whichApi == ApiConfig.UP_DATA_IMAEG) {

            ImageBean imageBean = (ImageBean) successResult;
            Glide.with(this)
             .load(imageBean.getData().getUrl())
             .apply(new RequestOptions().placeholder(R.mipmap.ic_launcher))
             .into(mImage);
            mTv.setText("使用成功:\n" + imageBean.toString());

        }
    }

    @Override
    public void onFailed(int whichApi, Throwable failedResult) {
        mTv.setText("使用失败:\n" + whichApi + "\n" + failedResult.getMessage());
    }

Git地址: langyangyang

创作不易,各位有更好意见的请在评论区留言!谢谢观看啦~

本文地址:https://blog.csdn.net/weixin_44819566/article/details/107507426