rxjava+rxandroid+retrofit2.0使用方法demo講解
最近看了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( “
.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---123
12-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() );
}
} );
分析:
修改call方法—
直接傳遞
List integers 物件
自定義的
public void call(List integers)
呼叫一次。