<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的日志拦截器Interceptor
42
requestGitHubContributorsAddOkHttpLog();
43
break;
44
case 4://使用自己封装的API,演示@Headers
45
requestGitHubContributorsAddHeader();
46
break;
47
case 5://演示同步请求
48
requestGitHubContributorsBySync();
49
break;
50
case 6://演示@Query
51
requestQueryRetrofitByGet(false);
52
break;
53
case 7://演示@QueryMap
54
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的日志拦截器Interceptor
134
*/
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.bqt
150
.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,演示@Headers
168
*/
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.bqt
175
.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和@QueryMap
214
*/
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.bqt
303
.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)//登录后返回的token
23
.addHeader("mobile", "1")// 0-PC,1-Android,2-IOS,3-web
24
.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())//自定义Header
42
.addInterceptor(buildLogInterceptor())//日志拦截
43
.connectTimeout(5, TimeUnit.SECONDS)
44
.build();
45
}
46
47
private static Gson buildGson() {
48
return new GsonBuilder()//配置你的Gson
49
.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 必须以 / 结束,不然会抛出一个IllegalArgumentException
58
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的类型即是User
17
}
18
});
2017-9-22