Retrofit的使用,及介绍:
一,概念描述及理解:
Retrofit的底层是封装的okhttp是对okhttp的封装其内置okhttp框架,说retrfit是网络请求的框架在这里是不准确的,其实在这里网络请求还是使用的okhttp,Retrofit的作用在于网络请求的高效,二者分工协作,宛如古人的『你耕地来我织布』
这里我写了大约7--8中小的案例,大家需要哪一种可以跳过不需要的部分,直接忽略:
我简单的描述一下如何使用吧,它的使用其实很简单,
1首先你要拿到一个根路径,
2之后你要通过各种方式拼凑路径
3拼凑是在@get注解中完成的,如果不需要参数,直接在注解中填入,抽象方法中就不需要参数了,
4如果需要各种参数,或者类型,get中的子路径获取需要经过各种拼凑,拼凑的数据需要用户输入,这时候,就将参数以形参的方式闯进抽象方法中,但是抽象方法中的形参也需要使用不同的注解,至于什么是注解这里我就不详细说了,毕竟本章是讲解Retrofit,代码量太大了
简单的说到这里,下面进行详细的代码描述;
请牢记你需要的的案例的抽象方法名,不然我相信你会凌乱的;记住方法名到主方法中去寻找案例吧。
二,具体使用步骤:
1,添加依赖:
compile 'com.squareup.retrofit2:retrofit:2.0.2'
2,创建接口(名称随意,见名知义):
在接口中通过注解的方式,指定url,或者url中的一部分,在创建接口之前,先创建个url类用来盛放各种需要的url,这里我准备了几个url,可能只会用到其中一两个而已,
先贴出来共享下:
public class Constant {
//荔枝新闻的完成的url地址
public final static String URL="http://litchiapi.jstv.com/" +
"api/GetFeeds?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41";
//荔枝新闻的跟路径
public final static String BASE_URL="http://litchiapi.jstv.com/";
//茶叶品牌 http://42.120.4.67/api/app/business/category?app_id=161
public final static String TEABASE_URL="http://42.120.4.67/api/app/business/";
//下载图片地址
public final static String IMAGE_URL="http://img5.imgtn.bdimg.com/it/u=4080105893,4096129906&fm=206&gp=0.jpg/";
//登录地址 http://10.0.152.244:8080/WebServiceDemo/LoginServlet
public final static String LOGIN_URL="http://10.0.165.133:8080/WebServiceDemo/";
//上传的网络地址 http://192.168.1.103:8080/UploadServer/UpLoadAction
public final static String UPLOAD_URL="http://10.0.165.133:8080/UploadServer/";
}
下面我将开始创建我们的接口,在接口中我填写了好几个抽象方法,用来掩饰好几种不同情况的url拼接案例,大家可以一种一种的看:
public interface INewsBiz {
/**
* 通过@GET注解标记位get请求 @GET中填写baseUrl根路径后的路径
* 访问的网络地址由根路径和@GET注解后的路径连接组成
*/
//案例一:这种是将根路径后面的路径整个放入了get中进行拼接,相对比较简单,后期和根url拼接
@GET("api/GetFeeds?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41")
//此处的返回值可以自行设置,这里我就简单的让他返回请求体的内容:
Call<ResponseBody> getResonseBody();
@GET("api/GetFeeds?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41")
//案例二:此处的返回值我让他返回的是String类型,具体返回逻辑我一会儿在主方法中创建:
Call<String> getJsonString();
//案例三:使用的是茶叶品牌的url,此处将根目录以后的部分进行了截取,但是返回的是一个Tea对象的集合,至于tea对象的生成大家一定都会使用Gson吧,这个我就不细说了。
@GET("category?app_id=161")
Call<List<Tea>> getTeas();
//案例四:此处使用的是同案例一,但是path路径不确定的情况情况下,使用{type}代替,当做抽象方法中的一个参数进行接收,
@GET("api/{type}?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41")
//这里的path就是你要传入的type类型,这里@path“tyle”名称一定要和@get();中的type同名,
Call<NewsInfo> getNewsInfo(@Path("type") String type);//String type="GetFeeds"
//案例五:有一个键值对的情况,如果不确定时,需要使用此方法,使用@query(键名)将你的值输入:
@GET("category")//category?app_id=161
Call<List<Tea>> getTeaByNetWork(@Query("app_id") int id);
//案例六:如果键值对是很多的情况下,案例五很明先无法满足需要,这时候需要使用@querymap接收一个map集合来进行拼凑。
@GET("api/GetFeeds")
Call<NewsInfo> getInfoByNetWork(@QueryMap Map<String, String> map);
//你也可以使用多种方式拼凑结合:使用{},加上参数的拼接等,都是可以灵活运行
案例七:
// @GET("api/{type}")
// Call<NewsInfo> getInfo(@Path("type") String type,@QueryMap Map<String,String> map);
//案例八:网络下载图片,
@GET("img")
Call<ResponseBody> downLoadImage();
//post形式提交表单数据 登录 注册,post需要服务器,这里无法进行演示,但是代码有,需要的话可以从自己的服务器中进行验证,
//@post注解说明采用post提交的形式 @Field("向服务器提交的key")
@POST("LoginServlet")
@FormUrlEncoded
Call<String> login(@Field("username") String userName,
@Field("password") String password);
//上传单个文件 @Field和@Part 客户端向服务端携带参数发起请求
//@Part 可携带的参数类型更多样 数据流等
@Multipart
@POST("UpLoadAction")
Call<ResponseBody> upLoadFile(@Part("img") RequestBody body);
//可以上传表单中所有的数据 表单文本+附件
@POST("UpLoadAction")
Call<ResponseBody> upLoad(@Body() MultipartBody body);
}
下面是主方法中的代码:
/**
* RetroFit 用来访问网络的第三方框架 http网络请求工具
* RetroFit使用步骤:
* 1.定义一个接口(封装url地址和数据请求)
* 2.实例化retrofit
* 3.调用retrofit实例创建接口服务对象
* 4.调用接口中的方法获取Call对象
* 5.call对象请求(异步\同步请求)
*/
public class MainActivity extends AppCompatActivity {
private TextView tv;
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv= (TextView) findViewById(R.id.tv);
iv= (ImageView) findViewById(R.id.iv_show);
// initRetrofit01();
// initRetrofit02();
// initRetrofit03();
// initRetrofit04();
// initRetrofit05();
// initRetrofit06();
// initRetrofit07();
initRetrofit08();
}
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
String info= (String) msg.obj;
tv.setText(info);
}
};
/**
* 采用同步的访问方式
*/
public void initRetrofit08(){
Retrofit retrofit=new Retrofit.Builder().baseUrl(Constant.BASE_URL).build();
final INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
new Thread(new Runnable() {
@Override
public void run() {
Call<ResponseBody> call=iNewsBiz.getResonseBody();
try {
//采用同步的形式请求数据
Response<ResponseBody> response=call.execute();
String str=response.body().string();
//将获取的数据通过消息发送到主线程
Message message=Message.obtain();
message.obj=str;
handler.sendMessage(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
/**
* 下载网络图片
*/
public void initRetrofit07(){
Retrofit retrofit=new Retrofit.Builder().baseUrl(Constant.IMAGE_URL).build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
Call<ResponseBody> call=iNewsBiz.downLoadImage();
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccess()){
// String str=response.body().string();
// byte[] buff=response.body().bytes();
InputStream in=response.body().byteStream();
Bitmap bm= BitmapFactory.decodeStream(in);
iv.setImageBitmap(bm);
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
/**
* get请求 请求通过@queryMap注解动态的传递多个参数
*/
public void initRetrofit06(){
Retrofit retrofit=new Retrofit.Builder()
.baseUrl(Constant.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
//column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41"
Map<String,String> map=new HashMap<>();
map.put("column","0");
map.put("PageSize","10");
map.put("pageIndex","1");
map.put("val","100511D3BE5301280E0992C73A9DEC41");
Call<NewsInfo> call=iNewsBiz.getInfoByNetWork(map);
call.enqueue(new Callback<NewsInfo>() {
@Override
public void onResponse(Call<NewsInfo> call, Response<NewsInfo> response) {
if(response.isSuccess()){
List<NewsInfo.ParamzBean.FeedsBean> news=response.
body().getParamz().getFeeds();
StringBuffer sb=new StringBuffer();
for(NewsInfo.ParamzBean.FeedsBean feed:news){
sb.append(feed.getData().getSubject());
}
tv.setText(sb.toString());
}
}
@Override
public void onFailure(Call<NewsInfo> call, Throwable t) {
}
});
}
/**
* get请求 通过@query注解动态传递参数的值
*/
public void initRetrofit05(){
Retrofit retrofit=new Retrofit
.Builder()
.baseUrl(Constant.TEABASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
Call<List<Tea>> call=iNewsBiz.getTeaByNetWork(161);
call.enqueue(new Callback<List<Tea>>() {
@Override
public void onResponse(Call<List<Tea>> call, Response<List<Tea>> response) {
if(response.isSuccess()){
List<Tea> list=response.body();
StringBuilder sb=new StringBuilder();
for(Tea t:list){
sb.append(t.getProduct_cat_name());
}
tv.setText(sb.toString());
}
}
@Override
public void onFailure(Call<List<Tea>> call, Throwable t) {
}
});
}
/**
* get请求 通过占位符指定path路径
*/
public void initRetrofit04(){
Retrofit retrofit=new Retrofit
.Builder()
.baseUrl(Constant.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
Call<NewsInfo> call=iNewsBiz.getNewsInfo("GetFeeds");
call.enqueue(new Callback<NewsInfo>() {
@Override
public void onResponse(Call<NewsInfo> call, Response<NewsInfo> response) {
if(response.isSuccess()){
List<NewsInfo.ParamzBean.FeedsBean> news=response.
body().getParamz().getFeeds();
StringBuffer sb=new StringBuffer();
for(NewsInfo.ParamzBean.FeedsBean feed:news){
sb.append(feed.getData().getSubject());
}
tv.setText(sb.toString());
}
}
@Override
public void onFailure(Call<NewsInfo> call, Throwable t) {
}
});
}
/**
* 普通的get请求 返回的数据为list集合
*/
public void initRetrofit03(){
Retrofit retrofit=new Retrofit
.Builder()
.baseUrl(Constant.TEABASE_URL)
//如果服务器返回的是json格式的数据 设置GsonConverterFactory后 实现对对象的转化
//相当于对服务器返回的json字符串直接进行解析
.addConverterFactory(GsonConverterFactory.create())
.build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
Call<List<Tea>> call=iNewsBiz.getTeas();
call.enqueue(new Callback<List<Tea>>() {
@Override
public void onResponse(Call<List<Tea>> call, Response<List<Tea>> response) {
if(response.isSuccess()){
List<Tea> list=response.body();
StringBuilder sb=new StringBuilder();
for(Tea t:list){
sb.append(t.getProduct_cat_name());
}
tv.setText(sb.toString());
}
}
@Override
public void onFailure(Call<List<Tea>> call, Throwable t) {
}
});
}
/**
* 普通的get请求 返回的数据为String类型
*/
public void initRetrofit02(){
Retrofit retrofit=new Retrofit
.Builder()
.baseUrl(Constant.BASE_URL)
//设置返回数据的适配器 get请求后可以返回String字符串类型的数据
.addConverterFactory(ScalarsConverterFactory.create())
.build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
Call<String> call=iNewsBiz.getJsonString();
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if(response.isSuccess()){
tv.setText(response.body());
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
}
});
}
/**
* 普通get请求
*/
public void initRetrofit01(){
//创建retrofit的实例
Retrofit retrofit=new Retrofit
.Builder()
.baseUrl(Constant.BASE_URL)//必须存在 指定访问网络的根路径
.build();
//根据接口的字节码文件对象获取接口对象
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
//调用接口中的方法
Call<ResponseBody> call=iNewsBiz.getResonseBody();
//调用call中的请求方法 enqueue()异步请求 execute()同步请求
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccess()){//成功的获取响应
try {
String result=response.body().string();//获取响应对象中的字符串
tv.setText(result);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
}
});
}
}
//Tea对象
public class Tea {
/**
* product_cat_id : 2032
* product_cat_name : 青茶
* product_cat_parent_id :
* industry_id : 161
*/
private String product_cat_id;
private String product_cat_name;
private String product_cat_parent_id;
private String industry_id;
public String getProduct_cat_id() {
return product_cat_id;
}
public void setProduct_cat_id(String product_cat_id) {
this.product_cat_id = product_cat_id;
}
public String getProduct_cat_name() {
return product_cat_name;
}
public void setProduct_cat_name(String product_cat_name) {
this.product_cat_name = product_cat_name;
}
public String getProduct_cat_parent_id() {
return product_cat_parent_id;
}
public void setProduct_cat_parent_id(String product_cat_parent_id) {
this.product_cat_parent_id = product_cat_parent_id;
}
public String getIndustry_id() {
return industry_id;
}
public void setIndustry_id(String industry_id) {
this.industry_id = industry_id;
}
}
//NeswsInfo对象
public class NewsInfo {
private String status;
private ParamzBean paramz;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public ParamzBean getParamz() {
return paramz;
}
public void setParamz(ParamzBean paramz) {
this.paramz = paramz;
}
public static class ParamzBean {
private int PageIndex;
private int PageSize;
private int TotalCount;
private int TotalPage;
private List<FeedsBean> feeds;
public int getPageIndex() {
return PageIndex;
}
public void setPageIndex(int PageIndex) {
this.PageIndex = PageIndex;
}
public int getPageSize() {
return PageSize;
}
public void setPageSize(int PageSize) {
this.PageSize = PageSize;
}
public int getTotalCount() {
return TotalCount;
}
public void setTotalCount(int TotalCount) {
this.TotalCount = TotalCount;
}
public int getTotalPage() {
return TotalPage;
}
public void setTotalPage(int TotalPage) {
this.TotalPage = TotalPage;
}
public List<FeedsBean> getFeeds() {
return feeds;
}
public void setFeeds(List<FeedsBean> feeds) {
this.feeds = feeds;
}
public static class FeedsBean {
private int id;
private int oid;
private String category;
private DataBean data;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getOid() {
return oid;
}
public void setOid(int oid) {
this.oid = oid;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public DataBean getData() {
return data;
}
public void setData(DataBean data) {
this.data = data;
}
public static class DataBean {
private String subject;
private String summary;
private String cover;
private String pic;
private String format;
private String changed;
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public String getCover() {
return cover;
}
public void setCover(String cover) {
this.cover = cover;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
public String getChanged() {
return changed;
}
public void setChanged(String changed) {
this.changed = changed;
}
}
}
}
}
//LogInActivity
public class LoginActivity extends AppCompatActivity{
private EditText et_name,et_pwd;
private TextView tv;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
et_name= (EditText) findViewById(R.id.et_name);
et_pwd= (EditText) findViewById(R.id.et_pwd);
tv= (TextView) findViewById(R.id.tv_result);
}
public void Login(View view){
Retrofit retrofit=new Retrofit.Builder().
baseUrl(Constant.LOGIN_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
String name=et_name.getText().toString().trim();
String pwd=et_pwd.getText().toString().trim();
Call<String> call=iNewsBiz.login(name,pwd);
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if(response.isSuccess()){
tv.setText(response.body());
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
}
});
}
}
//UpLoadActivity
public class UpLoadActivity extends AppCompatActivity{
private EditText et_name;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upload);
et_name= (EditText) findViewById(R.id.et_username);
}
/**
* 点击按钮上传附件(文件 图片 音视频 文本...)
*/
public void uploadFile(View view){
Retrofit retrofit=new Retrofit.Builder()
.baseUrl(Constant.UPLOAD_URL).build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
//需要上传的文件名称
String fileName= Environment.getExternalStorageDirectory()
.getAbsolutePath()+File.separator+"dog.jpg";
File file=new File(fileName);
// RequestBody 请求体对象 抽象类 MultipartBody子类
RequestBody requestBody=new MultipartBody
.Builder()
.addFormDataPart("app","dog.jpg",
MultipartBody.create(MediaType.parse("multipart/form-data"),file))
.build();
Call<ResponseBody> call=iNewsBiz.upLoadFile(requestBody);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccess()){
try {
Log.i("tag",response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
}
});
}
/**
* 上传表单和附件数据
* @param view
*/
public void uploadForm(View view){
String userName=et_name.getText().toString().trim();
File file=new File(Environment.
getExternalStorageDirectory().
getAbsolutePath()+File.separator+"dog.jpg");
Retrofit retrofit=new Retrofit.Builder()
.baseUrl(Constant.UPLOAD_URL).build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
//将需要上传的表单和文件数据添加到MultipartBody对象中 请求体对象
MultipartBody body=new MultipartBody.Builder()
.addFormDataPart("name",userName)//需要上传的表单数据
.addFormDataPart("app","dog.jpg",
MultipartBody.create(MediaType.parse("multipart/form-data"),file))//需要上传的文件数据
.build();
Call<ResponseBody> call=iNewsBiz.upLoad(body);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccess()){
try {
Log.i("tag",response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
}
});
}
}
//longin布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入用户名"
android:textSize="30sp"/>
<EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码"
android:inputType="textPassword"
android:textSize="30sp"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录"
android:textSize="25sp"
android:onClick="Login"/>
<TextView
android:id="@+id/tv_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textColor="#aa0000"
android:text="result"/>
</LinearLayout>
//主活动布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.yztc.retrofitdemo.MainActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<ImageView
android:id="@+id/iv_show"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true"
/>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
//上传文件upload布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/et_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
android:hint="请输入用户名"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="上传文件"
android:textSize="25sp"
android:onClick="uploadFile"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="上传全部"
android:textSize="25sp"
android:onClick="uploadForm"/>
</LinearLayout>
希望我的只写源代码能够帮助到需要的。