Rxjava+Retrofit简单封装

介绍了一个封装的网络请求库RxNetWork,简化了Android项目中的网络请求流程,支持自定义异常处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近公司小项目比较多,但是再小的项目里我们都要用到网络请求,所以每次创建新项目的时候都需要导入一些自己用的很顺畅的网络请求框架。比如我这样的,

文件太多就算是CV大法估计也比较麻烦,而且还要改包名啊,里面一些dialog的布局啊、主题啊、颜色、字体什么的一大堆比较繁琐的东西,感觉这就是在浪费时间浪费青春有木有。

作为一个合格的猿类,能写一行代码绝对不会写两行,所以我们必须要精简,要效率,所以还不如把这个请求在封装一下干脆弄一个依赖包得了,首先扩展性一定要好,该有的功能也不能少,然后就有了下面的RxNetWork

GitHub传送门

用法非常简单,在Module下build.gradle添加依赖

compile 'com.github.hahawaa1:RxNetWork:v1.0.3'

为了防止rxjava冲突还需在android{}下面添加

    packagingOptions {
        exclude 'META-INF/rxjava.properties'
    }

然后在project根目录的build.gradle下面的repositories{}里面添加

 maven { url 'https://jitpack.io' }

这样就完成了。

下面是完整代码

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.zy.factory"
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    packagingOptions {
        exclude 'META-INF/rxjava.properties'
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    

    compile 'com.github.hahawaa1:RxNetWork:v1.0.3'
}

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext.kotlin_version = '1.1.61'
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url 'https://jitpack.io' }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

接下来是使用环节;

我们需要在Application的onCreate方法里面初始化一下


一个参数:是否显示异常提示,true为显示,false为不显示;

两个参数:msg为异常提示自定义信息,默认提示为"操作失败,数据异常"



当设置为true时异常提示为Toast,false为Dialog,默认为Dialog


初始化网络请求,第一个参数上下文,第二个参数URL,第三个参数接Api接口,第四个参数为true时表示使用系统异常提示,当为false时使用我自定义的异常管理类,后面在细说,这样一来就就初始化好了,下面是完整代码

class App : Application() {

    override fun onCreate() {
        super.onCreate()
        mContext = this
        //初始化通用的SP&EDIT
        SP = getSharedPreferences("config", Context.MODE_PRIVATE)
        EDIT = SP?.edit()

        //第一个参数上下文,第二个url,第三个自定义接口,第四个参数,是否使用自定义异常管理
        instance = RetrofitClient.getInstance(this, ApiService.BASE_URL, ApiService::class.java,true).mApi
        
        //是否Toast异常显示 true为显示 false为不现实
        ApiErrorHelper.hint2show(true)
        
        //true为Toast false为dialog,默认为dialog
        ApiErrorHelper.dialog2Toast(true)

    }

    companion object {
        var mContext: Context? = null
        /**
         * 初始化SP&EDIT
         */
        var SP: SharedPreferences? = null
        var EDIT: SharedPreferences.Editor? = null
        var instance : ApiService? = null
    }
}

下面是ApiService接口类

interface ApiService {
    //http://api.douban.com/v2/movie/top250 现在用的是豆瓣top250的电影接口来测试
    //当RetrofitClient初始化的时候第四个参数为true的时候BaseResponseEntity自定义
    companion object{
        val BASE_URL : String
            get() = "http://api.douban.com"
    }
    
    @GET("/v2/movie/top250")
    fun getTop(): Observable<BaseResponseEntity<List<Top>>>

}

下面是BaseResponseEntity类

/**
 *  可以根据自己接口的返回值来定义成员变量
 */
public class BaseResponseEntity<T>  {
    
    public int count;
    public int start;
    public int code;
    public int total;
    public String title;
    public String message;
    public T subjects;
    public T data;
}

下面是Top类

public class Top {

    private RatingBean rating;
    private String title;
    private int collect_count;
    private String original_title;
    private String subtype;
    private String year;
    private ImagesBean images;
    private String alt;
    private String id;
    private List<String> genres;
    private List<CastsBean> casts;
    private List<DirectorsBean> directors;

    public RatingBean getRating() {
        return rating;
    }

    public void setRating(RatingBean rating) {
        this.rating = rating;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getCollect_count() {
        return collect_count;
    }

    public void setCollect_count(int collect_count) {
        this.collect_count = collect_count;
    }

    public String getOriginal_title() {
        return original_title;
    }

    public void setOriginal_title(String original_title) {
        this.original_title = original_title;
    }

    public String getSubtype() {
        return subtype;
    }

    public void setSubtype(String subtype) {
        this.subtype = subtype;
    }

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }

    public ImagesBean getImages() {
        return images;
    }

    public void setImages(ImagesBean images) {
        this.images = images;
    }

    public String getAlt() {
        return alt;
    }

    public void setAlt(String alt) {
        this.alt = alt;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public List<String> getGenres() {
        return genres;
    }

    public void setGenres(List<String> genres) {
        this.genres = genres;
    }

    public List<CastsBean> getCasts() {
        return casts;
    }

    public void setCasts(List<CastsBean> casts) {
        this.casts = casts;
    }

    public List<DirectorsBean> getDirectors() {
        return directors;
    }

    public void setDirectors(List<DirectorsBean> directors) {
        this.directors = directors;
    }

    public static class RatingBean {
        /**
         * max : 10
         * average : 9.6
         * stars : 50
         * min : 0
         */

        private int max;
        private double average;
        private String stars;
        private int min;

        public int getMax() {
            return max;
        }

        public void setMax(int max) {
            this.max = max;
        }

        public double getAverage() {
            return average;
        }

        public void setAverage(double average) {
            this.average = average;
        }

        public String getStars() {
            return stars;
        }

        public void setStars(String stars) {
            this.stars = stars;
        }

        public int getMin() {
            return min;
        }

        public void setMin(int min) {
            this.min = min;
        }
    }

    public static class ImagesBean {
        /**
         * small : http://img7.doubanio.com/view/movie_poster_cover/ipst/public/p480747492.webp
         * large : http://img7.doubanio.com/view/movie_poster_cover/lpst/public/p480747492.webp
         * medium : http://img7.doubanio.com/view/movie_poster_cover/spst/public/p480747492.webp
         */

        private String small;
        private String large;
        private String medium;

        public String getSmall() {
            return small;
        }

        public void setSmall(String small) {
            this.small = small;
        }

        public String getLarge() {
            return large;
        }

        public void setLarge(String large) {
            this.large = large;
        }

        public String getMedium() {
            return medium;
        }

        public void setMedium(String medium) {
            this.medium = medium;
        }
    }

    public static class CastsBean {
        /**
         * alt : https://movie.douban.com/celebrity/1054521/
         * avatars : {"small":"http://img7.doubanio.com/img/celebrity/small/17525.jpg","large":"http://img7.doubanio.com/img/celebrity/large/17525.jpg","medium":"http://img7.doubanio.com/img/celebrity/medium/17525.jpg"}
         * name : 蒂姆·罗宾斯
         * id : 1054521
         */

        private String alt;
        private AvatarsBean avatars;
        private String name;
        private String id;

        public String getAlt() {
            return alt;
        }

        public void setAlt(String alt) {
            this.alt = alt;
        }

        public AvatarsBean getAvatars() {
            return avatars;
        }

        public void setAvatars(AvatarsBean avatars) {
            this.avatars = avatars;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public static class AvatarsBean {
            /**
             * small : http://img7.doubanio.com/img/celebrity/small/17525.jpg
             * large : http://img7.doubanio.com/img/celebrity/large/17525.jpg
             * medium : http://img7.doubanio.com/img/celebrity/medium/17525.jpg
             */

            private String small;
            private String large;
            private String medium;

            public String getSmall() {
                return small;
            }

            public void setSmall(String small) {
                this.small = small;
            }

            public String getLarge() {
                return large;
            }

            public void setLarge(String large) {
                this.large = large;
            }

            public String getMedium() {
                return medium;
            }

            public void setMedium(String medium) {
                this.medium = medium;
            }
        }
    }

    public static class DirectorsBean {
        /**
         * alt : https://movie.douban.com/celebrity/1047973/
         * avatars : {"small":"http://img7.doubanio.com/img/celebrity/small/230.jpg","large":"http://img7.doubanio.com/img/celebrity/large/230.jpg","medium":"http://img7.doubanio.com/img/celebrity/medium/230.jpg"}
         * name : 弗兰克·德拉邦特
         * id : 1047973
         */

        private String alt;
        private AvatarsBeanX avatars;
        private String name;
        private String id;

        public String getAlt() {
            return alt;
        }

        public void setAlt(String alt) {
            this.alt = alt;
        }

        public AvatarsBeanX getAvatars() {
            return avatars;
        }

        public void setAvatars(AvatarsBeanX avatars) {
            this.avatars = avatars;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public static class AvatarsBeanX {
            /**
             * small : http://img7.doubanio.com/img/celebrity/small/230.jpg
             * large : http://img7.doubanio.com/img/celebrity/large/230.jpg
             * medium : http://img7.doubanio.com/img/celebrity/medium/230.jpg
             */

            private String small;
            private String large;
            private String medium;

            public String getSmall() {
                return small;
            }

            public void setSmall(String small) {
                this.small = small;
            }

            public String getLarge() {
                return large;
            }

            public void setLarge(String large) {
                this.large = large;
            }

            public String getMedium() {
                return medium;
            }

            public void setMedium(String medium) {
                this.medium = medium;
            }
        }
    }

}


下面是网络请求使用方法:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mRecycler.layoutManager = LinearLayoutManager(this)
        network()

    }


    private var mCompositeSubscription : CompositeSubscription? = null

    fun network(){
        mCompositeSubscription = CompositeSubscription()
        //HttpObserver<BaseResponseEntity<List<Top>>>(this,true)当为true的时候显示加载dialog,false则不显示
        mCompositeSubscription?.add(App.instance?.getTop()?.applySchedulers()?.subscribe(object : HttpObserver<BaseResponseEntity<List<Top>>>(this,true){

            override fun success(t:BaseResponseEntity<List<Top>>) {

                mRecycler.adapter = (object : CommonAdapter<Top>(this@MainActivity, R.layout.item_list,t.subjects) {
                    override fun convert(holder: ViewHolder?, t: Top?, position: Int) {
                        holder?.setText(R.id.name,t?.title)
                        holder?.setText(R.id.year,t?.year)
                    }
                })
            }
        }))
    }

    override fun onDestroy() {
        super.onDestroy()
        if (mCompositeSubscription!!.hasSubscriptions()) {
            mCompositeSubscription?.unsubscribe()
        }
    }
}

下面是一些效果图:

网络请求加载中dialog

Toast


Dialog



下面具体讲一下自定义异常管理

如果你项目返回的数据格式如下
public class BaseResponseEntity<T>  {

    public int count;
    public int start;
    public int code;
    public int total;
    public String title;
    public String message;
    public T subjects;
    public T data;
}

当code == 200的时候请求成功
不等于200的错误信息为message字段的时候那么就可以使用了
demo如下
{
    "code": "200",
    "data": [
        {
            "id": "2",
            "date": "2017-11-12",
            "agent_id": "4",
        }
    ]
}

或者data字段 = subjects字段 都可以
满足以上条件的话第四个参数就可以设置为false了

当code!=200的时候那么错误提示将为message返回的字段
如果想自己自定义的话 添加依赖库 fnetwork
找到 MyGsonResponseBodyConverter这个类在里面修改一个注式的参数就行了
public class MyGsonResponseBodyConverter<T> implements Converter<ResponseBody,T> {
    private static final Charset UTF_8 = Charset.forName("UTF-8");
    private final Gson mGson;
    private final TypeAdapter<T> adapter;

    public MyGsonResponseBodyConverter(Gson mGson, TypeAdapter<T> adapter) {
        this.mGson = mGson;
        this.adapter = adapter;
    }

    @Override
    public T convert(ResponseBody value) throws IOException {
        String response = value.string();
        //BaseResponseEntity 替换成自己定义的类
        BaseResponseEntity result = mGson.fromJson(response, BaseResponseEntity.class);
//        返回值判断改为自己接口定义的参数
        if (result.code != 200) {
            value.close();
            //第一个参数code码第二个参数异常提示信息
            throw new ApiException(result.code, result.message);
        }

        MediaType mediaType = value.contentType();
        Charset charset = mediaType != null ? mediaType.charset(UTF_8) : UTF_8;
        ByteArrayInputStream bis = new ByteArrayInputStream(response.getBytes());
        InputStreamReader reader = new InputStreamReader(bis,charset);
        JsonReader jsonReader = mGson.newJsonReader(reader);
        try {
            return adapter.read(jsonReader);
        } finally {
            value.close();
        }
    }
}

目前功能就这么多了,以后再慢慢完善吧!有好的建议欢迎大家提出来,一起进步


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值