频道栏目
首页 > 程序开发 > 移动开发 > Android > 正文
Android极封:Retrofit2+RxJava网络请求框架
2018-01-23 10:51:30      个评论    来源:qq_36523667的博客  
收藏   我要投稿

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

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,大家可以自己去试试这个数据的请求,亲测有效。

点击复制链接 与好友分享!回本站首页
上一篇:Android_Develop:如何将自定义View里的属性实时传递出来
下一篇:Android IPC机制详情
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站