装逼開始之前,为大家推荐两篇文章,用来更好的学习Retrofit和Rxjava。

在这里我们要感谢互联网装逼行业勇于献身,甘于奉献的的大婶们。

我仅代表个人,给您们跪舔了。

Retrofit:Retrofit官网

Rxjava:
Android 开发人员的 RxJava 具体解释

---------------这是切割线---------------

首先配置支持的gradle文件:

    compile 'io.reactivex:rxjava:1.1.3'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.retrofit2:retrofit:2.0.1'
compile 'com.squareup.retrofit2:converter-gson:2.0.1'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.1'

截止至本文发表前。上述支持库都是最新版本号。

贴出Retrofit官网的GET请求演示样例:GitHubService接口

public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}

网络请求部分代码为:

        String baseUrl = "https://*******";

        Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build(); GitHubService service = retrofit.create(GitHubService.class);
Call<List<XXXEntity>> repos = service.listRepos("octocat");
repos.enqueue(new Callback<XXXEntity>() {
@Override
public void onResponse(Call<XXXEntity> call, Response<XXXEntity> response) {
Log.i("onResponse",response.body().toString());
} @Override
public void onFailure(Call<XXXEntity> call, Throwable t) {
Log.i("onResponse",t.getMessage());
}
});

baseUrl 为网络请求地址

addConverterFactory(GsonConverterFactory.create())为设置json解析方式为Gson。

retrofit.create採用动态代理的方式获取GitHubService对象,并通过Callback获取返回的数据。

---------------当Retrofit与Rxjava相遇----------------

Retrofit.Builder须要调用

.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

方法,表示用Rxjava做回调。即Rxjava所讲的观察者模式。那么网络请求接口就须要改成例如以下方式:

Observable<List<Repo>> listRepos(@Path("user") String user);

网络请求部分的代码则更改为:

        String baseUrl = "https://*******";

        Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build(); service.listRepos("octocat")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<XXXEntity>() {
@Override
public void onCompleted() {
Log.i("onCompleted","onCompleted");
} @Override
public void onError(Throwable e) {
Log.i("onError",e.toString());
} @Override
public void onNext(XXXEntity movieEntity) {
Log.i("onCompleted",movieEntity.toString());
}
});

假设细致阅读过上述两篇文章,不难理解这部分代码的含义。因为篇幅原因。这里就不在反复了。

当然如此这般的结合,无法满足对代码有深度洁癖的骚年们。接下来。在此基础上,对代码做总体的封装。

项目文件夹结构例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" align="middle" alt="" style="line-height:15.7px">

首先封装网络请求类HTTPHelper.java

    /**
* 这一部分配置常量,能够抽取出常量类
*/
private static final String BASE_PATH = "http://www.weather.com.cn/";//訪问的地址
private static final long DEFAULT_TIMEOUT = 5000;//默认超时时间(毫秒) private Retrofit mRetrofit;
private INetService mNetService; private HTTPHelper(){
OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder();
okHttpClient.addInterceptor(new HTTPInterceptor());
okHttpClient.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
mRetrofit = new Retrofit.Builder()
.client(okHttpClient.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(BASE_PATH)
.build(); mNetService = mRetrofit.create(INetService.class); } /**
* 单例控制器
*/
private static class SingletonHolder{
private static final HTTPHelper INSTANCE = new HTTPHelper();
} /**
* 获取单例对象
* @return
*/
public static HTTPHelper getInstance(){
return SingletonHolder.INSTANCE;
}

我们须要将网络请求回来的字符串转换成javaBean对象,所以引入Rxjava的map转换机制。

代码例如以下:

    private class HttpResultFunc<T> implements Func1<IModel, T> {
@Override
public T call(IModel iModel) {
if (iModel == null){
try {
throw new Exception("result model is null");
} catch (Exception e) {
e.printStackTrace();
}
}
return (T)iModel;
}
}

到此。配置阶段结束,以下将是Rxjava的异步订阅请求网络并返回操作。

为了方便Activity、Fragment等界面处理数据。封装Subscriber接口:

package demo.myframework.common;

import rx.Subscriber;

/**
* @Author: lizhipeng
* @Data: 16/4/12 下午4:17
* @Description: 自己定义调阅者以及结果监听接口
*/
public class ResultSubscriber<T> extends Subscriber<T> {
private int mRequestType;
private OnResultListener<T> mListener = null; /**
* 自己定义订阅。參数用来区分网络接口。以用来在不同接口操作过程中。处理不同的逻辑
* @param requestType
*/
public ResultSubscriber(int requestType) {
this.mRequestType = requestType;
mListener = new OnResultListener<T>() {
@Override
public void onStart(int requestType) {
}
@Override
public void onCompleted(int requestType) {
}
@Override
public void onError(Throwable e, int requestType) {
}
@Override
public void onNext(T t, int requestType) {
}
};
} @Override
public void onStart() {
mListener.onStart(mRequestType);
} @Override
public void onCompleted() {
mListener.onCompleted(mRequestType);
} @Override
public void onError(Throwable e) {
if (e != null){
mListener.onError(e,mRequestType);
}
} @Override
public void onNext(T t) {
mListener.onNext(t,mRequestType);
} /**
* 设置订阅监听器
* @param listener
*/
public void setOnResultListener(OnResultListener listener){
if (listener != null){
mListener = listener;
}
} /**
* 订阅的监听器
* @param <T>
*/
public interface OnResultListener<T> {
/**
* 网络请求订阅開始
*/
void onStart(int requestType);
/**
* 网络请求完毕
*/
void onCompleted(int requestType);
/**
* 网络请求错误
*/
void onError(Throwable e,int requestType);
/**
* 处理请求结果
*/
void onNext(T t,int requestType);
}
}

已天气訪问为例网络请求接口为:

package demo.myframework.interfaces;

import demo.myframework.model.WeatherModel;
import retrofit2.http.GET;
import retrofit2.http.Path;
import rx.Observable; /**
* @Author: lizhipeng
* @Data: 16/4/12 下午2:57
* @Description: 网络请求接口
*/
public interface INetService {
@GET("data/cityinfo/{city_id}.html")
Observable<WeatherModel> getWeather(@Path("city_id") String city);
}

HTTPHelper.java 中 网络请求数据方法的实现为:

    /**
* 获取网络数据的方法
* @param cityId
*/
public void getWeather(String cityId, int resultType, ResultSubscriber.OnResultListener listener){
ResultSubscriber<IModel> subscriber = new ResultSubscriber<>(resultType);
subscriber.setOnResultListener(listener);
mNetService.getWeather(cityId)
.map(new HttpResultFunc<WeatherModel>())
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
}

MainActivity实现OnResultListener接口。点击button调用方法为

       HTTPHelper.getInstance().getWeather("101010300",CODE,MainActivity.this);

一下是activity的所有代码:

package demo.myframework.activity;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; import demo.myframework.R;
import demo.myframework.common.ResultSubscriber;
import demo.myframework.http.HTTPHelper;
import demo.myframework.model.IModel;
import demo.myframework.model.WeatherModel; public class MainActivity extends AppCompatActivity implements ResultSubscriber.OnResultListener<IModel>{
private static final String TAG = "MainActivity";
private static final int CODE = 1; private Button mButton;
private TextView mTextView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initView();
initData();
} private void initData() {
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i(TAG,"onClick");
HTTPHelper.getInstance().getWeather("101010300",CODE,MainActivity.this);
}
});
} private void initView() {
mButton = (Button) findViewById(R.id.button);
mTextView = (TextView) findViewById(R.id.textview);
} private void setResultSubscriber(){ } /**
* 网络请求前调用,通常显示Progressialog
* @param requestType
*/
@Override
public void onStart(int requestType) {
Log.i(TAG,"onStart");
} /**
* 网络请求完毕调用,通常销毁Progressialog
* @param requestType
*/
@Override
public void onCompleted(int requestType) {
Log.i(TAG,"onCompleted");
} /**
* 网络请求错误后调用
* @param e
* @param requestType
*/
@Override
public void onError(Throwable e, int requestType) {
Log.i(TAG,"onError");
} /**
* onNext 方法中处理请求下来的数据
* @param iModel
* @param requestType
*/
@Override
public void onNext(IModel iModel, int requestType) {
Log.i(TAG,"onNext");
if (requestType == CODE){
mTextView.setText(((WeatherModel)iModel).getWeatherinfo().toString());
}
}
}

另为了方便測试联调,实现OKhttp的过滤接口。一下代码分别为过滤器和javaBean的实现:

HTTPInterceptor.java

package demo.myframework.http;

import android.util.Log;

import java.io.IOException;

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response; /**
* @Author: lizhipeng
* @Data: 16/4/12 下午5:19
* @Description: 定义http拦截器,用于设置http协议和日志调试
*/
public class HTTPInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
//封装headers
Request request = chain.request().newBuilder()
.addHeader("Content-Type", "application/json") //加入请求头信息
.build();
// Headers headers = request.headers();
String requestUrl = request.url().toString(); //获取请求url地址
String methodStr = request.method(); //获取请求方式
RequestBody body = request.body(); //获取请求body
String bodyStr = (body==null?"":body.toString());
//打印Request数据
Log.i("HTTP-Interceptor","requestUrl=====>"+requestUrl);
Log.i("HTTP-Interceptor","requestMethod=====>"+methodStr);
Log.i("HTTP-Interceptor","requestBody=====>"+body); Response response = chain.proceed(request);
return response;
}
}

WeatherModel.java

package demo.myframework.model;

/**
* @Author: lizhipeng
* @Data: 16/4/12 下午3:16
* @Description: 天气信息模板
*/
public class WeatherModel implements IModel{ /**
* city : 朝阳
* cityid : 101010300
* temp1 : -2℃
* temp2 : 16℃
* weather : 晴
* img1 : d0.gif
* img2 : n0.gif
* ptime : 18:00
*/ private WeatherinfoBean weatherinfo; public WeatherinfoBean getWeatherinfo() {
return weatherinfo;
} public void setWeatherinfo(WeatherinfoBean weatherinfo) {
this.weatherinfo = weatherinfo;
} public static class WeatherinfoBean {
private String city;
private String cityid;
private String temp1;
private String temp2;
private String weather;
private String img1;
private String img2;
private String ptime; public String getCity() {
return city;
} public void setCity(String city) {
this.city = city;
} public String getCityid() {
return cityid;
} public void setCityid(String cityid) {
this.cityid = cityid;
} public String getTemp1() {
return temp1;
} public void setTemp1(String temp1) {
this.temp1 = temp1;
} public String getTemp2() {
return temp2;
} public void setTemp2(String temp2) {
this.temp2 = temp2;
} public String getWeather() {
return weather;
} public void setWeather(String weather) {
this.weather = weather;
} public String getImg1() {
return img1;
} public void setImg1(String img1) {
this.img1 = img1;
} public String getImg2() {
return img2;
} public void setImg2(String img2) {
this.img2 = img2;
} public String getPtime() {
return ptime;
} public void setPtime(String ptime) {
this.ptime = ptime;
} @Override
public String toString() {
return "WeatherinfoBean{" +
"city='" + city + '\'' +
", cityid='" + cityid + '\'' +
", temp1='" + temp1 + '\'' +
", temp2='" + temp2 + '\'' +
", weather='" + weather + '\'' +
", img1='" + img1 + '\'' +
", img2='" + img2 + '\'' +
", ptime='" + ptime + '\'' +
'}';
}
} }

凝视已经在代码中具体说明,就不做太多解释了。着重说一点。ResultSubscriber.java中的mRequestType是用来在连续多次请求网络接口时。须要在界面中做不同的处理而区分的属性。使用时,最好也为每一个接口配置为相应的唯一值。

附上GitHub地址,https://github.com/QiYuan007/EasyFrame 假设本文对你有帮助,多多start。

假设你有更好的实现方式,请与我联系。

Android 基于Retrofit+Rxjava搭建的简单易用的网络架构的更多相关文章

  1. 基于Retrofit+RxJava的Android分层网络请求框架

    目前已经有不少Android客户端在使用Retrofit+RxJava实现网络请求了,相比于xUtils,Volley等网络访问框架,其具有网络访问效率高(基于OkHttp).内存占用少.代码量小以及 ...

  2. 基于RxJava2+Retrofit2简单易用的网络请求实现

    代码地址如下:http://www.demodashi.com/demo/13473.html 简介 基于RxJava2+Retrofit2实现简单易用的网络请求,结合android平台特性的网络封装 ...

  3. Android 基于ijkplayer+Rxjava+Rxandroid+Retrofit2.0+MVP+Material Design的android万能播放器aaa

    MDPlayer万能播放器 MDPlayer,基于ijkplayer+Rxjava+Rxandroid+Retrofit2.0+MVP+Material Design的android万能播放器,可以播 ...

  4. Android中NDK的搭建及简单使用 Android.mk相关介绍 JNI的使用

    Android中NDK的搭建及简单使用: 使用NDK,简述其重要步骤:.搭建NDK环境(作用:用于自动生成jni下的.c对应的so文件)---到Android NDK官网或Android官网下载ndk ...

  5. Android MVP+Retrofit+RxJava实践小结

    关于MVP.Retrofit.RxJava,之前已经分别做了分享,如果您还没有阅读过,可以猛戳: 1.Android MVP 实例 2.Android Retrofit 2.0使用 3.RxJava ...

  6. Node.js基于Express框架搭建一个简单的注册登录Web功能

    这个小应用使用到了node.js  bootstrap  express  以及数据库的操作 :使用mongoose对象模型来操作 mongodb 如果没了解过的可以先去基本了解一下相关概念~ 首先注 ...

  7. 基于SpringBoot+WebSocket搭建一个简单的多人聊天系统

    前言   今天闲来无事,就来了解一下WebSocket协议.来简单了解一下吧. WebSocket是什么   首先了解一下WebSocket是什么?WebSocket是一种在单个TCP连接上进行全双工 ...

  8. Android Retrofit+RxJava 优雅的处理服务器返回异常、错误

    标签: 开始本博客之前,请先阅读: Retrofit请求数据对错误以及网络异常的处理 异常&错误 实际开发经常有这种情况,比如登录请求,接口返回的 信息包括请求返回的状态:失败还是成功,错误码 ...

  9. Retrofit + RxJava + OkHttp 让网络请求变的简单-基础篇

    https://www.jianshu.com/p/5bc866b9cbb9 最近因为手头上的工作做完了,比较闲,想着做一些优化.看到以前用的那一套网络框架添加一个请求比较麻烦,并且比较难用,所以想改 ...

随机推荐

  1. PAT1021

    给定一个k位整数N = dk-1*10k-1 + ... + d1*101 + d0 (0<=di<=9, i=0,...,k-1, dk-1>0),请编写程序统计每种不同的个位数字 ...

  2. 习题:玛丽卡(SPFA)

    玛丽卡(wikioi1021) [题目描述 ]麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复.因为她和他们不住在同一个城市,因此她开始准备她的长途旅行.在这个国家中每两个城市之间最多只有一条路相通, ...

  3. cf 853 D Michael and Charging Stations [dp]

    题面: 传送门 思路: 看到题目,第一思路是贪心,但是我很快就否决掉了(其实分类贪心也可以做) 然后就想,贪心不能解决的状态缺失,是否可以用dp来解决呢? 事实证明是可以的 我们设dp[i][j]表示 ...

  4. 转载:LeetCode:5Longest Palindromic Substring 最长回文子串

    本文转自:http://www.cnblogs.com/TenosDoIt/p/3675788.html 题目链接 Given a string S, find the longest palindr ...

  5. 【01】iconfont的使用

    我之前因为项目用bootstrap比较多,所以使用font awesome字体图标比较多,后来接触到了iconfont,发现想要的什么图标都有,还可以自定义图标,非常强大!之前看了一波教程,觉得繁琐, ...

  6. Bzoj1974 [Sdoi2010]auction 代码拍卖会

    Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 375  Solved: 151 Description 随着iPig在P++语言上的造诣日益提升,他形成 ...

  7. HDU3001 Travelling

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  8. POJ 2891

    Strange Way to Express Integers Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 19509 ...

  9. 一个简单有效的兼容IE7浏览器的办法

    最近发现了一个简单有效的兼容IE7浏览器的办法 直接将下面代码复制道页面 <meta http-equiv="X-UA-Compatible" content="I ...

  10. jQuery动态创建form表单并提交到后台(携带一定的数据进行页面跳转)

    今天遇到这么一个需求,携带一个编号一个名字跳转到另一个JSP页面,直接页面跳转(get携带数据)的话不太安全,于是想到到后台转发一下. 第一种:直接以表单提交方式的进行 JS代码: var form ...