上一篇文章讲述了Retrofit的基本使用,包括GET,POST等请求.今天的文章中Retrofit要与RxJava配合使用.
了解RxJava
RxJava有种种好处,我不在这里一一讲述.这里我只给出一个使用RxJava的例子.
接下来的文章,我也会写RxJava的进一步使用的.
案例说明
该例子是获取手机上安装的APP,然后列表显示包括名称,图标,安装时间等信息.
上代码
下面是自定义的AppInfo类,包含名称,图标,安装时间,版本号,版本名称等属性.
[代码]java代码:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
public class AppInfo {
private String name;
private String installTime;
private int versionCode;
private String versionName;
private Drawable icon;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getInstallTime() {
return installTime;
}
public void setInstallTime(String installTime) {
this.installTime = installTime;
}
public int getVersionCode() {
return versionCode;
}
public void setVersionCode(int versionCode) {
this.versionCode = versionCode;
}
public String getVersionName() {
return versionName;
}
public void setVersionName(String versionName) {
this.versionName = versionName;
}
public Drawable getIcon() {
return icon;
}
public void setIcon(Drawable icon) {
this.icon = icon;
}
@Override
public String toString() {
return "AppInfo{" +
"name='" + name + '\'' +
", installTime='" + installTime + '\'' +
", versionCode='" + versionCode + '\'' +
", versionName='" + versionName + '\'' +
", icon=" + icon +
'}';
}
} |
下面是获取AppLie表的代码,封装为工具类使用:
[代码]java代码:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
public class AppUtil {
/**
* 获取已安装的APP的列表
* @param context 上下文
* @return AppInfo列表
*/
public static List<appinfo> getAppList(Context context){
List<appinfo> appInfoList = new ArrayList<>();
List<packageinfo> packages = context.getPackageManager()
.getInstalledPackages(PackageManager.GET_ACTIVITIES);
for (PackageInfo packageInfo : packages) {
AppInfo appInfo = new AppInfo();
appInfo.setName(packageInfo.applicationInfo
.loadLabel(context.getPackageManager())
.toString());
appInfo.setIcon(packageInfo.applicationInfo
.loadIcon(context.getPackageManager()));
appInfo.setInstallTime(getFormatTime(packageInfo.firstInstallTime));
appInfo.setVersionCode(packageInfo.versionCode);
appInfo.setVersionName(packageInfo.versionName);
appInfoList.add(appInfo);
}
return appInfoList;
}
public static String getFormatTime(long time){
if (time <= 0){
return "";
}
return SimpleDateFormat.getDateInstance(DateFormat.FULL).format(new Date(time));
}
}</packageinfo></appinfo></appinfo> |
不使用RxJava怎么做?
我们在不适用RxJava时怎么做?通常新建一个子线程去执行任务,然后回调更新界面,对不对?
[代码]java代码:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
private void getByNormal() {
refreshLayout.setRefreshing(true);
infoList.clear();
appAdapter.notifyDataSetChanged();
new AsyncTask<void, void,="" list<appinfo="">>(){
@Override
protected List<appinfo> doInBackground(Void... params) {
return AppHelper.getHelper().getListByNormal(MainActivity.this);
}
@Override
protected void onPostExecute(List<appinfo> appInfos) {
infoList.addAll(appInfos);
appAdapter.notifyDataSetChanged();
refreshLayout.setRefreshing(false);
}
};
}</appinfo></appinfo></void,>
|
使用RxJava
使用RxJava是这样来写代码的:
1.创建Observable
[代码]java代码:
|
01
02
03
04
05
06
07
08
09
10
11
12
|
public Observable<list<appinfo>> getListByRxJava(final Context context){
Observable<list<appinfo>> observer = Observable.create(
new Observable.OnSubscribe<list<appinfo>>() {
@Override
public void call(Subscriber<!--? super List<AppInfo-->> subscriber) {
List<appinfo> infoList = AppUtil.getAppList(context);
subscriber.onNext(infoList);
subscriber.onCompleted();
}
});
return observer;
}</appinfo></list<appinfo></list<appinfo></list<appinfo> |
2.在界面出调用
[代码]java代码:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
private void getByRxJava() {
refreshLayout.setRefreshing(true);
infoList.clear();
appAdapter.notifyDataSetChanged();
AppHelper.getHelper().getListByRxJava(this)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<list<appinfo>>() {
@Override
public void onCompleted() {
appAdapter.notifyDataSetChanged();
refreshLayout.setRefreshing(false);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(List<appinfo> list) {
infoList.addAll(list);
}
});
}</appinfo></list<appinfo> |
看结果
这个Demo的源码在此:RxJavaDemo
在Retrofit中使用RxJava
上次我们获取手机的归属地时的PhoneService中是这样写的:
[代码]java代码:
|
1
2
3
|
@GET("/apistore/mobilenumber/mobilenumber")
Call<phoneresult> getResult(@Header("apikey") String apikey,
@Query("phone") String phone);</phoneresult>
|
返回了一个Call对象,使用RxJava我们则返回一个可被观测的PhoneResult:Observable<PhoneResult>,如下:
[代码]java代码:
|
1
2
3
|
@GET("/apistore/mobilenumber/mobilenumber")
Observable<phoneresult> getPhoneResult(@Header("apikey") String apikey,
@Query("phone") String phone);</phoneresult>
|
为了能返回此对象,我们需要在创建Retrofit对象时添加一个RxJava对象的Adapter来自动完成:
[代码]java代码:
|
1
2
3
4
5
|
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
|
为此,还封装了一个单例模式的PhoneApi类:
[代码]java代码:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
/** * 手机号相关的API
* Created by Asia on 2016/3/24 0024.
*/
public class PhoneApi {
/**
* HOST地址
*/
public static final String BASE_URL = "http://apis.baidu.com";
/**
* 开发者Key
*/
public static final String API_KEY = "8e13586b86e4b7f3758ba3bd6c9c9135";
/**
* 获取PhoneApi实例
* @return
*/
public static PhoneApi getApi(){
return ApiHolder.phoneApi;
}
static class ApiHolder{
private static PhoneApi phoneApi = new PhoneApi();
}
private PhoneService service;
private PhoneApi(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
service = retrofit.create(PhoneService.class);
}
/**
* 获取PhoneService实例
* @return
*/
public PhoneService getService(){
return service;
}
} |
下面就是使用去获取手机的归属地啦:
[代码]java代码:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
phoneService.getPhoneResult(PhoneApi.API_KEY, number) .subscribeOn(Schedulers.newThread()) //子线程访问网络
.observeOn(AndroidSchedulers.mainThread()) //回调到主线程
.subscribe(new Observer<phoneresult>() {
@Override
public void onCompleted() {}
@Override
public void onError(Throwable e) {}
@Override
public void onNext(PhoneResult result) {
if (result != null && result.getErrNum() == 0) {
PhoneResult.RetDataEntity entity = result.getRetData();
resultView.append("地址:" + entity.getCity());
}
}
});
}</phoneresult> |
运行一下吧,结果是同样的哈.