上一篇文章講述了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>
|
運行一下吧,結果是一樣的哈.