Retrofit 的大名大家都听说了吧! 一个封装非常好的网络框架,在网上搜索的关于Retrofit的文章一般都是对有基础的人看着很爽,对于注解什么的有些不太懂的看着有点懵。这是一篇介绍Retrofit 入门的文章,如果对于Retrofit懂的可以绕行。
有能力的自己看看官网文档 http://square.github.io/retrofit/
对于网络请求框架,最主要的功能就是,get请求,post请求,上传文件和下载文件。
文章的内容来自于http://www.kgc.cn/android/29105.shtml,花了9元买的。由于里面的后台有点不会搭,这里的请求网络,用的是http://www.jianshu.com/p/c0ec2a7fc26a这是个大神的博客,我用的是里面讲的一个项目天天防腐中的请求接口。对于上传文件我用的是尚硅谷http://www.atguigu.com/网络框架中上传文件的文件用的是tomcat搭建的。
get和post请求的接口是http://v2.ffu365.com/index.php?m=Api&c=Team&a=teamList&appid=1&page=1&pagesize=10
对于get和post请求界面如下
注解关键字
[1] get请求不带参数
在当前包下新建一个包 api,创建一个接口 NetService这里要说一下Retrofit是分BaseUrl和后面的对于上面的请求接口http://v2.ffu365.com/就是BaseUrl,BaseUrl必须以 / 结尾,所以上面的接口去掉 BaseUrl应该是index.php?m=Api&c=Team&a=teamList&appid=1&page=1 &pagesize=10 所以,接口可以写为
public interface NetService {
/**
* get 请求不带参数,采用拼接的形式请求网络
* @GET 是在 baseUrl后面直接拼接的字段
*ResponseBody是okhttp中的
*/
@GET("index.php?m=Api&c=Team&a=teamList&appid=1&page=1&pagesize=10")
Call<ResponseBody> getAppInfo();
}
接口写完后开始在activity中调用
public static final String BASE_URL="http://v2.ffu365.com/";
private Retrofit mRetrofit;
private NetService mNetService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRetrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.build();//获取Retrofit
mNetService = mRetrofit.create(NetService.class);//通过注解获取定义的接口
}
/**
* 按钮点击事件:get请求不带参数
*/
public void getAppInfo(View view){
Call<ResponseBody> call = mNetService.getAppInfo();
execute(call);
}
/**
* 执行call返回方法
* @param call
*/
private void execute(Call<ResponseBody> call) {
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
String string = null;
try {
string = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
Log.e(TAG, "onResponse: "+string);
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable throwable) {
}
});
}
[2] get请求带有参数,定长
/**
* get 请求,带有参数,参数的长度不变,值可能会变化
* @GET 是在 baseUrl后面直接拼接的字段
* @Query() 里面的字段是参数名,后面的定义参数类型,通过方法传递参数名的值
*/
@GET("index.php?m=Api&c=Team&a=teamList")
Call<ResponseBody> getInfoByParamsQuery(@Query("appid")int appid,@Query("page")int page,@Query("pagesize")int pagesize);
/**
* get请求带有参数,参数长度不可变
*/
public void getInfoByParamsQuery(View view){
Call<ResponseBody> call = mNetService.getInfoByParamsQuery(1,2,10);
execute(call);
}
[3] get请求带有参数,不定长度
/**
* get 请求,带有参数,参数的长度可变
* 前面的map是String,String类型,后面的map是String,Integer类型
*/
@GET("index.php?m=Api")
Call<ResponseBody> getInfoByParamsQueryMap(@QueryMap Map<String,String> strMap,@QueryMap Map<String,Integer> intParmars);
/**
* get请求带有参数,参数长度可变
*/
public void getInfoByParamsQueryMap(View view){
Map<String, String> strParmars = new HashMap<>();
strParmars.put("c","Team");
strParmars.put("a", "teamList");
Map<String, Integer> parmars = new HashMap<>();
parmars.put("appid",1);
parmars.put("page",1);
parmars.put("pagesize", 5);
Call<ResponseBody> call = mNetService.getInfoByParamsQueryMap(strParmars,parmars);
execute(call);
}
[4] post请求
/**
* post 请求,通过表单,请求
*/
@POST("index.php?m=Api&c=Team&a=teamList")
@FormUrlEncoded
Call<ResponseBody> login(@Field("appid") int appid,@Field("page") int page,@Field("pagesize") int pagesize);
/**
* post 请求带有参数,参数长度不可变
*/
public void login(View view){
Call<ResponseBody> call = mNetService.login(1,2,5);
execute(call);
}
[5]使用gson将返回的数据转换成自己想要的格式
/**
* post请求,并将返回结果转换成自己想要的格式
*/
@POST("index.php?m=Api&c=Team&a=teamList")
@FormUrlEncoded
Call<Result> format(@Field("appid") int appid,@Field("page") int page,@Field("pagesize") int pagesize);
/**
* post请求,将结果转换成自己想要的类型
*/
public void format(View view){
//上面的如果创建了Retrofit,这里请求会失效
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
NetService service = retrofit.create(NetService.class);
Call<Result> call = service.format(1,2,5);
call.enqueue(new Callback<Result>() {
@Override
public void onResponse(Call<Result> call, Response<Result> response) {
Log.e(TAG, "onResponse: "+response.body().getData().getList().get(0).getTeam_name());
}
@Override
public void onFailure(Call<Result> call, Throwable throwable) {
}
});
}
上传文件和下载文件
上传文件的服务,文件链接:http://pan.baidu.com/s/1bYvU3c 密码:ypnt将里面的文件解压会有怎样使用
上传和下载界面
注解关键字
[1]上传文件
和上面的差不多,区别就是注解的不同, 在api中新建一个FileService接口实现如下
public interface FileService {
/**
* 上传文件,如果上传文件同时需要上传相应的文字可以用 @Part("字段") RequestBody body
*/
@Multipart
@POST("FileUploadServlet")
Call<ResponseBody> uploadFile(@Part MultipartBody.Part body);
}
在Activity中
/**
* base_url 是以 / 结尾的
*/
public static final String BASE_URL = "http://192.168.200.101:8080/FileUpload/";
private Retrofit mRetrofit;
private FileService mFileService;
public static final int REQUEST_CODE = 0x0011;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PermissionHelper.with(this)
.requestCode(REQUEST_CODE)
.requestPermission(new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
})
.request();
mRetrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.build();
mFileService = mRetrofit.create(FileService.class);
}
/**
* 上传单个文件
*/
public void uploadFile(View view) {
File file = new File(Environment.getExternalStorageDirectory(), "image1.jpg");
if (file == null) {
Toast.makeText(this, "文件为空", Toast.LENGTH_SHORT).show();
}
RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part part = MultipartBody.Part
.createFormData("image", file.getName(), body);
Call<ResponseBody> call=mFileService.uploadFile(part);
execute(call);
}
[2]上传两个文件
/**
* 上传两个文件
*/
@Multipart
@POST("FileUploadServlet")
Call<ResponseBody> uploadFileTwo(@Part MultipartBody.Part file1,@Part MultipartBody.Part file2);
/**
* 上传两个文件
*/
public void uploadFileTwo(View view) {
File file = new File(Environment.getExternalStorageDirectory(), "image1.jpg");
if (file == null) {
Toast.makeText(this, "文件为空", Toast.LENGTH_SHORT).show();
}
RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part part = MultipartBody.Part
.createFormData("image", file.getName(), body);
File file1 = new File(Environment.getExternalStorageDirectory(), "image1.jpg");
if (file == null) {
Toast.makeText(this, "文件为空", Toast.LENGTH_SHORT).show();
}
RequestBody body1 = RequestBody.create(MediaType.parse("multipart/form-data"), file1);
MultipartBody.Part part1 = MultipartBody.Part
.createFormData("image", file.getName(), body1);
Call<ResponseBody> call = mFileService.uploadFileTwo(part, part1);
execute(call);
}
[3]上传多个文件
/**
* 上传多个文件
*/
@Multipart
@POST("FileUploadServlet")
Call<ResponseBody> uploadFileMore(@Part List<MultipartBody.Part> files);
/**
* 上传多个文件
*/
public void uploadFileMore(View view) {
File file = new File(Environment.getExternalStorageDirectory(), "image1.jpg");
if (file == null) {
Toast.makeText(this, "文件为空", Toast.LENGTH_SHORT).show();
}
RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part part = MultipartBody.Part
.createFormData("image", file.getName(), body);
File file1 = new File(Environment.getExternalStorageDirectory(), "image1.jpg");
if (file == null) {
Toast.makeText(this, "文件为空", Toast.LENGTH_SHORT).show();
}
RequestBody body1 = RequestBody.create(MediaType.parse("multipart/form-data"), file1);
MultipartBody.Part part1 = MultipartBody.Part
.createFormData("image", file.getName(), body1);
List<MultipartBody.Part> parts = new ArrayList<>();
parts.add(part);
parts.add(part1);
Call<ResponseBody> call=mFileService.uploadFileMore(parts);
execute(call);
}
[4]下载文件
/**
* 下载文件
*/
@GET("a.jpg")
Call<ResponseBody> filedownload();
/**
* 下载文件
*/
public void filedownload(View view) {
Call<ResponseBody> call = mFileService.filedownload();
execute(call);
}
动态获取资讯,什么意思?就是你的网址中有一部分是经常改变的,而其他的并不需要改变,如下面的index.php需要改变,而后面的参数不需要做出改变。
[1]动态获取资讯
/**
* 动态获取对象服务,
* 对于后面的 带= 的不能使用{} 来代替否则会报下面的错误
* must not have replace block.
* 对于可以变化的部分可以用{type} 和 @Path("type") 来动态获取
*/
@GET("{address}?m=Api&c=Team&a=teamList&appid=1&page=1&pagesize=5")
Call<ResponseBody> getInfo(@Path("address")String address);
/**
* 动态获取咨询
*/
public void getInfo(View view) {
Retrofit retrofit=new Retrofit.Builder()
.baseUrl("http://v2.ffu365.com/")
.build();
FileService fileService=retrofit.create(FileService.class);
Call<ResponseBody> call=fileService.getInfo("index.php");
execute(call);
}
[2] 动态通过url获取资讯,什么意思,就是: 你知道 BaseUrl后面的不清楚,通过方法传递 后面的url过来进行拼接
/**
* 动态获取对象
*/
@GET
Call<ResponseBody> getInfoByUrl(@Url String ulr);
/**
* 动态获取资讯,通过封装的进行调用
*/
public void getInfoByUrl(View view) {
FileService fs = (FileService) RetrofitManager.getInstance().getApiService(FileService.class);
Call<ResponseBody> call = fs.getInfoByUrl("index.php?m=Api&c=Team&a=teamList&appid=1&page=1&pagesize=10");
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.e(TAG, "onResponse: "+response.body().string());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}