retrofit2使用笔记

retrofit2 使用笔记

导包

1
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'

GET请求

1
2
3
4
5
6
7
8
9
10
11
12
13
注解规则
BaseURL 和@PATH 不是简单的拼接
而是和<a href="..">的处理方式一样</a>
BaseURL总是以“/”结尾
@URL 不要以“/”结尾
@POST("list") .baseUrl("http://api.nuuneui.com/base/level1") ----->http://api.nuuneui.com/base/list
@POST("list") .baseUrl("http://api.nuuneui.com/base/level1/") ----->http://api.nuuneui.com/base/level1/list
@POST("/list") 绝对跟路径 直接追加到url跟路径下
.baseUrl("http://api.nuuneui.com/base/level1/")------->http://api.nuuneui.com/list
public static final String URL_BASE = "http://m2.qiushibaike.com/“;//baseurl

GET无参数的请求

1
2
3
@GET("article/list/latest?page=1")
Call<ResponseBody> getLatesJsonString();

GET有参数的请求

1
2
@GET("article/list/{type}?")
Call<Model> getInfoList(@Path("type") String type, @Query("page") int page);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constant.URL_BASE)
.addConverterFactory(GsonConverterFactory.create())//json解析 .build(); MyServerInterface myServerInterface = retrofit.create(
MyServerInterface.class)
modelcall = myServerInterface.getInfoList("latest", 1); modelcall.enqueue(new Callback<Model>() {
@Override public void onResponse(Response<Model> response, Retrofit retrofit) {
if (response.isSuccess() && response.body() != null) {
List<Model.ItemsBean> items = response.body().getItems(); tv.setText(items.toString()); }
}
@Override public void onFailure(Throwable t) {
}
});//两个参数的用法// Call<ResponseBody> call = myServerInterface.getLatesJsonString();// call.enqueue(new Callback<ResponseBody>() {// @Override// public void onResponse(Response<ResponseBody> response, Retrofit retrofit) {//主线程// if (response.isSuccess()) {// try {// String result = response.body().string();// tv.setText(result);// } catch (IOException e) {// e.printStackTrace();// }// }// }//// @Override// public void onFailure(Throwable t) {//// }
// });//无参数的用法

GET请求

提交表单数据 方法中定义@QueryMap参数 @QueryMap在url后将在url后面追加类似”type=text&count=30&page=1“的字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@GET()
@GET("MyWeb/RegServlet")//服务器的路径
Call<ResponseBody> getRegInfo(@QueryMap Map<String, String> map);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constant.URL_BASE)//服务器地址 .addConverterFactory(GsonConverterFactory.create())//json解析 .build();MyServerInterface myServerInterface = retrofit.create(MyServerInterface.class);Map<String, String> map = new HashMap<String, String>();map.put("user","asd");map.put("id","1");map.put("pwd", "111");final Call<ResponseBody> regInfo = myServerInterface.getRegInfo(map);regInfo.enqueue(new Callback<ResponseBody>() {
@Override public void onResponse(Response<ResponseBody> response, Retrofit retrofit) {
if (response.isSuccess()&&response.body()!=null){
try {
tv.setText(response.body().string()); } catch (IOException e) {
e.printStackTrace(); }
}
}
@Override public void onFailure(Throwable t) {
}
});

下载图片

1
Call<ResponseBody> getNetworkData(@Url String urlString);

这种格式@GET后面不用写网址 在参数前面加上@Url

1
@GET("http://img.265g.com/userup/1201/201201071126534773.jpg") baseurl无效
1
Call<ResponseBody> getNetworkData();

这两个一样效果

第一个用传参数

第二个不需要传参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
call_bm = serverInterface.getNetworkData(Constant.URL_DOWNLOAD_IMAGE);
call_bm.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//进入主线程
Log.i("TAG", "---->onResponse::" + Thread.currentThread().getName());
//将下載后的文件保存进SD卡
String fileName = Constant.URL_DOWNLOAD_IMAGE.substring(Constant.URL_DOWNLOAD_IMAGE.lastIndexOf("/") + 1);
final boolean flag;
try {
flag = SDCardHelper.saveFileToSDCardPrivateCacheDir(response.body().bytes(), fileName, mContext);
Toast.makeText(mContext, "结果:" + flag, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(mContext, "下載圖片失敗!:" + t.toString(), Toast.LENGTH_SHORT).show();
}
});

下载大文件会导致异常 网络访问在主线程时间过长

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Streaming
@GET
Call<ResponseBody> getNetWorkDataAsync(@Url String urlString)
new Thread(new Runnable() {
@Override public void run() {
Call<ResponseBody> call_downBig = myServerInterface.getNetDataAsync("http://123.57.44.15:8085/webblue/uploads/1410202333730abc.mp4"); try {
Response<ResponseBody> execute = call_downBig.execute(); InputStream is = execute.body().byteStream(); String fileName = "http://123.57.44.15:8085/webblue/uploads/1410202333730abc.mp4".substring("http://123.57.44.15:8085/webblue/uploads/1410202333730abc.mp4".lastIndexOf("/") + 1); boolean iasuccess = SDCardHelper.saveFileToSDCardPrivateCacheDir(is, fileName, MainActivity.this); if (iasuccess) {
Intent intent = new Intent();
intent.setAction("aroen.com.retrofittexr”);//发送广播 提醒下载后打开
Bundle bundle = new Bundle(); bundle.putString("path", SDCardHelper.getSDCardPrivateCacheDir(context) + File.separator + fileName); intent.putExtras(bundle); sendBroadcast(intent); }
} catch (IOException e) {
e.printStackTrace(); }
}
}).start();
}

广播代码

1
2
3
4
5
6
7
8
9
10
11
12
public class Recrver extends BroadcastReceiver {
private String Path = "";
@Override public void onReceive(final Context context, final Intent intent) {
if (intent.getExtras() != null) {
Path = intent.getExtras().getString("path"); }
AlertDialog.Builder builder = new AlertDialog.Builder(context)
.setIcon(R.mipmap.ic_launcher)
.setTitle("提示").setMessage("是否播放").setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override public void onClick(DialogInterface dialog, int which) {
Intent intent1 = new Intent(); intent1.setAction("android.intent.action.VIEW"); intent1.setDataAndType(Uri.fromFile(new File(Path)), "video/*"); context.startActivity(intent); }
}); }
}

动态注册广播

1
2
3
4
recrver = new Recrver();
registerReceiver(recrver, new IntentFilter("aroen.com.retrofittexr"));
在onDestroy中解除注册
unregisterReceiver(recrver);//动态注册 要在onDestroy中取消

POST请求

方法中定义@Filed 参数,分别指定各个表单控件名称

1
2
3
@FormUrlEncoded
@POST(“MyWeb/RegServlet")
Call<ResponseBody> postFormFileds(@Field(“username”) String username,@Field(“password) String password,@Field(“age”) String age);
1
2
3
@FormUrlEncoded
@POST(“MyWeb/RegServlet")
Call<ResponseBody> postFormFiledMap(@FieldMap Map<String,String> options);

上传文件 @Part 该参数 指定 file控件 的名称及上传后文件的名称

1
2
3
4
5
6
7
8
9
10
@Multipart
@POST(“MyWeb/RegServlet")
Call<ResponseBody> postUploadFile(@Part ( “uploadfile\”;filename=\ “image.png”)RequestBody requestBody);
@Body参数 向服务器上传多个文件以及其他表单域数据
@POST(“MyWeb/RegServlet")
Call<ResponseBody> postUploadFilesMultipartBody(@Body MultipartBody multipartBidy);
Content-Disposition:form-data;name=“控件域名称”;filename=“xxx.png”
Cogent-Type:image/pjpeg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//POST请求数据 String username = "zhy"; String pwd = "123"; String age = "10";
Map<String, String> map = new HashMap<String, String>();
map.put("username", username); map.put("pwd", pwd); map.put("age", age);// Call<ResponseBody> responseBodyCall = myServerInterface.postFormFiled(username, pwd, age); Call<ResponseBody> responseBodyCallmap = myServerInterface.postFormFileMap(map);
responseBodyCallmap.enqueue(new Callback<ResponseBody>() {
@Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful() && response.body() != null) {
try {
tv.setText(response.body().string()); } catch (IOException e) {
e.printStackTrace(); }
}
}
@Override public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
//POST上传单个文件 File file = new File("path"); RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file); Call<ResponseBody> responseBodyCall = myServerInterface.postUploadFile(requestBody); responseBodyCall.enqueue(new Callback<ResponseBody>() {
@Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful() && response.body() != null) {
}
}
@Override public void onFailure(Call<ResponseBody> call, Throwable t) {
}
}); //POST上传多个文件 File[] files = new File[]{new File("path")}; String[] formFiledName = new String[]{"uploadfile"};//服务器对应的名字 控件域名称 //获取MulitpaRTBody MultipartBody multipartBody = buildMultipartBody(map, files, formFiledName); Call<ResponseBody> responseBodyCall1 = myServerInterface.postUploadFilesMultipartBody(multipartBody); responseBodyCall1.enqueue(new Callback<ResponseBody>() {
@Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
}
@Override public void onFailure(Call<ResponseBody> call, Throwable t) {
}
}); }
private MultipartBody buildMultipartBody(Map<String, String> map, File[] files, String[] formFiledName) {
MultipartBody.Builder builder = new MultipartBody.Builder(); //往MultipartBuilder对象中添加普通input控件的内容 if (map != null) {
for (Map.Entry<String, String> entry : map.entrySet()) {
//添加普通input块的数据 builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + entry.getKey() + "\""), RequestBody.create(null, entry.getValue())); }
}
//往MultipartBuilder对象中添加上传控件的内容 if (files != null && formFiledName != null) {
for (int i = 0; i < files.length; i++) {
File file = files[i]; String fileName = file.getName(); RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file); //添加file input块的数据 builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + formFiledName[i] + "\"; filename=\"" + fileName + "\""), requestBody); }
}
return builder.build();
}

和piasso一起使用的优化。定于okhttp3的工具类。获取单例对象 然后在retrofit创建的时候client(client)。 piasso初始化的时候需要定义downloader。downloader里的okhttp对象通过okhttp3的工具类取得。然后添加一个无参数的构造方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
public class OkHttp3Utils {
private static OkHttpClient okHttpClient = null;
public static OkHttpClient getOkHttpSingletonInstance() {
if (okHttpClient == null) {
synchronized (OkHttpClient.class) {
if (okHttpClient == null) {
okHttpClient = new OkHttpClient();
}
}
}
return okHttpClient;
}
}
public class MyDownLoader implements Downloader {
private static OkHttpClient defaultOkHttpClient() {
OkHttpClient client = OkHttp3Utils.getOkHttpSingletonInstance();
Log.d("MyOKHttpDownloader", "---->defaultOkHttpClient(): " + client.toString());
return client;
}
private final OkHttpClient client;
public MyDownLoader() {
this(defaultOkHttpClient());
}
/**
* Create a new downloader that uses the specified OkHttp instance. A response cache will not be
* automatically configured.
*/
public MyDownLoader(OkHttpClient client) {
this.client = client;
}
protected final OkHttpClient getClient() {
return client;
}
@Override public Response load(Uri uri, int networkPolicy) throws IOException {
CacheControl cacheControl = null;
if (networkPolicy != 0) {
if (NetworkPolicy.isOfflineOnly(networkPolicy)) {
cacheControl = CacheControl.FORCE_CACHE;
} else {
CacheControl.Builder builder = new CacheControl.Builder();
if (!NetworkPolicy.shouldReadFromDiskCache(networkPolicy)) {
builder.noCache();
}
if (!NetworkPolicy.shouldWriteToDiskCache(networkPolicy)) {
builder.noStore();
}
cacheControl = builder.build();
}
}
Request.Builder builder = new Request.Builder().url(uri.toString());
if (cacheControl != null) {
builder.cacheControl(cacheControl);
}
okhttp3.Response response = client.newCall(builder.build()).execute();
int responseCode = response.code();
if (responseCode >= 300) {
response.body().close();
throw new ResponseException(responseCode + " " + response.message(), networkPolicy,
responseCode);
}
boolean fromCache = response.cacheResponse() != null;
ResponseBody responseBody = response.body();
return new Response(responseBody.byteStream(), fromCache, responseBody.contentLength());
}
@Override public void shutdown() {
okhttp3.Cache cache = client.cache();
if (cache != null) {
try {
cache.close();
} catch (IOException ignored) {
}
}
}
}

MainActivity中设置

1
2
3
4
5
6
7
8
9
OkHttpClient client = OkHttp3Utils.getOkHttpSingletonInstance();
Log.i(TAG, "---->initRetrofit: " + client.toString());
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constant.URL_BASE)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
serverInterface = retrofit.create(MyServerInterface.class);