上一篇文章讲述了Retrofit的基本使用,包括GET,POST等请求.今天的文章中Retrofit要与RxJava配合使用.html
RxJava有种种好处,我不在这里一一讲述.这里我只给出一个使用RxJava的例子.java
接下来的文章,我也会写RxJava的进一步使用的.git
该例子是获取手机上安装的APP,而后列表显示包括名称,图标,安装时间等信息.github
下面是自定义的AppInfo
类,包含名称,图标,安装时间,版本号,版本名称等属性.api
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表的代码,封装为工具类使用:网络
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时怎么作?一般新建一个子线程去执行任务,而后回调更新界面,对不对?app
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是这样来写代码的:ide
1.建立Observable
工具
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.在界面出调用ui
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
上次咱们获取手机的归属地时的PhoneService
中是这样写的:
1
2
3
|
@GET
(
"/apistore/mobilenumber/mobilenumber"
)
Call<phoneresult> getResult(
@Header
(
"apikey"
) String apikey,
@Query
(
"phone"
) String phone);</phoneresult>
|
返回了一个Call对象,使用RxJava咱们则返回一个可被观测的PhoneResult
:Observable<PhoneResult>
,以下:
1
2
3
|
@GET
(
"/apistore/mobilenumber/mobilenumber"
)
Observable<phoneresult> getPhoneResult(
@Header
(
"apikey"
) String apikey,
@Query
(
"phone"
) String phone);</phoneresult>
|
为了能返回此对象,咱们须要在建立Retrofit对象时添加一个RxJava对象的Adapter来自动完成:
1
2
3
4
5
|
Retrofit retrofit =
new
Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
|
为此,还封装了一个单例模式的PhoneApi
类:
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;
}
}
|
下面就是使用去获取手机的归属地啦:
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>
|
运行一下吧,结果是一样的哈.