Retrofit 框架的学习(巨详细)

41 篇文章 2 订阅
27 篇文章 0 订阅

Retrofit 框架的学习

1.Retrofit 简介

1.Retrofit是当下最热门的一个网络请求库,是基于OKhttp和HTTP协议的网络请求框架

目录

https://imgconvert.csdnimg.cn/aHR0cDovL3VwbG9hZC1pbWFnZXMuamlhbnNodS5pby91cGxvYWRfaW1hZ2VzLzk0NDM2NS0yYmQ4MGIyMzRhZTlkMTU1LnBuZz9pbWFnZU1vZ3IyL2F1dG8tb3JpZW50L3N0cmlwJTdDaW1hZ2VWaWV3Mi8yL3cvMTI0MA

2.介绍
Retrofit简介
介绍一个RESTful的HTTP网络请求框架
作者Square
功能1.基于OKhttp & 遵循Restful的API设计风格; 2.通过注解配置网络请求参数; 3.支持同步/异步网络请求; 4.支持多种类型数据的解析; 5.提供对Rxjava的支持
优点功能强大;支持多种数据的解析;支持同步和异步;拓展性好;代码简洁
应用场景任何网络请求的需求场景都应该优先选择

本质过程

2.导入依赖

implementation 'com.squareup.retrofit2:retrofit:2.7.0'

3.Retrofit发起Get数据请求

1.创建一个接口api
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.GET;

public interface API {
    //GET注解里面的参数就是一个URL,就是baseURL后面的那坨坨
    @GET("/get/text")
    Call<ResponseBody> getJson();
}

所以为什么这儿还要特意把导入的包也要放进来呢?

踩坑!!!Call这个类必须是import retrofit2.Call,别的都是错的,一定要看清楚了

2.创建一个活动,在xml文件内添加一个按钮,用来发送请求
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Retrofit.RetrofitActivity"
    android:orientation="vertical">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Retrofit get请求"
        android:textAllCaps="false"
        android:onClick="RtgetRequest"
        tools:ignore="OnClick" />

</LinearLayout>
3.最后就是.java文件内编译
public class RetrofitActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_retrofit);
    }

    public void RtgetRequest(View view) {
        //首先还是要创建一个Retrofit,并设置baseURL
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://10.0.2.2:9102")
                .build();
        //创建一个API,retrofit.create()参数传入一个接口
        API api = retrofit.create(API.class);
        //创建一个任务
        Call<ResponseBody> task = api.getJson();
        //异步传输,这里和OKhttp一致
        task.enqueue(new Callback<ResponseBody>() {
            private static final String TAG = "RetrofitActivity";
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if (response.code() == HttpURLConnection.HTTP_OK) {
                    try {
                        Log.d(TAG, "onResponse: " + response.body().string());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }
}
4.运行时报错(非代码问题)?怎么解决

如果运行时候报错,在app.gradle文件下面的android{}下面添加如下代码:

 compileOptions{
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }

4.retrofit处理请求到的数据并显示到UI上

1.在xml文件上添加一个recycleview,用来显示数据;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Retrofit.RetrofitActivity"
    android:orientation="vertical">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Retrofit get请求"
        android:textAllCaps="false"
        android:onClick="RtgetRequest"
        tools:ignore="OnClick" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/result_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>
2.设置一个数据适配器器
public class RtJsonResultAdapter extends RecyclerView.Adapter<RtJsonResultAdapter.InnerHolder> {

    private List<GetTextItem.DataDTO> data = new ArrayList<>();

    @Override
    public InnerHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
        //绑定布局
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.acticity_rtjsonresult_item, parent, false);
        return new InnerHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull @NotNull InnerHolder holder, int position) {
        //绑定数据
        TextView tv_name = holder.itemView.findViewById(R.id.nameid);
        TextView tv_course = holder.itemView.findViewById(R.id.courseid);
        TextView tv_id = holder.itemView.findViewById(R.id.id);

        GetTextItem.DataDTO dataDTO = data.get(position);
        tv_name.setText(dataDTO.getName());
        tv_course.setText(dataDTO.getCourseId());
        tv_id.setText(dataDTO.getId());
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    public void setData(GetTextItem getTextItem) {
        data.clear();
        data.addAll(getTextItem.getData());
        notifyDataSetChanged();
    }

    public class InnerHolder extends RecyclerView.ViewHolder {
        public InnerHolder(@NonNull @NotNull View itemView) {
            super(itemView);
        }
    }
}

3.创建一个展示子项的xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/image_item"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:src="@mipmap/ic_launcher" />

        <LinearLayout
            android:layout_marginLeft="5dp"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="作者姓名:"
                    android:textSize="16sp" />

                <TextView
                    android:id="@+id/name_item"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:paddingLeft="10dp"
                    android:text="xxx"
                    android:textSize="16sp" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="horizontal">

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <TextView
                        android:id="@+id/text_courseid"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerInParent="true"
                        android:text="课程id:"
                        android:textSize="18sp"
                        android:layout_alignParentLeft="true"/>

                    <TextView
                        android:id="@+id/courseid"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignLeft="@+id/text_courseid"
                        android:layout_marginLeft="80dp"
                        android:layout_marginTop="20dp"
                        android:textSize="16sp"
                        android:text="123" />

                </RelativeLayout>

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1">

                    <TextView
                        android:id="@+id/text_id"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerInParent="true"
                        android:text="个人id:"
                        android:textSize="18sp"
                        android:layout_alignParentLeft="true"/>

                    <TextView
                        android:id="@+id/id"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignLeft="@+id/text_id"
                        android:layout_marginLeft="80dp"
                        android:layout_marginTop="20dp"
                        android:textSize="16sp"
                        android:text="123" />
                </RelativeLayout>
            </LinearLayout>

        </LinearLayout>

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="5dp"
        android:background="#00BCD4"/>

</LinearLayout>
4.在.java文件内编写代码
public class RetrofitActivity extends AppCompatActivity {

    private RtJsonResultAdapter rtJsonResultAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_retrofit);
        initView();
    }

    private void initView() {
        RecyclerView recyclerView = this.findViewById(R.id.result_list);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        rtJsonResultAdapter = new RtJsonResultAdapter();
        recyclerView.setAdapter(rtJsonResultAdapter);
    }

    public void RtgetRequest(View view) {
        //首先还是要创建一个Retrofit,并设置baseURL
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.wanandroid.com")
                .build();
        //创建一个API
        API api = retrofit.create(API.class);
        Call<ResponseBody> task = api.getJson();
        task.enqueue(new Callback<ResponseBody>() {
            private static final String TAG = "RetrofitActivity";

            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if (response.code() == HttpURLConnection.HTTP_OK) {
                    try {
                        //首先得到获取到的内容
                        String json = response.body().string();
                        Log.d(TAG, "onResponse: "+json);
                        //解析json
                        Gson gson = new Gson();
                        GetTextItem getTextItem = gson.fromJson(json,GetTextItem.class);
                        //在UI中更新数据
                        updateUI(getTextItem);
                        Log.d(TAG, "onResponse: "+json);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }

    private void updateUI(GetTextItem getTextItem) {
        rtJsonResultAdapter.setData(getTextItem);
    }
}

5.使用转换器把json转换成对象

1.添加依赖
 implementation 'com.squareup.retrofit2:converter-gson:2.7.0'
2.在“创建一个请求Request时”添加工厂类
 //首先还是要创建一个Retrofit,并设置baseURL
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.wanandroid.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
3.在API接口里面进行修改
public interface API {
    //GET注解里面的参数就是一个URL,就是baseURL后面的那坨坨
    @GET("/wxarticle/chapters/json")
    Call<GetTextItem> getJson();
}

6.使用@Query 发起带参数的get请求

1.老生常谈的创建一个新的活动,添加一个按钮和一个RecycleView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Retrofit.RetrofitActivity"
    android:orientation="vertical">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Retrofit 使用Query发起get请求"
        android:textAllCaps="false"
        android:onClick="RtgetRequestQuery"
        tools:ignore="OnClick" />
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/result_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>
2.添加一个数据适配器,代码请见第四点
3.用单例模式创建一个RetrofitManager 类,作为Retrofit使用的工具类

这个类并不是使用@Query注解必须需要的东西,而是为了使用Retrofit框架时更加简洁方便而创建的。

public class RetrofitManager {
    //首先还是要创建一个Retrofit,并设置baseURL
    private static Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://www.wanandroid.com")
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    public static Retrofit getReteofit(){
        return retrofit;
    }
}

4.修改你的api接口
public interface API {
    //GET注解里面的参数就是一个URL,就是baseURL后面的那坨坨
    @GET("/wxarticle/chapters/json")
    Call<GetTextItem> getJson();

    //使用QUERY注解来发送带参数的get请求
    @GET("/get/param")
    Call<GetTextItem> getwithParms(@Query("hanshikai")String keyword,@Query("123456") String password);
}

仔细学习@Query注解的使用方法,注解后边的参数需要写你想传入的参数,然后给这个关键字命名。切记!!注解后面的参数括号内不能有空格

5.在.java文件内编写代码
public void RtgetRequestQuery(View view) {
        //创建一个API,之前使用单例模式来创建一个Retrofit;
        API api = RetrofitManager.getReteofit().create(API.class);
        Call<GetTextItem> task = api.getwithParms("我是一个关键字","123456");
        task.enqueue(new Callback<GetTextItem>() {
            private static final String TAG = "RetrofitActivity";

            @Override
            public void onResponse(Call<GetTextItem> call, Response<GetTextItem> response) {
                if (response.code() == HttpURLConnection.HTTP_OK) {
                    try {
                        GetTextItem getTextItem = response.body();
                        updateUI(getTextItem);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onFailure(Call<GetTextItem> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }

看,多么简洁的代码。比起HTTP协议的代码简直安逸了不是一星半点哦。记得多用,多用。熟能生巧。

7.Retrofit的@QueryMap注解使用

1.修改api接口
//使用@QueryMap注解(用来解决参数过多的问题)
    @GET("/get/param")
    Call<GetTextItem> getwithParms(@QueryMap() Map<String,Object> params);
2.在.java文件内编写
//使用QueryMap注解
    public void RtgetRequestQueryMap(View view) {
        //创建一个API,之前使用单例模式来创建一个Retrofit;
        API api = RetrofitManager.getReteofit().create(API.class);
        Call<GetTextItem> task = api.getwithParms("我是一个关键字","123456");
        task.enqueue(new Callback<GetTextItem>() {
            private static final String TAG = "RetrofitActivity";

            @Override
            public void onResponse(Call<GetTextItem> call, Response<GetTextItem> response) {
                if (response.code() == HttpURLConnection.HTTP_OK) {
                    try {
                        GetTextItem getTextItem = response.body();
                        updateUI(getTextItem);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onFailure(Call<GetTextItem> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }

细看来,与@Query注解的使用基本一致,就是多添加一个map集合而已。用法不同但是结果相同,这就是异途同归吗哈哈哈

8.使用POST注解发起带参数的请求

1.创建一个接口
 //使用post注解来发起带参数的请求
    @POST
    Call<GetTextItem> PostwithParams(@Query("这是一个评论") String comment);
2.在.java文件下编辑代码
 public void PostWithParams(View view){
        API api = RetrofitManager.getReteofit().create(API.class);
        Call<GetTextItem> task = api.PostwithParams("返景入深林,复照青苔上");
        task.enqueue(new Callback<GetTextItem>() {
            private static final String TAG = "PostWithParamsActivity";

            @Override
            public void onResponse(Call<GetTextItem> call, Response<GetTextItem> response) {
                int code = response.code();
                if (code== HttpURLConnection.HTTP_OK) {
                    Log.d(TAG, "onResponse: "+response.body().toString());
                }
            }

            @Override
            public void onFailure(Call<GetTextItem> call, Throwable t) {
                Log.d(TAG, "onFailure: "+t.toString());
            }
        });
    }

9.使用POST注解发起带URL的请求

1.创建接口
 //使用post注解来发起带url的请求
    @POST
    Call<GetTextItem> PostwithUrl(@Url String url);
2.在.java文件内编写代码
 //使用post注解来发起带url的请求
    public void PostWithUrl(View view){
        API api = RetrofitManager.getReteofit().create(API.class);
        Call<GetTextItem> task = api.PostwithUrl("返景入深林,复照青苔上");
        task.enqueue(new Callback<GetTextItem>() {
            private static final String TAG = "PostWithParamsActivity";

            @Override
            public void onResponse(Call<GetTextItem> call, Response<GetTextItem> response) {
                int code = response.code();
                if (code== HttpURLConnection.HTTP_OK) {
                    Log.d(TAG, "onResponse: "+response.body().toString());
                }
            }

            @Override
            public void onFailure(Call<GetTextItem> call, Throwable t) {
                Log.d(TAG, "onFailure: "+t.toString());
            }
        });
    }

10.Retrofit的@Body注解

1.创建新活动,添加新按钮
<Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="使用Retrofit的@Body注解"
        android:onClick="PostWithBody"
        tools:ignore="MissingConstraints,OnClick" />
2.修改api接口
//使用Retrofit的@Body注解
    @POST("/post/comment")
    Call<GetTextItem> PostwithBody(@Body GetTextItem getTextItem);

注意这里的参数传的是一个实体类

3.在.java文件内编译
 //使用Retrofit的@Body注解
    public void PostWithBody(View view){
        API api = RetrofitManager.getReteofit().create(API.class);
        GetTextItem getTextItem = new GetTextItem();
        Call<GetTextItem> task = api.PostwithBody(getTextItem);
        task.enqueue(new Callback<GetTextItem>() {
            @Override
            public void onResponse(Call<GetTextItem> call, Response<GetTextItem> response) {
                int code = response.code();
                if (code== HttpURLConnection.HTTP_OK) {
                    Log.d(TAG, "onResponse: "+response.body().toString());
                }
            }

            @Override
            public void onFailure(Call<GetTextItem> call, Throwable t) {
                t.toString();
            }
        });
    }

因为在api中传入的参数是一个实体类,所以在调用接口的方法时,传入的参数也必须是那个实体类

11.Retrofit使用@Part注解上传文件

1.继续创建活动,添加按钮,参考上面代码
2.修改api内容
/@Part注解实现单文件的上传
    @Multipart
    @POST("/file/upload")
    Call<GetTextItem> PostFile(@Part MultipartBody.Part part);
3.编辑代码
 //retrofit使用@Part注解来上传文件
    @RequiresApi(api = Build.VERSION_CODES.M)
    public void RtPostFile(View view){
        //内容提供器里面的知识
        int permissonResult = checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
        if(permissonResult != PackageManager.PERMISSION_GRANTED){
            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},REQUEST_CODE);
        }
        //然后是基操
        API api = RetrofitManager.getReteofit().create(API.class);
        //创建文件
        File file = new File("/storage/emulated/0/Download/1.jpeg");
        RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpeg"), file);
        MultipartBody.Part part = MultipartBody.Part.createFormData("file",file.getName(),requestBody);
        Call<GetTextItem> getTextItemCall = api.PostFile(part);
        getTextItemCall.enqueue(new Callback<GetTextItem>() {
            @Override
            public void onResponse(Call<GetTextItem> call, Response<GetTextItem> response) {
                int code = response.code();
                if (code== HttpURLConnection.HTTP_OK) {
                    Log.d(TAG, "onResponse: "+response.body().toString());
                }
            }

            @Override
            public void onFailure(Call<GetTextItem> call, Throwable t) {
                Log.d(TAG, "onFailure: "+t.toString());
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull @NotNull String[] permissions, @NonNull @NotNull int[] grantResults) {
        if (requestCode == REQUEST_CODE) {
            //TODO:处理权限获取结果
        }
    }

Retrofit基操之前有一段代码是内容提供器里面的知识。别的都是以前学了的,根据所需要的参数再创建需要的东西。

12.Retrofit使用注解上传多文件

1.添加按钮
2.修改api
 //多文件的上传
    @Multipart
    @POST
    Call<GetTextItem> PostFiles(@Part List<MultipartBody.Part> parts);
3. 编辑代码
 //使用注解来上传多文件
    public void PostFiles(View view){
        List<MultipartBody.Part> list = new ArrayList<>();
        API api = RetrofitManager.getReteofit().create(API.class);
        MultipartBody.Part file1 = createPartByPathAndKry("/storage/emulated/0/Download/1.jpeg", "files");
        MultipartBody.Part file2 = createPartByPathAndKry("/storage/emulated/0/Download/2.jpeg", "files");
        MultipartBody.Part file3 = createPartByPathAndKry("/storage/emulated/0/Download/3.jpeg", "files");
        list.add(file1);
        list.add(file2);
        list.add(file3);
        Call<GetTextItem> task = api.PostFiles(list);
        task.enqueue(new Callback<GetTextItem>() {
            @Override
            public void onResponse(Call<GetTextItem> call, Response<GetTextItem> response) {
                int code = response.code();
                if (code== HttpURLConnection.HTTP_OK) {
                    Log.d(TAG, "onResponse: "+response.body().toString());
                }
            }

            @Override
            public void onFailure(Call<GetTextItem> call, Throwable t) {
                Log.d(TAG, "onFailure: "+t.toString());
            }
        });
    }
    //封装一下上传文件的代码
    public MultipartBody.Part createPartByPathAndKry(String path,String key){
        File file = new File(path);
        RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpeg"), file);
        MultipartBody.Part formData = MultipartBody.Part.createFormData(key, file.getName(), requestBody);
        return formData;
    }

13.上传文件且带有参数信息

1.添加按钮
2.修改api
//上传文件且携带参数
    @Multipart
    @POST
    Call<GetTextItem> PostFilesWithParam(@Part MultipartBody.Part part,@Part Map<String,String> params);
3.编辑代码
 //Retrofit上传文件且携带参数
    public void RtPostFilesWithParms(View view){
        MultipartBody.Part files = createPartByPathAndKry("/storage/emulated/0/Download/1.jpeg", "files");
        Map<String,String> params = new HashMap<>();
        params.put("description","这是一条信息");
        params.put("isfree","true");
        API api = RetrofitManager.getReteofit().create(API.class);
        Call<GetTextItem> task = api.PostFilesWithParam(files, params);
        task.enqueue(new Callback<GetTextItem>() {
            @Override
            public void onResponse(Call<GetTextItem> call, Response<GetTextItem> response) {
                int code = response.code();
                if (code== HttpURLConnection.HTTP_OK) {
                    Log.d(TAG, "onResponse: "+response.body().toString());
                }
            }

            @Override
            public void onFailure(Call<GetTextItem> call, Throwable t) {
                Log.d(TAG, "onFailure: "+t.toString());
            }
        });
    }

14.使用@Field注解上传表单

1.修改api,然后编辑代码
    //提交表单
    @FormUrlEncoded
    @POST("/login")
    Call<GetTextItem> doLogin(@Field("username")String userName,@Field("password")String word);
 public void RtPostFileField(View view){
        API api = RetrofitManager.getReteofit().create(API.class); 
		Call<GetTextItem> task = api.doLogin("黄大仙", "123456");
        task.enqueue(new Callback<GetTextItem>() {
            @Override
            public void onResponse(Call<GetTextItem> call, Response<GetTextItem> response) {
                int code = response.code();
                if (code== HttpURLConnection.HTTP_OK) {
                    Log.d(TAG, "onResponse: "+response.body().toString());
                }
            }

            @Override
            public void onFailure(Call<GetTextItem> call, Throwable t) {
                Log.d(TAG, "onFailure: "+t.toString());
            }
        });
}

15.使用@FieldMap注解

1.修改api然后编辑代码
//提交表单
    @FormUrlEncoded
    @POST("/login")
    Call<GetTextItem> doLogin(@FieldMap Map<String,String> map);
 //使用Field注解来上传表单
    public void RtPostFileField(View view){
        API api = RetrofitManager.getReteofit().create(API.class);
        Map<String,String> map = new HashMap<>();
        map.put("username","大哥");
        map.put("password","1234dc");
        Call<GetTextItem> task = api.doLogin(map);
        task.enqueue(new Callback<GetTextItem>() {
            @Override
            public void onResponse(Call<GetTextItem> call, Response<GetTextItem> response) {
                int code = response.code();
                if (code== HttpURLConnection.HTTP_OK) {
                    Log.d(TAG, "onResponse: "+response.body().toString());
                }
            }

            @Override
            public void onFailure(Call<GetTextItem> call, Throwable t) {
                Log.d(TAG, "onFailure: "+t.toString());
            }
        });
    }

16.Retrofit下载文件

1.创建一个新的活动,然后添加一个按钮
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Retrofit.ReteofitDownFile">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="下载文件"
        android:onClick="RtDownFile"
        tools:ignore="OnClick" />

</LinearLayout>
2.修改api接口,添加一个 下载文件的接口
 //下载文件
    @GET
    Call<GetTextItem> downFile(@Url String url);
3.在.java文件中写代码
public class ReteofitDownFile extends AppCompatActivity {

    private static final String TAG = "ReteofitDownFile";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_reteofit_down_file);
    }

    //使用Retrofit下载文件
    public void RtDownFile(View view) {
        API api = RetrofitManager.getReteofit().create(API.class);
        Call<GetTextItem> task = api.downFile("http://www.baidu.com");
        task.enqueue(new Callback<GetTextItem>() {
            @Override
            public void onResponse(Call<GetTextItem> call, Response<GetTextItem> response) {
                int code = response.code();
                if (code == HttpURLConnection.HTTP_OK) {
                    //知道文件名称
                    Headers headers = response.headers();
                    String fileNameHeader = headers.get("Content-disposition");
                    String filename = "未命名.png";
                    if (fileNameHeader != null) {
                        filename = fileNameHeader.replace("attachment;filename=", "");
                        Log.d(TAG, "filename: " + filename);
                    }
                    for (int i = 0; i < headers.size(); i++) {
                        String value = headers.value(i);
                        String name = headers.name(i);
                        Log.d(TAG, "onResponse: " + value);
                    }
                    //写文件,但是这里UI线程,不可以写
                    writeString2disk(response, filename);
                }
            }

            private void writeString2disk(Response<GetTextItem> response, String filename) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String s = response.body().toString();
                        InputStream inputStream = response.body().byteStream();
                        File baseOutFile = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
                        Log.d(TAG, "run: " + baseOutFile);
                        File outFile = new File(baseOutFile,filename);
                        try {
                            FileOutputStream fos = new FileOutputStream(outFile);
                            byte[] buffer = new byte[1024];
                            int len;
                            while ((len = inputStream.read(buffer))!=-1){
                                fos.write(buffer,0,len);
                            }
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }

            @Override
            public void onFailure(Call<GetTextItem> call, Throwable t) {
                Log.d(TAG, "onFailure: " + t.toString());
            }
        });
    }
}

基本上都是一样的套路

17.@Header、@Headers、@HeadersMap注解的使用

 //@Part注解实现单文件的上传
    @Multipart
    @POST("/file/upload")
    Call<GetTextItem> PostFile(@Part MultipartBody.Part part, @Header("token") String token);

    //多文件的上传
    @Headers({"token:----","client:android","version:1.0"})
    @Multipart
    @POST("/files/upload")
    Call<GetTextItem> PostFiles(@Part List<MultipartBody.Part> parts);

完结撒花!!!

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值