博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Retrofit使用教程(三) : Retrofit与RxJava初相逢
阅读量:6924 次
发布时间:2019-06-27

本文共 7280 字,大约阅读时间需要 24 分钟。

讲述了Retrofit的基本使用,包括GET,POST等请求.今天的文章中Retrofit要与RxJava配合使用.

了解RxJava

RxJava有种种好处,我不在这里一一讲述.这里我只给出一个使用RxJava的例子.如果想更深入地了解RxJava,可以参考以下文章:

接下来的文章,我也会写RxJava的进一步使用的.

案例说明

该例子是获取手机上安装的APP,然后列表显示包括名称,图标,安装时间等信息.

上代码

下面是自定义的AppInfo类,包含名称,图标,安装时间,版本号,版本名称等属性.

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表的代码,封装为工具类使用:

public class AppUtil {    /**     * 获取已安装的APP的列表     * @param context 上下文     * @return AppInfo列表     */    public static List
getAppList(Context context){ List
appInfoList = new ArrayList<>(); List
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)); }}

不使用RxJava怎么做?

我们在不适用RxJava时怎么做?通常新建一个子线程去执行任务,然后回调更新界面,对不对?

private void getByNormal() {        refreshLayout.setRefreshing(true);        infoList.clear();        appAdapter.notifyDataSetChanged();        new AsyncTask
>(){ @Override protected List
doInBackground(Void... params) { return AppHelper.getHelper().getListByNormal(MainActivity.this); } @Override protected void onPostExecute(List
appInfos) { infoList.addAll(appInfos); appAdapter.notifyDataSetChanged(); refreshLayout.setRefreshing(false); } }; }

使用RxJava

使用RxJava是这样来写代码的:

1.创建Observable

public Observable
> getListByRxJava(final Context context){ Observable
> observer = Observable.create( new Observable.OnSubscribe
>() { @Override public void call(Subscriber
> subscriber) { List
infoList = AppUtil.getAppList(context); subscriber.onNext(infoList); subscriber.onCompleted(); } }); return observer; }

2.在界面出调用

private void getByRxJava() {        refreshLayout.setRefreshing(true);        infoList.clear();        appAdapter.notifyDataSetChanged();        AppHelper.getHelper().getListByRxJava(this)                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Subscriber
>() { @Override public void onCompleted() { appAdapter.notifyDataSetChanged(); refreshLayout.setRefreshing(false); } @Override public void onError(Throwable e) { } @Override public void onNext(List
list) { infoList.addAll(list); } }); }

看结果

这个Demo的源码在此:

在Retrofit中使用RxJava

上次我们获取手机的归属地时的PhoneService中是这样写的:

@GET("/apistore/mobilenumber/mobilenumber")    Call
getResult(@Header("apikey") String apikey, @Query("phone") String phone);

返回了一个Call对象,使用RxJava我们则返回一个可被观测的PhoneResult:Observable<PhoneResult>,如下:

@GET("/apistore/mobilenumber/mobilenumber")    Observable
getPhoneResult(@Header("apikey") String apikey, @Query("phone") String phone);

为了能返回此对象,我们需要在创建Retrofit对象时添加一个RxJava对象的Adapter来自动完成:

Retrofit retrofit = new Retrofit.Builder()        .baseUrl(BASE_URL)        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())        .addConverterFactory(GsonConverterFactory.create())        .build();

为此,还封装了一个的PhoneApi类:

/** * 手机号相关的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;    }}

下面就是使用去获取手机的归属地啦:

phoneService.getPhoneResult(PhoneApi.API_KEY, number)        .subscribeOn(Schedulers.newThread())    //子线程访问网络        .observeOn(AndroidSchedulers.mainThread())  //回调到主线程        .subscribe(new Observer
() { @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()); } } });}

运行一下吧,结果是同样的哈.

项目地址在此:

更多文章请移步我的博客:

重要说明

想随时获取最新博客文章更新,请关注公共账号DevWiki,或扫描下面的二维码:

微信公共号

转载地址:http://ijujl.baihongyu.com/

你可能感兴趣的文章
Oracle的统计分析函数(STDDEV函数)
查看>>
网卡配置文件
查看>>
开始安卓开发历程
查看>>
防止人为误操作MySQL数据库技巧一例
查看>>
linux svn 客户端使用!
查看>>
【java设计模式】备忘录模式
查看>>
我的友情链接
查看>>
快速排序
查看>>
mysql查询时截取字符串
查看>>
java死锁和避免死锁
查看>>
仲裁流程系统开发杂记
查看>>
消息中间件基础介绍
查看>>
PMP——折旧法
查看>>
增加ad属性
查看>>
bootstrap大图轮播手机端不能手指滑动解决办法
查看>>
DNS服务器*****(二)
查看>>
tomcat在conf/Catalina/localhost目录下配置项目路径
查看>>
网络设备在网络环境中的应用
查看>>
ICN:SDN后的下一个热潮
查看>>
图解linux下top命令的使用
查看>>