rxjava+rxandroid+retrofit2.0使用方法demo讲解

来源:互联网 发布:耽美网络电视剧最新 编辑:程序博客网 时间:2024/05/22 03:19

最近看了retrofit框架,比较新的网络访问请求框架,很多项目都涉及到,所以学习了一下,做个总结。
第一讲 retrofit2.0单独使用
1、导入依赖jar包(也可能是library,反正studio会自动下载)
compile ‘io.reactivex:rxandroid:1.1.0’
compile ‘io.reactivex:rxjava:1.1.0’
compile ‘com.squareup.retrofit:retrofit:2.0.0-beta2’
compile ‘com.squareup.retrofit:converter-gson:2.0.0-beta2’
compile ‘com.squareup.retrofit:adapter-rxjava:2.0.0-beta2’
2、创建访问网络接口(其实就是构造utl)
public interface GitHubApi {
@GET(“repos/{owner}/{repo}/contributors”)
Call get(@Path(“owner”) String owner, @Path(“repo”) String repo);
}
这里面使用了注解代码,大家可以自行百度学习一下。
主要有:
@path
@GET
@POST
@QUERY
@QUERYMAP

简单来说,就是构造网络访问的url
这里面
Call 方法(参数);
Call 方法();
T:返回的数据类型
这个是固定模板。
当然,
如果结合使用了rxjava,模板也可以是:
Observable 方法(XXX);

3、使用Call.enqueue访问网络
访问网络耗时操作,通常放在线程中执行,你可以自己
new Thread(){run()}.start() ,
其实retrofit已经封装了线程请—enqueue( )
button.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl( “https://api.github.com/” )
.build();
GitHubApi repo = retrofit.create( GitHubApi.class );//拿到接口对象,反射代理机制
Call call = repo.get( “square”, “retrofit” );//get方法已经被重写了
//使用call进行请求
call.enqueue( new Callback() {
@Override
public void onResponse(Response response, Retrofit retrofit) {
try {
response.body().string()—” + response.body().string() );
}
} catch (IOException e) {
Log.d( “lihui”, “e—” + e.toString() );
e.printStackTrace();
}
}
@Override
public void onFailure(Throwable t) {
Log.d( “lihui”, “t—” + t.toString() );
}
} );
分析:
call.enqueue( )这个是异步请求。
call也支持同步请求,
Call call = repo.get();
ResponseBody responseBody= call.execute();
这里:call.execute()返回对象模板关系

Call<T>

T t=call.execute();
但是android会抛出异常
阻塞线程,因此你不能在安卓的主线程中调用,不然会面临NetworkOnMainThreadException。如果你想调用execute方法,请在后台线程执行。

如果返回的数据是json格式,
可以对response.body()返回的数据进行反序列化,
使用json包
compile ‘com.google.code.gson:gson:2.3’

 Gson gson = new Gson();                            ArrayList<Contributor> contributorsList = gson.fromJson( response.body().string(), new TypeToken<List<Contributor>>() {                            }.getType() );

Contributor实体类,对应

public class Contributor {    private String login;    private String contributions;    private String html_url;    private String avatar_url;    public String getAvatar_url() {        return avatar_url;    }    public void setAvatar_url(String avatar_url) {        this.avatar_url = avatar_url;    }    public Contributor(String login) {        this.login = login;    }    public String getHtml_url123() {        return html_url;    }    public void setHtml_url123(String html_url) {        this.html_url = html_url;    }    public String getLogin() {        return login;    }    public void setLogin(String login) {        this.login = login;    }    public String getContributions() {        return contributions;    }    public void setContributions(String contributions) {        this.contributions = contributions;    }}

这里面的属性名称一定要和json中name一致!!!!

其实retrofit中已经有了json转化器,自动将返回的json格式数据进行序列化。
修改:

 @GET("repos/{owner}/{repo}/contributors") Call<List<Contributor>> get(@Path("owner") String owner, @Path("repo") String repo);
 Retrofit retrofit = new Retrofit.Builder().baseUrl( "https://api.github.com/" ).**addConverterFactory**( GsonConverterFactory.create() ).build();

addConverterFactory:转化器
对应jar包:
compile ‘com.squareup.retrofit:converter-gson:2.0.0-beta2’

返回处理:

public void onResponse(Response<List<Contributor>> response, Retrofit retrofit) {                        List<Contributor> contributors = response.body();//已经向返回的数据进行了序列化                        for (Contributor contributor : contributors) {                            Log.d( "lihui", "1---" + contributor.getLogin() );                            Log.d( "lihui", "2---" + contributor.getContributions() );                            Log.d( "lihui", "3---" + contributor.getHtml_url123() );                        }                    }

4、结合rxjava+rxandroid
修改如下:
1)jar包
compile ‘com.squareup.retrofit:adapter-rxjava:2.0.0-beta2’
适配器
2)@GET("repos/{owner}/{repo}/contributors")
rx.Observable<List<Contributor>> getSource(@Path("owner") String owner, @Path("repo") String repo);

模板2,返回对象Observable

  Retrofit retrofit = new Retrofit.Builder().baseUrl( "https://api.github.com/" ).                                                   addCallAdapterFactory( **RxJavaCallAdapterFactory**.create() ).                                               addConverterFactory( GsonConverterFactory.create() ).build();

注:
addCallAdapterFactory添加适配工厂,这样rxjava中可以直接传递List对象了。

 button3.setOnClickListener( new View.OnClickListener() {                                        @Override                                        public void onClick(View v) {                                            Retrofit retrofit = new Retrofit.Builder().baseUrl( "https://api.github.com/" ).                                                    addCallAdapterFactory( RxJavaCallAdapterFactory.create() ).                                                    addConverterFactory( GsonConverterFactory.create() ).build();   GitHubApi mGitHubService = retrofit.create( GitHubApi.class );                                          mGitHubService.getSource( "square", "retrofit" ).subscribeOn( Schedulers.io() ).observeOn( AndroidSchedulers.mainThread() ).subscribe( new Observer<List<Contributor>>() {                          @Override           public void onCompleted() {}                     @Override                public void onError(Throwable e) {}       @Override        public void onNext(List<Contributor> contributors) {  for (Contributor c : contributors) {         Log.d( "lihui", "Contributions---" + c.getContributions() );                                                    }                                                }                                            } );                                        }                                    }        );

注:
addCallAdapterFactory
返回的数据可以结合rxjava的Observeble数据传递下去。

2016-12-1 笔记:
retrofit结合使用rxjava,
必须添加
.addCallAdapterFactory( RxJavaCallAdapterFactory.create() )
否则出现异常:

 E/AndroidRuntime: FATAL EXCEPTION: main                                                                            Process: com.example.lihui20.testhttp, PID: 6397                                                                            java.lang.IllegalArgumentException: *Unable to create call adapter for* rx.Observable<com.squareup.okhttp.ResponseBody>                                                                                for method GitHubApi.getLocation                                                                                at retrofit.Utils.methodError(Utils.java:177)                                                                                at retrofit.MethodHandler.createCallAdapter(MethodHandler.java:47)                                                                                at retrofit.MethodHandler.create(MethodHandler.java:26)                                                                                at retrofit.Retrofit.loadMethodHandler(Retrofit.java:151)                                                                                at retrofit.Retrofit$1.invoke(Retrofit.java:132)                                                                                at java.lang.reflect.Proxy.invoke(Proxy.java:813)                                                                                at $Proxy0.getLocation(Unknown Source)                                                                                at com.example.lihui20.testhttp.MainActivity$4.onClick(MainActivity.java:161)                                                                                at android.view.View.performClick(View.java:5609)                                                                                at android.view.View$PerformClick.run(View.java:22279)                                                                                at android.os.Handler.handleCallback(Handler.java:751)                                                                                at android.os.Handler.dispatchMessage(Handler.java:95)                                                                                at android.os.Looper.loop(Looper.java:154)                                                                                at android.app.ActivityThread.main(ActivityThread.java:6111)                                                                                at java.lang.reflect.Method.invoke(Native Method)                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)                                                                             Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for rx.Observable<com.squareup.okhttp.ResponseBody>. Tried:                                                                             * retrofit.ExecutorCallAdapterFactory                                                                                at retrofit.Retrofit.nextCallAdapter(Retrofit.java:207)                                                                                at retrofit.Retrofit.callAdapter(Retrofit.java:175)                                                                                at retrofit.MethodHandler.createCallAdapter(MethodHandler.java:45)                                                                                    ... 15 more

java.lang.IllegalArgumentException: Unable to create call adapter for rx.Observable

Call<ResponseBody>

结果返回不是json格式,我们想转换成其他类型,如:
Call

  Process: com.example.lihui20.testhttp, PID: 11899                                                                              java.lang.IllegalArgumentException: **Unable to create converter for class java.lang.String**                                                                                  for method GitHubApi.getLocation                                                                                  at retrofit.Utils.methodError(Utils.java:177)                                                                                  at retrofit.MethodHandler.createResponseConverter(MethodHandler.java:57)                                                                                  at retrofit.MethodHandler.create(MethodHandler.java:29)                                                                                  at retrofit.Retrofit.loadMethodHandler(Retrofit.java:151)                                                                                  at retrofit.Retrofit$1.invoke(Retrofit.java:132)                                                                                  at java.lang.reflect.Proxy.invoke(Proxy.java:813)                                                                                  at $Proxy0.getLocation(Unknown Source)                                                                                  at com.example.lihui20.testhttp.MainActivity$4.onClick(MainActivity.java:162)                                                                                  at android.view.View.performClick(View.java:5609)                                                                                  at android.view.View$PerformClick.run(View.java:22279)                                                                                  at android.os.Handler.handleCallback(Handler.java:751)                                                                                  at android.os.Handler.dispatchMessage(Handler.java:95)                                                                                  at android.os.Looper.loop(Looper.java:154)                                                                                  at android.app.ActivityThread.main(ActivityThread.java:6111)                                                                                  at java.lang.reflect.Method.invoke(Native Method)                                                                                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)                                                                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)                                                                               Caused by: java.lang.IllegalArgumentException: Could not locate ResponseBody converter for class java.lang.String. Tried:                                                                               * retrofit.BuiltInConverters                                                                                  at retrofit.Retrofit.responseConverter(Retrofit.java:266)                                                                                  at retrofit.MethodHandler.createResponseConverter(MethodHandler.java:55)                                                                                    ... 15 more

自定义
converter for class java.lang.String

 .addConverterFactory( new Converter.Factory() {                            @Override                            public Converter<ResponseBody, ?> fromResponseBody(Type type, Annotation[] annotations) {                                return new Converter<ResponseBody, String>() {                                    @Override                                    public String convert(ResponseBody value) throws IOException {                                        return value.string();                                    }                                };                            }                        } )

rxjava运算符学习:
1)just和from
直接上例子

  List<Integer> list2 = new ArrayList<Integer>();                list2.add( 123 );                list2.add( 34 );                Observable.from( list2  ).subscribe( new Action1<Integer>() {                    @Override                    public void call(Integer integer) {                        Log.d("lihui","from---"+ integer);                    }                } );分析:call方法会连续调用多次,循环把list中item输出。12-02 17:04:31.958 13858-13858/com.example.lihui20.testhttp D/lihui: from---12312-02 17:04:31.958 13858-13858/com.example.lihui20.testhttp D/lihui: from---34                Observable.just(list2 ).subscribe( new Action1<List<Integer>>() {                    @Override                    public void call(List<Integer> integers) {                        Log.d("lihui","just---"+ integers.toString() );                    }                } );

分析:
直接传递
List integers 对象
调用一次。

2 0
原创粉丝点击