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

昨天给大家介绍了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

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

猜你喜欢

转载自blog.csdn.net/weixin_44819566/article/details/107507426