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

Android极封:Retrofit2+RxJava网络请求框架

程序员文章站 2022-04-22 10:46:23
说是极封,其实只是看起来极封 new RetrofitUtils(LoginAPI.class) { @Override protected void o...

说是极封,其实只是看起来极封

new RetrofitUtils(LoginAPI.class) {
    @Override
    protected void onSuccess(com.alibaba.fastjson.JSONObject jsonObject) {
        
    }
};

其实真正的极封还需要考虑许多细节以及性能的优化,不过这里已经可以满足我个人的需求了

原来的请求是这样的

new Retrofit.Builder()
        .baseUrl(baseUrl)
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .build()
        .create(LoginAPI.class)
        .getFriendList(user)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {
            }

            @Override
            public void onNext(JSONObject jsonObject) {

            }
        });

真是长篇大论,让代码太不美观了,所以我们必须得封装

封装思路,baseUrl也放到接口中

public interface LoginAPI {
    String baseUrl = "https://news-at.zhihu.com/";
    
    @GET("api/4/news/latest")
    Observable login();
}

所以我们只需要完成两件事情,就等于完成整个封装了

1.通过反射获取baseUrl

2.通过反射调用接口内的方法

获取Url

Field field = clx.getDeclaredFields()[0];
String baseUrl = field.get(null).toString();
clx就是你传进来的接口类,clx.getDeclaredFields()是获取了类中所有的属性,0是第一个属性,这里毫无疑问就是我们指定的baseUrl了。

field.get(null)本来是要传一个对象进去的,不然你怎么知道要获取的是哪个对象的这条属性,但是我们已经实现指定好了怎么办?直接传null,并且把属性设置为静态才行,由于接口中的所有都是public static的,所以这里就不用指定了

这里是Retrofit为我们创建了接口类

Object obj = new Retrofit.Builder()
        .baseUrl(baseUrl)
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .build()
        .create(clx);

获取这个类中的方法,并调用我们上面实例化的这个类中的这个方法,得到了返回值,对应上面的Observable

Method method = clx.getDeclaredMethods()[0];
Observable obs = (Observable) method.invoke(obj, args);

接下来根据得到的Observable来搞就行了

obs.subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {
                Log.i("xbh", "这个Log在RetrofitUtils,错误信息是:" +e.getMessage());
            }

            @Override
            public void onNext(T t) {
                onSuccess(t);
            }
        });
protected abstract void onSuccess(T t);

所以现在就实现了我们一开始的效果

new RetrofitUtils(LoginAPI.class) {
    @Override
    protected void onSuccess(com.alibaba.fastjson.JSONObject jsonObject) {

    }
};

下面给出所有代码

RetrofitUtils

package com.example.test;
import android.mtp.MtpConstants;
import android.support.annotation.Nullable;
import android.util.Log;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.Scheduler;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public abstract class RetrofitUtils {
    public RetrofitUtils(Class clx, Object...args) {
        try {
            test(clx, args);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // TODO: 2018/1/23 这是假定这个接口只包含一个方法的创建过程,可以弄一个String nullable
    public void test(Class clx, Object...args) throws Exception{
        Field field = clx.getDeclaredFields()[0];
        String baseUrl = field.get(null).toString();

        Object obj = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(clx);

        Method method = clx.getDeclaredMethods()[0];
        Observable obs = (Observable) method.invoke(obj, args);

        obs.subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.i("xbh", "这个Log在RetrofitUtils,错误信息是:" +e.getMessage());
                    }

                    @Override
                    public void onNext(T t) {
                        onSuccess(t);
                    }
                });
    }

    protected abstract void onSuccess(T t);
}

API

public interface LoginAPI {
    String baseUrl = "https://news-at.zhihu.com/";

    @GET("api/4/news/latest")
    Observable login();
}

调用

new RetrofitUtils(LoginAPI.class) {
    @Override
    protected void onSuccess(com.alibaba.fastjson.JSONObject jsonObject) {

    }
};

需要的gradle和权限

gradle
compile 'io.reactivex:rxjava:1.2.0'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
权限

就OK了,这个是知乎日报的API,大家可以自己去试试这个数据的请求,亲测有效。