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网络架构搭建的更多相关文章

  1. 基于Retrofit2.0+RxJava+Dragger2实现不一样的Android网络构架搭建(转载)

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

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

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

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

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

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

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

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

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

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

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

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

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

  8. Android 网络请求Retrofit + RxJava

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

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

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

随机推荐

  1. 认识JQuery,JQuery的优势、语法、多库冲突、JS原生对象和JQuery对象之间相互转换和DOM操作,常用的方法

    (一)认识JQuery  JQuery是一个JavaScript库,它通过封装原生的JavaScript函数得到一套定义好的方法    JQuery的主旨:以更少的代码,实现更多的功能 (二)JQue ...

  2. python3爬取女神图片,破解盗链问题

    title: python3爬取女神图片,破解盗链问题 date: 2018-04-22 08:26:00 tags: [python3,美女,图片抓取,爬虫, 盗链] comments: true ...

  3. Android ART、Dalvik在multidex上的差异、关联

    为提升应用运行性能,谷歌官方从5.0(api level:21)版本开始,将虚拟机运行环境默认为ART, 此处主要研究ART.Dalvik在multidex处理上的差异和关联,做了一个简单的手绘,如下 ...

  4. Caffe的运行mnist手写数字识别

    老规矩,首先附上官方教程:http://caffe.berkeleyvision.org/gathered/examples/mnist.html 1.必要软件 因为Caffe中使用的是Linux才能 ...

  5. [Luogu 3919]【模板】可持久化数组(可持久化线段树/平衡树)

    Description 如题,你需要维护这样的一个长度为 N 的数组,支持如下几种操作 在某个历史版本上修改某一个位置上的值 访问某个历史版本上的某一位置的值 此外,每进行一次操作(对于操作2,即为生 ...

  6. 冰精冻西瓜[P3787洛谷]

    题目描述 琪露诺是拥有操纵冷气程度的能力的妖精,一天她发现了一片西瓜地.这里有n个西瓜,由n-1条西瓜蔓连接,形成一个有根树,琪露诺想要把它们冷冻起来慢慢吃. 这些西瓜蔓具有神奇的性质,可以将经过它的 ...

  7. ●BZOJ 3238 [Ahoi2013]差异

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3238 题解: 后缀数组套路深. 问题转化为求出任意两个后缀的LCP之和 在计算贡献时,各种不 ...

  8. Polya计数

    Let it Bead Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5365   Accepted: 3585 Descr ...

  9. 【SDOI2009】学校食堂

    Description 小F的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用 ...

  10. python中的赋值操作和复制操作

    之前一直写C#,变量之间赋值相当于拷贝,修改拷贝变量不会改变原来的值.但是在python中发现赋值操作本质是和C++中的引用类似,即指向同一块内存空间.下面通过一个例子说明: p=[0,1,2,3,4 ...