<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>2
2
1
<uses-permission android:name="android.permission.INTERNET"/>2
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>依赖
注:这里没有指定支持 Lambda 表达式需要的配置
//【retrofit2】
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
//【okhttp】
compile 'com.squareup.okhttp3:okhttp:3.8.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.8.0'
compile 'com.squareup.okio:okio:1.13.0'
//【butterknife】
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
//【rxjava】
compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.6'17
17
1
//【retrofit2】2
compile 'com.squareup.retrofit2:retrofit:2.3.0'3
compile 'com.squareup.retrofit2:converter-gson:2.3.0'4
compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0'5
6
//【okhttp】7
compile 'com.squareup.okhttp3:okhttp:3.8.0'8
compile 'com.squareup.okhttp3:logging-interceptor:3.8.0'9
compile 'com.squareup.okio:okio:1.13.0'10
11
//【butterknife】12
compile 'com.jakewharton:butterknife:8.8.1'13
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'14
15
//【rxjava】16
compile 'io.reactivex:rxandroid:1.1.0'17
compile 'io.reactivex:rxjava:1.1.6'GitHubApi
public interface GitHubApi {
@GET("repos/{owner}/{repo}/contributors")
Call<ResponseBody> contributorsBySimpleGetCall(@Path("owner") String owner, @Path("repo") String repo);
@GET("repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributorsByAddConverterGetCall(@Path("owner") String owner, @Path("repo") String repo);
@Headers({"Accept: application/vnd.github.v3.full+json", "User-Agent: RetrofitBean-Sample-App", "name:ljd"})
@GET("repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributorsAndAddHeader(@Path("owner") String owner, @Path("repo") String repo);
@GET("search/repositories")
Call<RetrofitBean> queryRetrofitByGetCall(@Query("q") String owner, @Query("since") String time, @Query("page") int page, @Query("per_page") int per_Page);
@GET("search/repositories")
Call<RetrofitBean> queryRetrofitByGetCallMap(@QueryMap Map<String, String> map);
@GET("repos/{owner}/{repo}/contributors")
Observable<List<Contributor>> contributorsByRxJava(@Path("owner") String owner, @Path("repo") String repo);
@GET("users/{user}")
Observable<User> userByRxJava(@Path("user") String user);
@GET("/mobilesafe/shouji360/360safesis/360MobileSafe_6.2.3.1060.apk")
Call<ResponseBody> retrofitDownload();
}27
27
1
public interface GitHubApi {2
3
("repos/{owner}/{repo}/contributors")4
Call<ResponseBody> contributorsBySimpleGetCall(("owner") String owner, ("repo") String repo);5
6
("repos/{owner}/{repo}/contributors")7
Call<List<Contributor>> contributorsByAddConverterGetCall(("owner") String owner, ("repo") String repo);8
9
({"Accept: application/vnd.github.v3.full+json", "User-Agent: RetrofitBean-Sample-App", "name:ljd"})10
("repos/{owner}/{repo}/contributors")11
Call<List<Contributor>> contributorsAndAddHeader(("owner") String owner, ("repo") String repo);12
13
("search/repositories")14
Call<RetrofitBean> queryRetrofitByGetCall(("q") String owner, ("since") String time, ("page") int page, ("per_page") int per_Page);15
16
("search/repositories")17
Call<RetrofitBean> queryRetrofitByGetCallMap( Map<String, String> map);18
19
("repos/{owner}/{repo}/contributors")20
Observable<List<Contributor>> contributorsByRxJava(("owner") String owner, ("repo") String repo);21
22
("users/{user}")23
Observable<User> userByRxJava(("user") String user);24
25
("/mobilesafe/shouji360/360safesis/360MobileSafe_6.2.3.1060.apk")26
Call<ResponseBody> retrofitDownload();27
}MainActivity
public class MainActivity extends ListActivity {
private TextView tv;
private static final String baseUrl = "https://api.github.com/";
private static final String mUserName = "square";//哪个公司【square】
private static final String mRepo = "retrofit";//哪个项目【retrofit】
private CompositeSubscription mSubscriptions = new CompositeSubscription();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] array = {"1、简单完整演示retrofit的使用",
"2、添加Gson转换器",
"3、添加okHttp的日志拦截器Interceptor",
"4、使用自己封装的API,演示@Headers",
"5、演示同步请求",
"6、演示@Query",
"7、演示@QueryMap",
"8、最简单、完整的retrofit+rxJava示例",
"9、rxJava+retrofit增强",
"10、演示文件下载",};
tv = new TextView(this);// 将内容显示在TextView中
tv.setTextColor(Color.BLUE);
getListView().addFooterView(tv);
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new ArrayList<>(Arrays.asList(array))));
}
@Override
protected void onDestroy() {
if (mSubscriptions != null) mSubscriptions.unsubscribe();
super.onDestroy();
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
switch (position + 1) {
case 1://简单完整演示retrofit的使用
requestGitHubContributorsSimple();
break;
case 2://添加Gson转换器
requestGitHubContributorsByConverter();
break;
case 3://添加okHttp的日志拦截器Interceptor
requestGitHubContributorsAddOkHttpLog();
break;
case 4://使用自己封装的API,演示@Headers
requestGitHubContributorsAddHeader();
break;
case 5://演示同步请求
requestGitHubContributorsBySync();
break;
case 6://演示@Query
requestQueryRetrofitByGet(false);
break;
case 7://演示@QueryMap
requestQueryRetrofitByGet(true);
break;
case 8://最简单、完整的retrofit+rxJava示例
requestGitHubContributorsByRxJava();
break;
case 9://rxJava+retrofit增强
requestGitHubContributorsWithFullUserInfo();
break;
case 10://演示文件下载
retrofitDownload();
break;
}
}
/**
* 1、简单示例
*/
private void requestGitHubContributorsSimple() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.build();
GitHubApi repo = retrofit.create(GitHubApi.class);
Call<ResponseBody> call = repo.contributorsBySimpleGetCall(mUserName, mRepo);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> response) {
String result = null;
try {
result = response.body().string();
if (result == null) return;
} catch (IOException e) {
e.printStackTrace();
}
tv.setText("GitHub上对项目的贡献-1:
");
ArrayList<Contributor> list = new Gson()
.fromJson(result, new TypeToken<List<Contributor>>() {
}.getType());
if (list == null || list.size() == 0) return;
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "
");
}
}
@Override
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
/**
* 2、添加Gson转换器
*/
private void requestGitHubContributorsByConverter() {
new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())//转换器
.build()
.create(GitHubApi.class)
.contributorsByAddConverterGetCall(mUserName, mRepo)
.enqueue(new Callback<List<Contributor>>() {
@Override
public void onResponse(@NonNull Call<List<Contributor>> call, @NonNull Response<List<Contributor>> response) {
List<Contributor> list = response.body();
tv.setText("GitHub上对项目的贡献-2:
");
if (list == null || list.size() == 0) return;
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "
");
}
}
@Override
public void onFailure(@NonNull Call<List<Contributor>> call, @NonNull Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
/**
* 3、添加okHttp的日志拦截器Interceptor
*/
private void requestGitHubContributorsAddOkHttpLog() {
HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);
Retrofit retrofit = new Retrofit.Builder()
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(new OkHttpClient.Builder().addInterceptor(logInterceptor).build())
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
retrofit.create(GitHubApi.class)
.contributorsByAddConverterGetCall(mUserName, mRepo)
.enqueue(new Callback<List<Contributor>>() {
@Override
public void onResponse(@NonNull Call<List<Contributor>> call, @NonNull Response<List<com.bqt
.retrofit.bean.Contributor>> response) {
List<Contributor> list = response.body();
tv.setText("GitHub上对项目的贡献-3:
");
if (list == null || list.size() == 0) return;
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "
");
}
}
@Override
public void onFailure(@NonNull Call<List<Contributor>> call, @NonNull Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
/**
* 4、使用自己封装的API,演示@Headers
*/
private void requestGitHubContributorsAddHeader() {
createRetrofitService(GitHubApi.class)
.contributorsAndAddHeader(mUserName, mRepo)
.enqueue(new Callback<List<Contributor>>() {
@Override
public void onResponse(@NonNull Call<List<Contributor>> call, @NonNull Response<List<com.bqt
.retrofit.bean.Contributor>> response) {
List<Contributor> list = response.body();
tv.setText("GitHub上对项目的贡献-4:
");
if (list == null || list.size() == 0) return;
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "
");
}
}
@Override
public void onFailure(@NonNull Call<List<Contributor>> call, @NonNull Throwable t) {
}
});
}
/**
* 5、演示同步请求
*/
private void requestGitHubContributorsBySync() {
final Call<List<Contributor>> call = createRetrofitService(GitHubApi.class)
.contributorsByAddConverterGetCall(mUserName, mRepo);
new Thread(() -> {
try {
Response<List<Contributor>> response = call.execute();//在子线程中请求网络
final List<Contributor> list = response.body();
runOnUiThread(() -> {
tv.setText("GitHub上对项目的贡献-5:
");
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "
");
}
});
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
/**
* 6/7、演示@Query和@QueryMap
*/
private void requestQueryRetrofitByGet(boolean isQueryMap) {
GitHubApi mGitHubService = createRetrofitService(GitHubApi.class);
Call<RetrofitBean> call;
if (!isQueryMap) call = mGitHubService.queryRetrofitByGetCall("retrofit", "2016-03-29", 1, 3);
else {
Map<String, String> queryMap = new HashMap<>();
queryMap.put("q", "retrofit");
queryMap.put("since", "2016-03-29");
queryMap.put("page", "1");
queryMap.put("per_page", "3");
call = mGitHubService.queryRetrofitByGetCallMap(queryMap);
}
call.enqueue(new Callback<RetrofitBean>() {
@Override
public void onResponse(@NonNull Call<RetrofitBean> call, @NonNull Response<RetrofitBean> response) {
RetrofitBean retrofitBean = response.body();
if (retrofitBean == null) return;
List<Item> list = retrofitBean.getItems();
if (list == null || list.size() == 0) return;
tv.setText(new SimpleDateFormat("yyyy.MM.dd HH:mm:ss SSS", Locale.getDefault()).format(new Date()));
tv.append("
total:" + retrofitBean.getTotalCount() + "
incompleteResults:" + retrofitBean.getIncompleteResults());
for (Item item : list) {
tv.append("
【name】" + item.name);
tv.append("
【full_name】" + item.full_name);
tv.append("
【 description】" + item.description);
}
}
@Override
public void onFailure(@NonNull Call<RetrofitBean> call, @NonNull Throwable t) {
}
});
}
/**
* 8、最简单、完整的retrofit+rxJava示例
*/
private void requestGitHubContributorsByRxJava() {
createRetrofitService(GitHubApi.class)
.contributorsByRxJava(mUserName, mRepo)//
.subscribeOn(Schedulers.io())//
.observeOn(AndroidSchedulers.mainThread())//
.subscribe(new Observer<List<Contributor>>() {
@Override
public void onCompleted() {
Toast.makeText(MainActivity.this, "完成", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(List<Contributor> list) {
tv.setText("GitHub上对项目的贡献-8:
");
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "
");
}
}
});
}
/**
* 9、rxJava+retrofit增强
*/
private void requestGitHubContributorsWithFullUserInfo() {
tv.setText("");
final GitHubApi mGitHubService = createRetrofitService(GitHubApi.class);
Subscription subscription =
mGitHubService.contributorsByRxJava(mUserName, mRepo)//
.flatMap(new Func1<List<Contributor>, Observable<Contributor>>() {
//变换:将事件序列中的对象或整个序列进行加工处理,转换成不同的事件或事件序列
@Override
public Observable<Contributor> call(List<Contributor>
contributors) {
//1、使用传入的事件对象创建一个 Observable 对象;
//2、并不发送这个 Observable,而是将它激活,于是它开始发送事件;
//3、创建的 Observable 发送的事件,都被汇入同一个 Observable,而这个 Observable 负责将这些事件统一交给Subscriber 的回调方法
return Observable.from(contributors);
}
})
.flatMap(new Func1<Contributor, Observable<Pair<User, Contributor>>>() {
@Override
public Observable<Pair<User, Contributor>> call(com.bqt
.retrofit.bean.Contributor contributor) {
Observable<User> userObservable = mGitHubService.userByRxJava(contributor.login)
.filter(user -> !isEmpty(user.name) && !isEmpty(user.email));
return Observable.zip(userObservable, Observable.just(contributor), Pair::new);
}
})
.subscribeOn(Schedulers.newThread())//指定 subscribe() 发生在哪个线程,后台线程取数据,主线程显示
.observeOn(AndroidSchedulers.mainThread())//指定 Subscriber 的回调发生在主线程
.subscribe(new Observer<Pair<User, Contributor>>() {
@Override
public void onCompleted() {
Toast.makeText(MainActivity.this, "完成", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(Pair<User, Contributor> pair) {
User user = pair.first;
Contributor contributor = pair.second;
tv.append("name:" + user.name + "
contributions:" + contributor.contributions + "
Email:" + user.email + "
");
}
});
mSubscriptions.add(subscription);
}
/**
* 10、演示文件下载
*/
public void retrofitDownload() {
//监听下载进度
final ProgressDialog dialog = new ProgressDialog(this);
dialog.setProgressNumberFormat("%1d KB/%2d KB");
dialog.setTitle("下载");
dialog.setMessage("正在下载,请稍后...");
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setCancelable(false);
dialog.show();
ProgressHelper.setProgressHandler(new DownloadProgressHandler() {
@Override
protected void onProgress(long bytesRead, long contentLength, boolean done) {
//在主线程中运行
dialog.setMax((int) (contentLength / 1024));
dialog.setProgress((int) (bytesRead / 1024));
if (done) dialog.dismiss();
}
});
Retrofit retrofit = new Retrofit.Builder()//
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//
.addConverterFactory(GsonConverterFactory.create())//
.baseUrl("http://msoftdl.360.cn")
.client(ProgressHelper.addProgress(null).build())
.build();
retrofit.create(GitHubApi.class).retrofitDownload()
.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> response) {
try {
InputStream is = response.body().byteStream();
File file = new File(Environment.getExternalStorageDirectory(), "12345.apk");
FileOutputStream fos = new FileOutputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
fos.flush();
}
fos.close();
bis.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
}
});
}
public static <T> T createRetrofitService(final Class<T> service) {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder builder = new OkHttpClient.Builder().addInterceptor(httpLoggingInterceptor);
Retrofit retrofit = new Retrofit.Builder()//
.client(ProgressHelper.addProgress(builder).build())//
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//
.addConverterFactory(GsonConverterFactory.create())//
.baseUrl("https://api.github.com/")//
.build();
return retrofit.create(service);
}
}403
403
1
public class MainActivity extends ListActivity {2
private TextView tv;3
private static final String baseUrl = "https://api.github.com/";4
private static final String mUserName = "square";//哪个公司【square】5
private static final String mRepo = "retrofit";//哪个项目【retrofit】6
private CompositeSubscription mSubscriptions = new CompositeSubscription();7
8
protected void onCreate(Bundle savedInstanceState) {9
super.onCreate(savedInstanceState);10
String[] array = {"1、简单完整演示retrofit的使用",11
"2、添加Gson转换器",12
"3、添加okHttp的日志拦截器Interceptor",13
"4、使用自己封装的API,演示@Headers",14
"5、演示同步请求",15
"6、演示@Query",16
"7、演示@QueryMap",17
"8、最简单、完整的retrofit+rxJava示例",18
"9、rxJava+retrofit增强",19
"10、演示文件下载",};20
tv = new TextView(this);// 将内容显示在TextView中21
tv.setTextColor(Color.BLUE);22
getListView().addFooterView(tv);23
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new ArrayList<>(Arrays.asList(array))));24
}25
26
27
protected void onDestroy() {28
if (mSubscriptions != null) mSubscriptions.unsubscribe();29
super.onDestroy();30
}31
32
33
protected void onListItemClick(ListView l, View v, int position, long id) {34
switch (position + 1) {35
case 1://简单完整演示retrofit的使用36
requestGitHubContributorsSimple();37
break;38
case 2://添加Gson转换器39
requestGitHubContributorsByConverter();40
break;41
case 3://添加okHttp的日志拦截器Interceptor42
requestGitHubContributorsAddOkHttpLog();43
break;44
case 4://使用自己封装的API,演示@Headers45
requestGitHubContributorsAddHeader();46
break;47
case 5://演示同步请求48
requestGitHubContributorsBySync();49
break;50
case 6://演示@Query51
requestQueryRetrofitByGet(false);52
break;53
case 7://演示@QueryMap54
requestQueryRetrofitByGet(true);55
break;56
case 8://最简单、完整的retrofit+rxJava示例57
requestGitHubContributorsByRxJava();58
break;59
case 9://rxJava+retrofit增强60
requestGitHubContributorsWithFullUserInfo();61
break;62
case 10://演示文件下载63
retrofitDownload();64
break;65
}66
}67
68
/**69
* 1、简单示例70
*/71
private void requestGitHubContributorsSimple() {72
Retrofit retrofit = new Retrofit.Builder()73
.baseUrl(baseUrl)74
.build();75
GitHubApi repo = retrofit.create(GitHubApi.class);76
Call<ResponseBody> call = repo.contributorsBySimpleGetCall(mUserName, mRepo);77
call.enqueue(new Callback<ResponseBody>() {78
79
public void onResponse( Call<ResponseBody> call, Response<ResponseBody> response) {80
String result = null;81
try {82
result = response.body().string();83
if (result == null) return;84
} catch (IOException e) {85
e.printStackTrace();86
}87
tv.setText("GitHub上对项目的贡献-1:
");88
ArrayList<Contributor> list = new Gson()89
.fromJson(result, new TypeToken<List<Contributor>>() {90
}.getType());91
if (list == null || list.size() == 0) return;92
for (Contributor contributor : list) {93
tv.append(contributor.login + " " + contributor.contributions + "
");94
}95
}96
97
98
public void onFailure( Call<ResponseBody> call, Throwable t) {99
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();100
}101
});102
}103
104
/**105
* 2、添加Gson转换器106
*/107
private void requestGitHubContributorsByConverter() {108
new Retrofit.Builder()109
.baseUrl(baseUrl)110
.addConverterFactory(GsonConverterFactory.create())//转换器111
.build()112
.create(GitHubApi.class)113
.contributorsByAddConverterGetCall(mUserName, mRepo)114
.enqueue(new Callback<List<Contributor>>() {115
116
public void onResponse( Call<List<Contributor>> call, Response<List<Contributor>> response) {117
List<Contributor> list = response.body();118
tv.setText("GitHub上对项目的贡献-2:
");119
if (list == null || list.size() == 0) return;120
for (Contributor contributor : list) {121
tv.append(contributor.login + " " + contributor.contributions + "
");122
}123
}124
125
126
public void onFailure( Call<List<Contributor>> call, Throwable t) {127
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();128
}129
});130
}131
132
/**133
* 3、添加okHttp的日志拦截器Interceptor134
*/135
private void requestGitHubContributorsAddOkHttpLog() {136
HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);137
138
Retrofit retrofit = new Retrofit.Builder()139
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())140
.client(new OkHttpClient.Builder().addInterceptor(logInterceptor).build())141
.baseUrl(baseUrl)142
.addConverterFactory(GsonConverterFactory.create())143
.build();144
145
retrofit.create(GitHubApi.class)146
.contributorsByAddConverterGetCall(mUserName, mRepo)147
.enqueue(new Callback<List<Contributor>>() {148
149
public void onResponse( Call<List<Contributor>> call, Response<List<com.bqt150
.retrofit.bean.Contributor>> response) {151
List<Contributor> list = response.body();152
tv.setText("GitHub上对项目的贡献-3:
");153
if (list == null || list.size() == 0) return;154
for (Contributor contributor : list) {155
tv.append(contributor.login + " " + contributor.contributions + "
");156
}157
}158
159
160
public void onFailure( Call<List<Contributor>> call, Throwable t) {161
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();162
}163
});164
}165
166
/**167
* 4、使用自己封装的API,演示@Headers168
*/169
private void requestGitHubContributorsAddHeader() {170
createRetrofitService(GitHubApi.class)171
.contributorsAndAddHeader(mUserName, mRepo)172
.enqueue(new Callback<List<Contributor>>() {173
174
public void onResponse( Call<List<Contributor>> call, Response<List<com.bqt175
.retrofit.bean.Contributor>> response) {176
List<Contributor> list = response.body();177
tv.setText("GitHub上对项目的贡献-4:
");178
if (list == null || list.size() == 0) return;179
for (Contributor contributor : list) {180
tv.append(contributor.login + " " + contributor.contributions + "
");181
}182
}183
184
185
public void onFailure( Call<List<Contributor>> call, Throwable t) {186
}187
});188
}189
190
/**191
* 5、演示同步请求192
*/193
private void requestGitHubContributorsBySync() {194
final Call<List<Contributor>> call = createRetrofitService(GitHubApi.class)195
.contributorsByAddConverterGetCall(mUserName, mRepo);196
new Thread(() -> {197
try {198
Response<List<Contributor>> response = call.execute();//在子线程中请求网络199
final List<Contributor> list = response.body();200
runOnUiThread(() -> {201
tv.setText("GitHub上对项目的贡献-5:
");202
for (Contributor contributor : list) {203
tv.append(contributor.login + " " + contributor.contributions + "
");204
}205
});206
} catch (IOException e) {207
e.printStackTrace();208
}209
}).start();210
}211
212
/**213
* 6/7、演示@Query和@QueryMap214
*/215
private void requestQueryRetrofitByGet(boolean isQueryMap) {216
GitHubApi mGitHubService = createRetrofitService(GitHubApi.class);217
Call<RetrofitBean> call;218
if (!isQueryMap) call = mGitHubService.queryRetrofitByGetCall("retrofit", "2016-03-29", 1, 3);219
else {220
Map<String, String> queryMap = new HashMap<>();221
queryMap.put("q", "retrofit");222
queryMap.put("since", "2016-03-29");223
queryMap.put("page", "1");224
queryMap.put("per_page", "3");225
call = mGitHubService.queryRetrofitByGetCallMap(queryMap);226
}227
228
call.enqueue(new Callback<RetrofitBean>() {229
230
public void onResponse( Call<RetrofitBean> call, Response<RetrofitBean> response) {231
RetrofitBean retrofitBean = response.body();232
if (retrofitBean == null) return;233
List<Item> list = retrofitBean.getItems();234
if (list == null || list.size() == 0) return;235
236
tv.setText(new SimpleDateFormat("yyyy.MM.dd HH:mm:ss SSS", Locale.getDefault()).format(new Date()));237
tv.append("
total:" + retrofitBean.getTotalCount() + "
incompleteResults:" + retrofitBean.getIncompleteResults());238
for (Item item : list) {239
tv.append("
【name】" + item.name);240
tv.append("
【full_name】" + item.full_name);241
tv.append("
【 description】" + item.description);242
}243
}244
245
246
public void onFailure( Call<RetrofitBean> call, Throwable t) {247
}248
});249
}250
251
/**252
* 8、最简单、完整的retrofit+rxJava示例253
*/254
private void requestGitHubContributorsByRxJava() {255
createRetrofitService(GitHubApi.class)256
.contributorsByRxJava(mUserName, mRepo)//257
.subscribeOn(Schedulers.io())//258
.observeOn(AndroidSchedulers.mainThread())//259
.subscribe(new Observer<List<Contributor>>() {260
261
public void onCompleted() {262
Toast.makeText(MainActivity.this, "完成", Toast.LENGTH_SHORT).show();263
}264
265
266
public void onError(Throwable e) {267
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();268
}269
270
271
public void onNext(List<Contributor> list) {272
tv.setText("GitHub上对项目的贡献-8:
");273
for (Contributor contributor : list) {274
tv.append(contributor.login + " " + contributor.contributions + "
");275
}276
}277
});278
}279
280
/**281
* 9、rxJava+retrofit增强282
*/283
private void requestGitHubContributorsWithFullUserInfo() {284
tv.setText("");285
final GitHubApi mGitHubService = createRetrofitService(GitHubApi.class);286
287
Subscription subscription =288
mGitHubService.contributorsByRxJava(mUserName, mRepo)//289
.flatMap(new Func1<List<Contributor>, Observable<Contributor>>() {290
//变换:将事件序列中的对象或整个序列进行加工处理,转换成不同的事件或事件序列291
292
public Observable<Contributor> call(List<Contributor>293
contributors) {294
//1、使用传入的事件对象创建一个 Observable 对象;295
//2、并不发送这个 Observable,而是将它激活,于是它开始发送事件;296
//3、创建的 Observable 发送的事件,都被汇入同一个 Observable,而这个 Observable 负责将这些事件统一交给Subscriber 的回调方法297
return Observable.from(contributors);298
}299
})300
.flatMap(new Func1<Contributor, Observable<Pair<User, Contributor>>>() {301
302
public Observable<Pair<User, Contributor>> call(com.bqt303
.retrofit.bean.Contributor contributor) {304
Observable<User> userObservable = mGitHubService.userByRxJava(contributor.login)305
.filter(user -> !isEmpty(user.name) && !isEmpty(user.email));306
return Observable.zip(userObservable, Observable.just(contributor), Pair::new);307
}308
})309
.subscribeOn(Schedulers.newThread())//指定 subscribe() 发生在哪个线程,后台线程取数据,主线程显示310
.observeOn(AndroidSchedulers.mainThread())//指定 Subscriber 的回调发生在主线程311
.subscribe(new Observer<Pair<User, Contributor>>() {312
313
public void onCompleted() {314
Toast.makeText(MainActivity.this, "完成", Toast.LENGTH_SHORT).show();315
}316
317
318
public void onError(Throwable e) {319
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();320
}321
322
323
public void onNext(Pair<User, Contributor> pair) {324
User user = pair.first;325
Contributor contributor = pair.second;326
tv.append("name:" + user.name + "
contributions:" + contributor.contributions + "
Email:" + user.email + "
");327
}328
});329
mSubscriptions.add(subscription);330
}331
332
/**333
* 10、演示文件下载334
*/335
public void retrofitDownload() {336
//监听下载进度337
final ProgressDialog dialog = new ProgressDialog(this);338
dialog.setProgressNumberFormat("%1d KB/%2d KB");339
dialog.setTitle("下载");340
dialog.setMessage("正在下载,请稍后...");341
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);342
dialog.setCancelable(false);343
dialog.show();344
345
ProgressHelper.setProgressHandler(new DownloadProgressHandler() {346
347
protected void onProgress(long bytesRead, long contentLength, boolean done) {348
//在主线程中运行349
dialog.setMax((int) (contentLength / 1024));350
dialog.setProgress((int) (bytesRead / 1024));351
if (done) dialog.dismiss();352
}353
});354
355
Retrofit retrofit = new Retrofit.Builder()//356
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//357
.addConverterFactory(GsonConverterFactory.create())//358
.baseUrl("http://msoftdl.360.cn")359
.client(ProgressHelper.addProgress(null).build())360
.build();361
362
retrofit.create(GitHubApi.class).retrofitDownload()363
.enqueue(new Callback<ResponseBody>() {364
365
public void onResponse( Call<ResponseBody> call, Response<ResponseBody> response) {366
try {367
InputStream is = response.body().byteStream();368
File file = new File(Environment.getExternalStorageDirectory(), "12345.apk");369
FileOutputStream fos = new FileOutputStream(file);370
BufferedInputStream bis = new BufferedInputStream(is);371
byte[] buffer = new byte[1024];372
int len;373
while ((len = bis.read(buffer)) != -1) {374
fos.write(buffer, 0, len);375
fos.flush();376
}377
fos.close();378
bis.close();379
is.close();380
} catch (IOException e) {381
e.printStackTrace();382
}383
}384
385
386
public void onFailure( Call<ResponseBody> call, Throwable t) {387
}388
});389
}390
391
public static <T> T createRetrofitService(final Class<T> service) {392
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor()393
.setLevel(HttpLoggingInterceptor.Level.BODY);394
OkHttpClient.Builder builder = new OkHttpClient.Builder().addInterceptor(httpLoggingInterceptor);395
Retrofit retrofit = new Retrofit.Builder()//396
.client(ProgressHelper.addProgress(builder).build())//397
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//398
.addConverterFactory(GsonConverterFactory.create())//399
.baseUrl("https://api.github.com/")//400
.build();401
return retrofit.create(service);402
}403
}综合配置
retrofit、okhttp、RxJava、Gson、拦截器、Header等配置
public class H {
private static Interceptor buildInterceptor() {
final String token = AccountManager.getInstance().getToken();
PackageInfo packInfo = null;
try {
packInfo = App.app.getPackageManager().getPackageInfo(App.app.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
final int version = packInfo == null ? 1 : packInfo.versionCode;
return new Interceptor() {//应用程序拦截器,只被调用一次
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request()
.newBuilder()
.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
.addHeader("Accept-Encoding", "gzip, deflate")
.addHeader("Connection", "keep-alive")
.addHeader("Accept", "*/*")
//****************************************自定义Header**************************************************
.addHeader("version", version + "")//app版本号
.addHeader("token", token == null ? "" : token)//登录后返回的token
.addHeader("mobile", "1")// 0-PC,1-Android,2-IOS,3-web
.build();
return chain.proceed(request);
}
};
}
private static Interceptor buildLogInterceptor() {
return new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
L.i(message);
}
}).setLevel(HttpLoggingInterceptor.Level.BODY);//日志显示级别
}
private static OkHttpClient buildOkHttp() {
return new OkHttpClient.Builder()
.addInterceptor(buildHeaderInterceptor())//自定义Header
.addInterceptor(buildLogInterceptor())//日志拦截
.connectTimeout(5, TimeUnit.SECONDS)
.build();
}
private static Gson buildGson() {
return new GsonBuilder()//配置你的Gson
.setDateFormat("yyyy-MM-dd hh:mm:ss")
.setPrettyPrinting()
.serializeNulls()
.create();
}
private static String buildBaseUrl() {
switch (UrlHelper.getEnv()) {
case 0: // baseUlr 必须以 / 结束,不然会抛出一个IllegalArgumentException
return "http://test.talk.99cj.com.cn/";
case 1:
return "http://wechat.99cj.com.cn/";
default:
return "http://wechat.99cj.com.cn/";
}
}
private static Retrofit buildRetrofit(OkHttpClient client, Converter.Factory converterFactory, CallAdapter.Factory callAdapterFactory) {
return new Retrofit.Builder()
.baseUrl(buildBaseUrl())
.client(client)
.addConverterFactory(converterFactory)//可以接收自定义的Gson,当然也可以不传
.addCallAdapterFactory(callAdapterFactory)
.build();
}
private static <T> T createRetrofitService(final Class<T> service) {
Retrofit retrofit = buildRetrofit(buildOkHttp(), //
GsonConverterFactory.create(buildGson()),//
RxJavaCallAdapterFactory.create());//
return retrofit.create(service);
}
public static BqtService h() {
return createRetrofitService(BqtService.class);
}
}x
1
public class H {2
private static Interceptor buildInterceptor() {3
final String token = AccountManager.getInstance().getToken();4
PackageInfo packInfo = null;5
try {6
packInfo = App.app.getPackageManager().getPackageInfo(App.app.getPackageName(), 0);7
} catch (PackageManager.NameNotFoundException e) {8
e.printStackTrace();9
}10
final int version = packInfo == null ? 1 : packInfo.versionCode;11
return new Interceptor() {//应用程序拦截器,只被调用一次12
13
public okhttp3.Response intercept(Chain chain) throws IOException {14
Request request = chain.request()15
.newBuilder()16
.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")17
.addHeader("Accept-Encoding", "gzip, deflate")18
.addHeader("Connection", "keep-alive")19
.addHeader("Accept", "*/*")20
//****************************************自定义Header**************************************************21
.addHeader("version", version + "")//app版本号22
.addHeader("token", token == null ? "" : token)//登录后返回的token23
.addHeader("mobile", "1")// 0-PC,1-Android,2-IOS,3-web24
.build();25
return chain.proceed(request);26
}27
};28
}29
30
private static Interceptor buildLogInterceptor() {31
return new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {32
33
public void log(String message) {34
L.i(message);35
}36
}).setLevel(HttpLoggingInterceptor.Level.BODY);//日志显示级别37
}38
39
private static OkHttpClient buildOkHttp() {40
return new OkHttpClient.Builder()41
.addInterceptor(buildHeaderInterceptor())//自定义Header42
.addInterceptor(buildLogInterceptor())//日志拦截43
.connectTimeout(5, TimeUnit.SECONDS)44
.build();45
}46
47
private static Gson buildGson() {48
return new GsonBuilder()//配置你的Gson49
.setDateFormat("yyyy-MM-dd hh:mm:ss")50
.setPrettyPrinting()51
.serializeNulls()52
.create();53
}54
55
private static String buildBaseUrl() {56
switch (UrlHelper.getEnv()) {57
case 0: // baseUlr 必须以 / 结束,不然会抛出一个IllegalArgumentException58
return "http://test.talk.99cj.com.cn/";59
case 1:60
return "http://wechat.99cj.com.cn/";61
default:62
return "http://wechat.99cj.com.cn/";63
}64
}65
66
private static Retrofit buildRetrofit(OkHttpClient client, Converter.Factory converterFactory, CallAdapter.Factory callAdapterFactory) {67
return new Retrofit.Builder()68
.baseUrl(buildBaseUrl())69
.client(client)70
.addConverterFactory(converterFactory)//可以接收自定义的Gson,当然也可以不传71
.addCallAdapterFactory(callAdapterFactory)72
.build();73
}74
75
private static <T> T createRetrofitService(final Class<T> service) {76
Retrofit retrofit = buildRetrofit(buildOkHttp(), //77
GsonConverterFactory.create(buildGson()),//78
RxJavaCallAdapterFactory.create());//79
return retrofit.create(service);80
}81
82
public static BqtService h() {83
return createRetrofitService(BqtService.class);84
}85
}添加上述【HttpLoggingInterceptor】拦截器后会打印如下日志

请求参数封装
public interface BqtService {
/*个人中心*/ /* 如果注解中提供的url是完整的url(以http开头),则忽略baseUrl,直接讲此url将作为请求的url */
@GET("User") /* 如果不以/开头,则请求的url为baseUrl+注解中提供的值;否则请求的url为baseUrl的主机部分+注解中提供的值*/
Observable<BqtRes<User>> getUser();
/*用户购买记录*/
@FormUrlEncoded
@POST("BuyInfo/buyRecord") /*【type】1:购买课程 2:购买观点 3:直播赞赏*/
Observable<BqtRes<ArrayList<MyClassBean>>> getPurchaseHistory1(@Field("user_id") int uid, @Field("page") int page, @Field("type") int type);
}x
10
1
public interface BqtService {2
/*个人中心*/ /* 如果注解中提供的url是完整的url(以http开头),则忽略baseUrl,直接讲此url将作为请求的url */3
("User") /* 如果不以/开头,则请求的url为baseUrl+注解中提供的值;否则请求的url为baseUrl的主机部分+注解中提供的值*/4
Observable<BqtRes<User>> getUser();5
6
/*用户购买记录*/7
8
("BuyInfo/buyRecord") /*【type】1:购买课程 2:购买观点 3:直播赞赏*/9
Observable<BqtRes<ArrayList<MyClassBean>>> getPurchaseHistory1(("user_id") int uid, ("page") int page, ("type") int type);10
}调用
H.h().getUser()
.subscribeOn(Schedulers.newThread())//指定 subscribe() 发生在哪个线程,后台线程取数据,主线程显示
.observeOn(AndroidSchedulers.mainThread())//指定 Subscriber 的回调发生在主线程
.subscribe(new Subscriber<BqtRes<User>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
L.i("【onError】" + e.toString());
}
@Override
public void onNext(BqtRes<User> response) {
L.i("【onNext】" + response.data.toString());//这里response.data的类型即是User
}
});18
1
H.h().getUser()2
.subscribeOn(Schedulers.newThread())//指定 subscribe() 发生在哪个线程,后台线程取数据,主线程显示3
.observeOn(AndroidSchedulers.mainThread())//指定 Subscriber 的回调发生在主线程4
.subscribe(new Subscriber<BqtRes<User>>() {5
6
public void onCompleted() {7
}8
9
10
public void onError(Throwable e) {11
L.i("【onError】" + e.toString());12
}13
14
15
public void onNext(BqtRes<User> response) {16
L.i("【onNext】" + response.data.toString());//这里response.data的类型即是User17
}18
});2017-9-22