Retrofit2.0+RxJava+Dragger2实现不一样的Android网络架构搭建
Tamic :csdn
http://blog.csdn.net/sk719887916
众所周知,手机APP的核心就在于调用后台接口,展示相关信息,方便我们在手机上就能和外界交互。所以APP中网络框架的搭建一直是我们开发者所关心的问题,在Android中关于如何搭建网络框架分为两种:一种是不想重复造轮子使用第三方开源的网络框架;第二种就是喜欢造轮子的封装自己的网络框架。
自己封装实现网络框架这种行为固然不错,但是这需要自身具备比较高的能力,而很多时候我们没有那样的能力把它封装的足够好。这时我们使用开源的网络框架也未尝不是一件好事,github上面知名的网络框架已经经过了很多app的验证,在一定意义上是非常符合我们在实际的项目开发所需要的。
Android开发中几个知名的开源的网络框架有android-async-http,Volley,OkHttp等,国人 开发的xUtils快速开发框架也比较流行。android-async-http是个很老牌的网络框架,非常的经典。Volley官方推荐的,自不必说。OkHttp可以说是后起之秀,现在非常流行,Android系统底层api都有用到,所以是非常niubility.
我们很多开发者大都在小型公司,不了解大公司是怎么做Android网络框架的,也想知道那些用户量过千万的APP到底用了些什么技术,下面有两张图片,让我们一起来了解一下Android版的美团和Uber到底用了些什么技术。
Uber
美团
看完你会发现其实这些用户量过亿的APP也使用了很多的开源框架,而且这些开源框架中大多数其实都是我们平常在开发中所常用到的,并不陌生。可能大多数人对Retrofit,Rxjava这些还不太熟悉,那话不多说,今天我们就来讲讲怎么用Retrofit2.0+RxJava+Dragger2来实现Android网络构架搭建,给大家提供一种思路,供大家参考参考。
- Retrofit2.0 GitHub:https://github.com/square/retrofit
Square开发的类型安全的REST安卓客户端请求库,网络请求默认使用的是OkHttp,具体介绍请看相关教程。
- RxJava +RxAndroid GitHub地址: https://github.com/ReactiveX/RxJava
RxJava是一种响应式编程框架,采用观察者设计模式。最核心的是Observables(被观察者,事件源)和Subscribers(观察者)这两个东西,RxAndroid是Rxjava在Android上的实现。
Dragger2
- 是一种依赖注入框架,可以大大节省我们的代码量,便于维护。
在这里我就不费过多笔墨来介绍着三个东西了,今天的主题是提供一种如何搭建一个不一样的网络框架的思路。如果读者对这三个框架不是很了解的话,可以自行的Google脑补一下。
首先,就是开始把这些框架引入到咱们的项目中来作为依赖库,在app/build.gradle文件中添加
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.finddreams.retrofit"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard- rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
//retrofit
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
//gson解析
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
//rxjava
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
//dragger2
provided 'org.glassfish:javax.annotation:10.0-b28'
apt 'com.google.dagger:dagger-compiler:2.0.2'
compile 'com.google.dagger:dagger:2.0.2'
}
因为Dragger2是基于注解的,它会预先生成一些类文件,所以需要在整个项目的/build.gradle文件中加上apt工具:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0-beta6'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
接着开始写一个提供Retrofit的单例类:
/**
* Retrofit的实体类
*/
public class RestApiAdapter {
private static Retrofit retrofit = null;
public static Retrofit getInstance() {
if (retrofit == null) {
GsonConverterFactory gsonConverterFactory = GsonConverterFactory.create();
OkHttpClient okHttpClient = new OkHttpClient();
OkHttpClient.Builder builder = okHttpClient.newBuilder();
builder.retryOnConnectionFailure(true);
retrofit = new Retrofit.Builder().client(okHttpClient)
.baseUrl(ConstantApi.BaiduUrl)
.addConverterFactory(gsonConverterFactory)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
return retrofit;
}
}
addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 这个方法就是RxJava和Retrofit结合的关键。
接着我们为Retrofit 提供一个service接口,声明api接口地址和所需要的参数,这里我们使用百度API提供的天气接口,实现根据城市名称查询天气的功能,接口地址:http://apistore.baidu.com/apiworks/servicedetail/112.html 代码如下:
` /**
* 天气接口Api
*/
public interface WeatherApiService {
/**
* 查询天气
*/
@GET("apistore/weatherservice/cityname")
Observable<WeatherResultBean> queryWeather(@Header("apikey") String apikey, @Query("cityname") String cityname);
}`
返回一个Observable被观察者/事件源的意思是交给RxJava来处理。 然后我们写一个BaseSubsribe观察者来管理网络请求开始结束,成功与失败:
public abstract class BaseSubsribe<T> extends Subscriber<T> {
private static final String TAG = "BaseSubsribe";
@Override
public void onStart() {
super.onStart();
Log.i(TAG, "onStart");
}
@Override
public void onNext(T t) {
Log.i(TAG, "response" + t.toString());
onSuccess(t);
}
@Override
public void onCompleted() {
Log.i(TAG, "onCompleted");
}
public abstract void onSuccess(T result);
@Override
public void onError(Throwable e) {
e.printStackTrace();
Log.i(TAG, "onError" + e.getMessage());
}
}
接着我们写一个WeatherInteractor接口连接service类:
public interface WeatherInteractor {
Subscription queryWeather(String apikey, String cityname, BaseSubsribe<WeatherResultBean> subsribe);
}
然后是这个接口的实现类:
public class WeatherInteractorImpl implements WeatherInteractor {
private final WeatherApiService api;
@Inject
public WeatherInteractorImpl(WeatherApiService myApi) {
this.api = myApi;
}
@Override
public Subscription queryWeather(String apikey, String cityname, BaseSubsribe<WeatherResultBean> subsribe) {
Observable<WeatherResultBean> observable = api.queryWeather(apikey, cityname);
Subscription subscribe = observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(subsribe);
return subscribe;
}
}
接下来是如何使用Dragger2的时候,知道Dragger2的都知道有几个概念,一个是Module:主要提供依赖对象比如context, rest api …; 一个是@inject:注解,用在需要依赖对象的地方;另一个是Componet:用来连接Module和@inject
首先定义一个Module类,提供需要注入依赖的对象: Module类
@Module
public class InteractorModule {
@Provides
public Retrofit provideRestAdapter() {
return RestApiAdapter.getInstance();
}
@Provides
public WeatherApiService provideHomeApi(Retrofit restAdapter) {
return restAdapter.create(WeatherApiService.class);
}
@Provides
public WeatherInteractor provideHomeInteractor(WeatherApiService myApi) {
return new WeatherInteractorImpl(myApi);
}
}
接着是写一个Componet类:
/**
* 声明AppComponent组件
*
* @author finddreams
* @address http://blog.csdn.net/finddreams
*/
@Singleton
@Component(
modules = {
InteractorModule.class,
}
)
public interface AppComponent {
void inject(App app);
WeatherInteractor getWeatherInteractor();
}
然后我们在Application中初始化这个AppComponent:
/**
* Application类
*
* @author finddreams
* @address http://blog.csdn.net/finddreams
*/
public class App extends Application {
private AppComponent component;
@Override
public void onCreate() {
super.onCreate();
setDraggerConfig();
}
public AppComponent component() {
return component;
}
public static App get(Context context) {
return (App) context.getApplicationContext();
}
/**
* 初始化Dragger,DaggerAppComponent是自动生成,需要Rebuild
*/
private void setDraggerConfig() {
component = DaggerAppComponent.builder().interactorModule(new InteractorModule())
.build();
component.inject(this);
}
}
这里需要注意的是,由于Dagger2是预编译生成一个类,所以我们需要Rebuild项目,才会生成DaggerAppComponent这个类。如果开发中出现
import com.finddreams.retrofit.api.config.DaggerAppComponent;
找不到这个类的错误
这时就需要重新的Rebuild项目
这是Rebuild项目之后生成的class文件,如图:
最后我们就可以在Activity中开始使用了:
/**
* 主页
*
* @author finddreams
* @address http://blog.csdn.net/finddreams
*/
public class MainActivity extends AppCompatActivity {
private AppComponent component;
private WeatherInteractor weatherInteractor;
private EditText city;
private TextView queryresult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
city = (EditText) findViewById(R.id.city);
queryresult = (TextView) findViewById(R.id.queryresult);
//获取到AppComponent组件
component = App.get(this).component();
//通过AppComponent拿到WeatherInteractor
weatherInteractor = component.getWeatherInteractor();
findViewById(R.id.query).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
queryWeatherData();
}
});
}
public void queryWeatherData() {
String content = city.getText().toString();
//调用查询天气接口的方法
Subscription subscription = weatherInteractor.queryWeather(ConstantApi.baiduKey, content, new BaseSubsribe<WeatherResultBean>() {
@Override
public void onSuccess(WeatherResultBean result) {
WeatherResultBean.RetDataEntity retData = result.getRetData();
queryresult.setText(retData.getCity() + ":" + retData.getWeather() + ":" + retData.getDate());
}
@Override
public void onError(Throwable e) {
super.onError(e);
queryresult.setText("查询失败");
}
}
);
//取消请求
//subscription.unsubscribe();
}
}
我们看下项目运行的结果图:
附上源码给有需要的朋友参考一下,比较结合源码才能理解的更透彻,GitHub: https://github.com/finddreams/Retrofit2_Rxjava_Dagger2
原文:finddreams:http://blog.csdn.net/finddreams/article/details/50849385
Retrofit2.0+RxJava+Dragger2实现不一样的Android网络架构搭建的更多相关文章
- 基于Retrofit2.0+RxJava+Dragger2实现不一样的Android网络构架搭建(转载)
转载请注明出处:http://blog.csdn.net/finddreams/article/details/50849385#0-qzone-1-61707-d020d2d2a4e8d1a374a ...
- retrofit2 使用教程 及 Android 网络架构搭建 (原创)
squareup 推出 retrofit2 已经有一段时间了,现在的版本比较稳定,没有什么大坑了.网络上的教程要么太简单,只是个Demo:要么有些落时,要么复用性比较差,所以自己写个教程,供大家参考. ...
- Android基于Retrofit2.0 +RxJava 封装的超好用的RetrofitClient工具类(六)
csdn :码小白 原文地址: http://blog.csdn.net/sk719887916/article/details/51958010 RetrofitClient 基于Retrofit2 ...
- 一个App带你学会Retrofit2.0,麻麻再也不用担心我的网络请求了!
Retrofit.Retrofit.Retrofit,越来越多的人在玩这个网络请求框架,这个由squareup公司开源的网络请求框架确实挺好用,今天我们就来看一下这个东东怎么玩! Retrofit作为 ...
- Retrofit2.0通俗易懂的学习姿势,Retrofit2.0 + OkHttp3 + Gson + RxJava
Retrofit2.0通俗易懂的学习姿势,Retrofit2.0 + OkHttp3 + Gson + RxJava Retrofit,因为其简单与出色的性能,也是受到很多人的青睐,但是他和以往的通信 ...
- Novate 网络库:Retrofit2.0和RxJava的又一次完美改进加强(Tamic博客 -CSDN)
作者/Tamic http://blog.csdn.net/sk719887916/article/details/52195428 前言 用过RxJava和Retrofit的朋友,用久了就会发现Re ...
- Android网络框架之Retrofit + RxJava + OkHttp 变化的时代
1.什么是Retrofit框架? 它是Square公司开发的现在非常流行的网络框架,所以我们在导入它的包的时候都可以看到这个公司的名字,目前的版本是2. 特点: 性能好,处理快,使用简单,Retrof ...
- Android 网络请求Retrofit + RxJava
一.背景 经常看到项目用Retrofit+RxJava+RxAndroid的框架,为了看懂项目的结构.现在来了解一下,Retrofit: Retrofit是Square 公司开发的一款正对Androi ...
- Android 基于ijkplayer+Rxjava+Rxandroid+Retrofit2.0+MVP+Material Design的android万能播放器aaa
MDPlayer万能播放器 MDPlayer,基于ijkplayer+Rxjava+Rxandroid+Retrofit2.0+MVP+Material Design的android万能播放器,可以播 ...
随机推荐
- Spring boot 整合 Mybatis (完整版)
最近工作上时间有点多,然后自己就学习了一下Spring boot,外加上Mybatis,在实际开发中都是比较常用的,所以这篇写一下SpringBoot整合Mybatis. 一.数据准备 CREATE ...
- laydate 日期格式为yyyy 或yyyy-MM时,出现错误Uncaught TypeError: Cannot read property 'length' of undefined
这个改起比较麻烦,没有深究,简单兼容了yyyy 和yyyy-MM,其他格式可能还是会有错误.替换Dates.check方法. //检测日期是否合法 Dates.check = function(){ ...
- C#之序列化对象(二进制方式序列化对象)
应用程序有时需要以对象的形式在磁盘上存储数据,FrameWork有两个可用的实现方式: 一:System.Runtime.Serialization.Formatters.Binarry这个名称空间包 ...
- 一篇文章说透Nginx的rewrite模块
rewrite模块即ngx_http_rewrite_module模块,主要功能是改写请求URI,是Nginx默认安装的模块.rewrite模块会根据PCRE正则匹配重写URI,然后发起内部跳转再匹配 ...
- mv&cp
mv [选项] [源] [目标] 当目标不存在时,重命名源为目标 当目标存在时,若目标为目录文件,将源移动到目标文件里: 若目标为非目录文件,将源重命名为目标,并强制覆盖目标. mv -b 1 2 ...
- 计蒜客NOIP模拟赛(2) D2T1 劫富济贫
[问题描述] 吕弗·普自小从英国长大,受到骑士精神的影响,吕弗·普的梦想便是成为一位劫富济贫的骑士. 吕弗·普拿到了一份全国富豪的名单(不在名单上的都是穷人),上面写着所有富豪的名字以及他们的总资产, ...
- 【BZOJ3573】【HNOI2014】米特运输
Description 米特是D星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为主要能源的D星上,这种米特能源的运输和储存一直是一个大问题. D星上有N个城市,我们将其顺序编号为1到N,1号城市 ...
- 【NOIP2012TG】solution
D1T1(Vigenere) 题意:给你一个原串与一个密码串,问你按照题意规则加密后的密文. 解题思路:暴力模拟. #include <stdio.h> ],c[],u1[],u2[]; ...
- 2015 多校联赛 ——HDU5305(搜索)
Friends Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Su ...
- APIO2017 懵逼记
Day -1: 移步http://www.cnblogs.com/juruolty/p/6854795.html Day 0: CTSC铁牌后,下一个就是APIO了. lmy,sxy,cxc,lh过来 ...