• Android Retrofit使用教程(三):Retrofit与RxJava初相逢


    上一篇文章讲述了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>

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

  • 相关阅读:
    leetcode — simplify-path
    leetcode — climbing-stairs
    leetcode — sqrtx
    leetcode — text-justification
    leetcode — add-binary
    leetcode — plus-one
    leetcode — valid-number
    leetcode — minimum-path-sum
    leetcode — unique-paths-ii
    四维偏序 CDQ套CDQ
  • 原文地址:https://www.cnblogs.com/android-blogs/p/5752451.html
Copyright © 2020-2023  润新知