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

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

了解RxJava

RxJava有种种好处,我不在这里一一讲述.这里我只给出一个使用RxJava的例子.java

 

 

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

案例说明

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

上代码

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

[代码]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时怎么作?一般新建一个子线程去执行任务,而后回调更新界面,对不对?app

[代码]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是这样来写代码的:ide

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.在界面出调用ui

[代码]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>

 

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

相关文章
相关标签/搜索