手记

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>

 

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

原文链接:http://www.apkbus.com/blog-705730-61356.html

0人推荐
随时随地看视频
慕课网APP