天涯尽头无女友
2018-10-07 14:13:22浏览 2119
上一篇文章讲述了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>
|
运行一下吧,结果是同样的哈.
原文链接:http://www.apkbus.com/blog-705730-61356.html