简单应用实例:

在介绍如何使用Retrofit之前先做点准备。首先要有个开放的API供我们使用网络去获取信息,接下来的例子将使用OpenWeather来练习下,如下是openWeather的地址:
http://openweathermap.org/
和众多的API一样都需要申请一个开发者的key,申请key的过程就不在这里介绍了。

  1. 在AS中引入RxJava + Retrofix
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"

defaultConfig {
applicationId "com.idealist.doumusic"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:design:23.3.0'

compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
compile 'com.google.code.gson:gson:2.6.2'
}

开始我们先创建一个接口,关键部分先留空,后面我带大家一点一点往上面填:

public interface IDouMusic {
@GET("")
Callback<WheatherResult> getWheatherResult();

}

首先到这一步大家一定都申请了对应的APPID,也就是对应的APIkey,类似f8d8ead8299f963abcded5c40c0bcb81
找不到申请地方的我这里贴个地址:http://openweathermap.org/appid
申请到APPID后怎么使用呢?整个模板是这样的,只要在最后的申请后面添加APIKEY即可
http://api.openweathermap.org/data/2.5/forecast/city?id=524901&APPID={APIKEY}
前面的又是什么呢?大家进入这个页面http://openweathermap.org/api 这里面有很多的查询方案,作为例子我们选个简单的,当前的天气情况:
http://openweathermap.org/current 这里提供了很多的查询方式,可以按照城市名,城市id等信息查询。
你不知道城市id怎么表示?可以到这个地方下载city.list.json 查询 http://bulk.openweathermap.org/sample/
比如我们以广东惠州为例,查询当天天气,那么访问的地址应该是:http://api.openweathermap.org/data/2.5/weather?q=Huizhou&APPID=f8d8ead8299f963abcded5c40c0bcb81
注意这里的APIKey需要换成大家自己申请的。将上述的地址拷贝到浏览器上这时候就会返回下面信息:

{
"coord": {
"lon": 114.4,
"lat": 23.08
},
"weather": [
{
"id": 802,
"main": "Clouds",
"description": "scattered clouds",
"icon": "03n"
}
],
"base": "stations",
"main": {
"temp": 300.93,
"pressure": 995,
"humidity": 49,
"temp_min": 300.93,
"temp_max": 300.93
},
"wind": {
"speed": 1.03,
"gust": 7.71
},
"rain": {},
"clouds": {
"all": 48
},
"dt": 1463923088,
"sys": {
"type": 3,
"id": 187827,
"message": 0.0145,
"country": "CN",
"sunrise": 1463866709,
"sunset": 1463914799
},
"id": 1806776,
"name": "Huizhou",
"cod": 200
}

OK,到这一步我们来实现这个功能:
由于要访问到网络所以需要添加网络访问权限:

<uses-permission android:name="android.permission.INTERNET"/>

紧接着完善刚刚提到的那个接口:
为什么是@GET(“weather”)? 我们上面提到要访问的地址为:

http://api.openweathermap.org/data/2.5/weather?q=Huizhou&APPID=f8d8ead8299f963abcded5c40c0bcb81

去除掉访问参数后的地址为:

http://api.openweathermap.org/data/2.5/weather

我们再看OpenWeather的API,其中http://api.openweathermap.org/data/2.5/ 为公共部分,最后一个是变化的,我们将http://api.openweathermap.org/data/2.5/ 作为baseUri
weather作为地址的区别部分。这里需要注意的是baseuri一定要以’/‘结尾,GET(“weather”)这个不能以/开头,刚开始使用的时候由于这个原因导致了获取不到返回值,具体为什么,我将会在介绍完这个例子后给大家介绍下。

public interface IDouWheather {
@GET("weather")
Call<WheatherResult> getWheatherResult(@Query("q") String cityName, @Query("APPID") String ApiId);
}

关于访问接口还有如下的写法,这里介绍的是Path的用法。

public interface GitHub {
@GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(@Path("owner") String owner,@Path("repo") String repo);
}
//baseurl 定义
String baseUrl = "http://api.openweathermap.org/data/2.5/";

//创建Retrofit:
Retrofit retrofit = new Retrofit.Builder()
/**
使用Retrofit会将Json数据直接解析转换成java 对象,因此需要用到json 解析库作为转换器
这里使用GSON解析数据,但是retrofit2还支持如下列表的解析器:
    Gson: com.squareup.retrofit2:converter-gson 
    Jackson: com.squareup.retrofit2:converter-jackson 
    Moshi: com.squareup.retrofit2:converter-moshi 
    Protobuf: com.squareup.retrofit2:converter-protobuf 
    Wire: com.squareup.retrofit2:converter-wire 
    Simple XML:com.squareup.retrofit2:converter-simplexml
    
        */
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
/*需要注意下BASE_URL这个参数,如果@GET方法里的URl是完整的,则不拼接参数,否则拼接URL*/
.build();
//创建访问服务:
IDouWheather weatherService = retrofit.create(IDouWheather.class);
//将参数传递进去:
Call<WheatherResult> call = weatherService.getWheatherResult("Huizhou", "f8d8ead8299f963abcded5c40c0bcb89");
//异步访问:
call.enqueue(new Callback<WheatherResult>() {
//回调函数发生在主线程,可以进行UI相关的操作
@Override
public void onResponse(Call<WheatherResult> call, Response<WheatherResult> response) {
if(response.isSuccess()) {
//获取返回结果
WheatherResult result = response.body();
Log.i("xiaohai.lin", "getName = " + result.getName());
Log.i("xiaohai.lin", "getTemp = " + result.getMain().getTemp());
Log.i("xiaohai.lin", "getLat = " + result.getCoord().getLat());
Log.i("xiaohai.lin", "getLon = " + result.getCoord().getLon());
Log.i("xiaohai.lin", "getDescription = " + result.getWeather().get(0).getDescription());
}
}
@Override
public void onFailure(Call<WheatherResult> call, Throwable t) {

}
});

下面是返回数据对应的Bean,这个我是使用GSONFormat插件自动生成的:注意这里可以不用实现全部的节点,但是一定要注意,参数名一定要和返回的json数据的key一致:

public class WheatherResult {
/**
* lon : 114.4
* lat : 23.08
*/

private CoordBean coord;
/**
* coord : {"lon":114.4,"lat":23.08}
* weather : [{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}]
* base : stations
* main : {"temp":302.04,"pressure":994,"humidity":56,"temp_min":302.04,"temp_max":302.04}
* wind : {"speed":2.49,"deg":144}
* rain : {}
* clouds : {"all":68}
* dt : 1464103691
* sys : {"type":3,"id":187827,"message":0.0114,"country":"CN","sunrise":1464039473,"sunset":1464087657}
* id : 1806776
* name : Huizhou
* cod : 200
*/

private String base;
/**
* temp : 302.04
* pressure : 994
* humidity : 56
* temp_min : 302.04
* temp_max : 302.04
*/

private MainBean main;
/**
* speed : 2.49
* deg : 144
*/

private WindBean wind;
private RainBean rain;
/**
* all : 68
*/

private CloudsBean clouds;
private int dt;
/**
* type : 3
* id : 187827
* message : 0.0114
* country : CN
* sunrise : 1464039473
* sunset : 1464087657
*/

private SysBean sys;
private int id;
private String name;
private int cod;
/**
* id : 803
* main : Clouds
* description : broken clouds
* icon : 04n
*/

private List<WeatherBean> weather;

public CoordBean getCoord() {
return coord;
}

public void setCoord(CoordBean coord) {
this.coord = coord;
}

public String getBase() {
return base;
}

public void setBase(String base) {
this.base = base;
}

public MainBean getMain() {
return main;
}

public void setMain(MainBean main) {
this.main = main;
}

public WindBean getWind() {
return wind;
}

public void setWind(WindBean wind) {
this.wind = wind;
}

public RainBean getRain() {
return rain;
}

public void setRain(RainBean rain) {
this.rain = rain;
}

public CloudsBean getClouds() {
return clouds;
}

public void setClouds(CloudsBean clouds) {
this.clouds = clouds;
}

public int getDt() {
return dt;
}

public void setDt(int dt) {
this.dt = dt;
}

public SysBean getSys() {
return sys;
}

public void setSys(SysBean sys) {
this.sys = sys;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getCod() {
return cod;
}

public void setCod(int cod) {
this.cod = cod;
}

public List<WeatherBean> getWeather() {
return weather;
}

public void setWeather(List<WeatherBean> weather) {
this.weather = weather;
}

public static class CoordBean {
private double lon;
private double lat;

public double getLon() {
return lon;
}

public void setLon(double lon) {
this.lon = lon;
}

public double getLat() {
return lat;
}

public void setLat(double lat) {
this.lat = lat;
}
}

public static class MainBean {
private double temp;
private int pressure;
private int humidity;
private double temp_min;
private double temp_max;

public double getTemp() {
return temp;
}

public void setTemp(double temp) {
this.temp = temp;
}

public int getPressure() {
return pressure;
}

public void setPressure(int pressure) {
this.pressure = pressure;
}

public int getHumidity() {
return humidity;
}

public void setHumidity(int humidity) {
this.humidity = humidity;
}

public double getTemp_min() {
return temp_min;
}

public void setTemp_min(double temp_min) {
this.temp_min = temp_min;
}

public double getTemp_max() {
return temp_max;
}

public void setTemp_max(double temp_max) {
this.temp_max = temp_max;
}
}

public static class WindBean {
private double speed;
private int deg;

public double getSpeed() {
return speed;
}

public void setSpeed(double speed) {
this.speed = speed;
}

public int getDeg() {
return deg;
}

public void setDeg(int deg) {
this.deg = deg;
}
}

public static class RainBean {
}

public static class CloudsBean {
private int all;

public int getAll() {
return all;
}

public void setAll(int all) {
this.all = all;
}
}

public static class SysBean {
private int type;
private int id;
private double message;
private String country;
private int sunrise;
private int sunset;

public int getType() {
return type;
}

public void setType(int type) {
this.type = type;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public double getMessage() {
return message;
}

public void setMessage(double message) {
this.message = message;
}

public String getCountry() {
return country;
}

public void setCountry(String country) {
this.country = country;
}

public int getSunrise() {
return sunrise;
}

public void setSunrise(int sunrise) {
this.sunrise = sunrise;
}

public int getSunset() {
return sunset;
}

public void setSunset(int sunset) {
this.sunset = sunset;
}
}

public static class WeatherBean {
private int id;
private String main;
private String description;
private String icon;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getMain() {
return main;
}

public void setMain(String main) {
this.main = main;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public String getIcon() {
return icon;
}

public void setIcon(String icon) {
this.icon = icon;
}
}
}

点击运行就可以直接获取返回的结果了。

基本用法:

Retrofix && RxJava:

使用RXJava会使得整个流程会显得更加清晰,在原先项目中加入RxJava步骤很简单只需要在原有的基础上作如下改动即可:

在build.gradle中加入:

compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'

这时候接口就不能是Call了,而应该是Observable:

public interface IDouMusic {
@GET("weather")
Observable<WheatherResult> getWheatherResult(@Query("q") String cityName, @Query("APPID") String ApiId);
}
String baseUrl = "http://api.openweathermap.org/data/2.5/";
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
//添加RxJavaCallAdapterFactory
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(baseUrl)
.build();

IDouMusic weatherService = retrofit.create(IDouMusic.class);
Observable<WheatherResult> observable = weatherService.getWheatherResult("Huizhou", "f8d8ead8299f963abcded5c40c0bcb89");
//在IO线程执行网络查询
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
//切换到主线程在主线程更新UI
.subscribe(new Subscriber<WheatherResult>() {
@Override
public void onCompleted() {}
@Override
public void onError(Throwable e) {}
@Override
public void onNext(WheatherResult wheatherResult) {
Log.i("xiaohai.lin", "getName = " + wheatherResult.getName());
Log.i("xiaohai.lin", "getTemp = " + wheatherResult.getMain().getTemp());
Log.i("xiaohai.lin", "getLat = " + wheatherResult.getCoord().getLat());
Log.i("xiaohai.lin", "getLon = " + wheatherResult.getCoord().getLon());
Log.i("xiaohai.lin", "getDescription = " + wheatherResult.getWeather().get(0).getDescription());
}
});

Retrofix && Realm:

Realm 可以与 Retrofit 1.x 和 2.x 无缝配合工作。但注意 Retrofit 不会自动将对象存入 Realm。
你需要通过调用 Realm.copyToRealm() 或 Realm.copyToRealmOrUpdate() 来将它们存入 Realm。

GitHubService service = restAdapter.create(GitHubService.class);
List<Repo> repos = service.listRepos("octocat");

// Copy elements from Retrofit to Realm to persist them.
realm.beginTransaction();
List<Repo> realmRepos = realm.copyToRealmOrUpdate(repos);
realm.commitTransaction();

Retrofix2 新特性:

http://api.openweathermap.org/data/2.5/weather?q=Huizhou&APPID=f8d8ead8299f963abcded5c40c0bcb89
https://gank.io/post/56e80c2c677659311bed9841
https://yq.aliyun.com/articles/26705

http://www.07net01.com/program/2016/02/1307334.html
http://www.jianshu.com/p/c1a3a881a144
https://twiceyuan.com/2015/12/26/retrofit2-0/?utm_source=tuicool&utm_medium=referral
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0915/3460.html
http://blog.csdn.net/liuhongwei123888/article/details/50375283
http://www.cnblogs.com/angeldevil/p/3757335.html
http://www.bkjia.com/Androidjc/995850.html
http://blog.csdn.net/lizelinll/article/details/42361327
http://www.tuicool.com/articles/6zIvQbb
http://www.tuicool.com/articles/fQju2uQ
http://blog.csdn.net/tiankong1206/article/details/46486401
http://blog.csdn.net/caroline_wendy/article/details/50557470

http://www.cxbiao.com/2016/05/14/Retrofit2%E4%B8%8ERxJava%E7%94%A8%E6%B3%95%E8%A7%A3%E6%9E%90/
http://www.jcodecraeer.com/plus/view.php?aid=3460

Contents
  1. 1. 简单应用实例:
  2. 2. 基本用法:
  3. 3. Retrofix && RxJava:
  • Retrofix && Realm:
    1. 1. Retrofix2 新特性: