最近公司小项目比较多,但是再小的项目里我们都要用到网络请求,所以每次创建新项目的时候都需要导入一些自己用的很顺畅的网络请求框架。比如我这样的,
文件太多就算是CV大法估计也比较麻烦,而且还要改包名啊,里面一些dialog的布局啊、主题啊、颜色、字体什么的一大堆比较繁琐的东西,感觉这就是在浪费时间浪费青春有木有。
作为一个合格的猿类,能写一行代码绝对不会写两行,所以我们必须要精简,要效率,所以还不如把这个请求在封装一下干脆弄一个依赖包得了,首先扩展性一定要好,该有的功能也不能少,然后就有了下面的RxNetWork
用法非常简单,在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的时候请求成功
{
"code": "200",
"data": [
{
"id": "2",
"date": "2017-11-12",
"agent_id": "4",
}
]
}
或者data字段 = subjects字段 都可以
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();
}
}
}
目前功能就这么多了,以后再慢慢完善吧!有好的建议欢迎大家提出来,一起进步