转载请注明出处:http://blog.csdn.net/finddreams/article/details/50849385#0-qzone-1-61707-d020d2d2a4e8d1a374a433f596ad1440

 

一起分享,一起进步。finddreams:http://blog.csdn.net/finddreams/article/details/50849385
众所周知,手机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观察者来管理网络请求开始结束,成功与失败:

/**
* 观察者
*
* @author finddreams
* @address http://blog.csdn.net/finddreams
*/
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类:

/**
* 获取天气信息接口
*
* @author finddreams
* @address http://blog.csdn.net/finddreams
*/
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类
* 提供需要注入的类
*
* @author finddreams
* @address http://blog.csdn.net/finddreams
*/
@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

基于Retrofit2.0+RxJava+Dragger2实现不一样的Android网络构架搭建(转载)的更多相关文章

  1. Retrofit2.0+RxJava+Dragger2实现不一样的Android网络架构搭建

    Tamic :csdn http://blog.csdn.net/sk719887916 众所周知,手机APP的核心就在于调用后台接口,展示相关信息,方便我们在手机上就能和外界交互.所以APP中网络框 ...

  2. Android基于Retrofit2.0 +RxJava 封装的超好用的RetrofitClient工具类(六)

    csdn :码小白 原文地址: http://blog.csdn.net/sk719887916/article/details/51958010 RetrofitClient 基于Retrofit2 ...

  3. 一个App带你学会Retrofit2.0,麻麻再也不用担心我的网络请求了!

    Retrofit.Retrofit.Retrofit,越来越多的人在玩这个网络请求框架,这个由squareup公司开源的网络请求框架确实挺好用,今天我们就来看一下这个东东怎么玩! Retrofit作为 ...

  4. retrofit2 使用教程 及 Android 网络架构搭建 (原创)

    squareup 推出 retrofit2 已经有一段时间了,现在的版本比较稳定,没有什么大坑了.网络上的教程要么太简单,只是个Demo:要么有些落时,要么复用性比较差,所以自己写个教程,供大家参考. ...

  5. Novate 网络库:Retrofit2.0和RxJava的又一次完美改进加强(Tamic博客 -CSDN)

    作者/Tamic http://blog.csdn.net/sk719887916/article/details/52195428 前言 用过RxJava和Retrofit的朋友,用久了就会发现Re ...

  6. Retrofit2.0通俗易懂的学习姿势,Retrofit2.0 + OkHttp3 + Gson + RxJava

    Retrofit2.0通俗易懂的学习姿势,Retrofit2.0 + OkHttp3 + Gson + RxJava Retrofit,因为其简单与出色的性能,也是受到很多人的青睐,但是他和以往的通信 ...

  7. Retrofit2.0 ,OkHttp3完美同步持久Cookie实现免登录(二)

    原文出自csdn: http://blog.csdn.net/sk719887916/article/details/51700659: 通过对Retrofit2.0的<Retrofit 2.0 ...

  8. Android网络框架之Retrofit + RxJava + OkHttp 变化的时代

    1.什么是Retrofit框架? 它是Square公司开发的现在非常流行的网络框架,所以我们在导入它的包的时候都可以看到这个公司的名字,目前的版本是2. 特点: 性能好,处理快,使用简单,Retrof ...

  9. Android 网络请求Retrofit + RxJava

    一.背景 经常看到项目用Retrofit+RxJava+RxAndroid的框架,为了看懂项目的结构.现在来了解一下,Retrofit: Retrofit是Square 公司开发的一款正对Androi ...

随机推荐

  1. Node.js 实用工具

    稳定性: 4 - 锁定 这些函数都在'util' 模块里.使用 require('util') 来访问他们. util 模块原先设计的初衷是用来支持 node 的内部 API 的.这里的很多的函数对你 ...

  2. let内嵌lambda使用set!构成闭包

    查了半天没有找到scheme中判断数据类型的函数,索性自己写了个type?,发现闭包和递归有着微妙的联系. 本例中,自由变量是types,外层let初始化了types的值,内层let里的(set! t ...

  3. 剑指Offer——知识点储备--Linux基本命令+Makefile

    剑指Offer--知识点储备–Linux基本命令 1.linux下查看进程占用cpu的情况(top): 格式 top [-] [d delay] [q] [c] [S] [s] [i] [n] 主要参 ...

  4. Button的几种常用的xml背景,扁平化,下划线,边框包裹,以及按压效果

    Button的几种常用的xml背景,扁平化,下划线,边框包裹,以及按压效果 分享下我项目中用到的几种Button的效果,说实话,还真挺好看的 一.标准圆角 效果是这样的 他的实现很简单,我们只需要两个 ...

  5. Ubuntu下配置Telnet服务器

    1. 首先介绍linux中的守护进程 在Linux系统中有一个特殊的守护进程inetd(InterNET services Daemon),它用于Internet标准服务,通常在系统启动时启动.通过命 ...

  6. Spring开发环境搭建教程

    Spring开发环境搭建 JDK7以上版本 eclispe for j2ee 4.0以上版本 Spring frameWorks 3.0以上版本 至于前两个我们就不介绍,直接百度就可以了,对于Spri ...

  7. TCP连接建立系列 — 客户端发送SYN段

    主要内容:客户端调用connect()时的TCP层实现. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd connect的TCP层实现 SOCK_STRE ...

  8. Unable to access the IIS metabase.You do not have sufficient privilege

    今天在用vs打开以前老代码的时候报如下问题,无法打开工程了,从提示来不大可能是因为vs的版本引起的,本身我用的是最新版的vs. 网上查了下解决方法如下:找到你电脑中的如下路径"C:\Wind ...

  9. 随机采样和随机模拟:吉布斯采样Gibbs Sampling

    http://blog.csdn.net/pipisorry/article/details/51373090 吉布斯采样算法详解 为什么要用吉布斯采样 通俗解释一下什么是sampling. samp ...

  10. 登录ssh时Host key verification failed错误

    工作中总是测试不同的路由设备, 路由器的ip都是 192.168.111.1 ,ssh登录的时候总是出现这个错误. macos上,错误如下 spawn ssh -p 22 root@192.168.1 ...