Android Retrofit

发布于:2023-01-20 ⋅ 阅读:(7) ⋅ 点赞:(0) ⋅ 评论:(0)

目录

1.Retrofit是什么?

2.OkHttp和Retrofit

3.Retrofit的使用(异步GET)

        1 添加Retrofit库的依赖

        2 添加网络权限

        3 创建接收服务器返回数据的类

        4 创建用于描述网络请求的接口

        5 创建Retrofit实例

        6 创建网络请求接口实例

        7 发送网络请求

        8 处理返回结果

4 Retrofit的使用(异步POST)

        1 添加Retrofit库的依赖  

        2 添加网络权限

        3 创建接收服务器返回数据的类

        4 创建用于描述网络请求的接口 (接收请求体)

        5 创建Retrofit实例

        6 创建网络请求接口实例

        7 发送网络请求

        8 处理返回结果

5Retrofit+OkHTTP+RecycleView的实现步骤

        第一步: 创建项目

        第二步:导入依赖

        第三步:添加网络权限

        第四步:在activity_main.xml添加Recycle,并给其设置id

        第五步:创建子布局 news_item.xml

        第六步:创建实体类  

        第七步:创建适配器

        第八步:设置适配器

        第九步:进行网络请求


1.Retrofit是什么?

准确来说,Retrofit 是一个 RESTful HTTP 网络请求框架的封装

原因:
网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责网络请求接口的封装。 App 应用程序通过 Retrofit请求网络,实际上是使用 Retrofit 接口层封装请求参数、 Header Url 等信息,之后由 OkHttp 完成后续的请求操作。在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit Retrofit 根据用户 的需求对结果进行解析。所以,网络请求的本质仍旧是OkHttp 完成的, retrofit 只是帮使用者来进行工 作简化的,比如配置网络,处理数据等工作,提高这一系列操作的复用性。这也就是网上流行的一个不 太准确的总结:
OkHttp 是瑞士军刀, retrofit 则是将瑞士军刀包装成了一个非常好用的指甲钳

2.OkHttp和Retrofit

        
OKhttp 的意义:
OkHttp 是基于 Http 协议封装的一套请求客户端,虽然它也可以开线程,但根本上它更偏向真正的请求,跟HttpClient,HttpUrlConnection 的职责是一样的。
OkHttp 的职责:
OkHttp 主要负责 socket 部分的优化,比如多路复用, buffer 缓存,数据压缩等等。
OkHttp 给用户留下的问题
1. 用户网络请求的接口配置繁琐,尤其是需要配置请求 body ,请求头,参数的时候;
2. 数据解析过程需要用户手动拿到 responsbody 进行解析,不能复用;
3. 无法适配自动进行线程的切换。
使用 Retrofit解决问题
Retrofit 主要负责应用层面的封装,就是说主要面向开发者,方便使用,比如请求参数,响应数据的处 理,错误处理等等。
Retrofit 封装了具体的请求,线程切换以及数据转换。
网上一般都推荐 RxJava+Retrofit+OkHttp 框架, Retrofit 负责请求的数据和请求的结果,使用接口的 方式呈现, OkHttp 负责请求的过程, RxJava 负责异步,各种线程之间的切换,用起来非常便利。
查看源图像

主要的步骤都是:
创建网络请求实体 client-> 构建真正的网络请求 -> 将网络请求方案与真正的网络请求实体结合构成一个 请求 Call-> 执行网络请求 -> 处理返回数据 -> 处理 Android 平台的线程问题。
在上图中,我们看到的对比最大的区别是什么?
1. OkHttp 创建的是 OkhttpClient, 然而 retrofit 创建的是 Retrofit 实例
2. 构建蓝色的 Requet 的方案 ,retrofit 是通过注解来进行的适配
3. 配置 Call 的过程中 ,retrofit 是利用 Adapter 适配的 Okhttp Call
4. 相对 okhttp,retrofit 会对 responseBody 进行自动 Gson 解析
5. 相对 okhttp,retrofit 会自动的完成线程的切换

3.Retrofit的使用(异步GET

        1 添加Retrofit库的依赖

由于 Retrofit 是基于 OkHttp ,所以还需要添加 OkHttp 库依赖
implementation("com.squareup.okhttp3:okhttp:4.10.0")
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'

        2 添加网络权限

AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>

        3 创建接收服务器返回数据的类

PhoneAddress.java
       
public class PhoneAddress {
    private boolean success;
    private String tel;
    private Info info;

    public static class Info{
        private String local;
        private String duan;
        private String type;
        private String yys;
        private String bz;

        @Override
        public String toString() {
            return "Info{" +
                    "local='" + local + '\'' +
                    ", duan='" + duan + '\'' +
                    ", type='" + type + '\'' +
                    ", yys='" + yys + '\'' +
                    ", bz='" + bz + '\'' +
                    '}';
        }
    }
    public void show(){
        System.out.println(success);
        System.out.println(tel);

        System.out.println(info.local);
        System.out.println(info.duan);
        System.out.println(info.type);
        System.out.println(info.yys);
        System.out.println(info.bz);

    }

    @Override
    public String toString() {
        return "PhoneAddress{" +
                "success=" + success +
                ", tel='" + tel + '\'' +
                ", info=" + info +
                '}';
    }
}

        4 创建用于描述网络请求的接口

GetRequest_Interface.java
public interface GetRequest_Interface {

    @GET("api/phone?")
    Call<PhoneAddress> getCall(@Query("tel")String tel);
}

        5 创建Retrofit实例

        6 创建网络请求接口实例

        7 发送网络请求

        8 处理返回结果

//创建Retrofit对象
Retrofit retrofit=new Retrofit.Builder()
        .baseUrl("https://api.vvhan.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
//创建网络请求接口的实例
GetRequest_Interface request=retrofit.create(GetRequest_Interface.class);
//对发送送请求进行封装
Call<PhoneAddress> call=request.getCall(phonenum);
//发送网络请求(异步)
call.enqueue(new Callback<PhoneAddress>() {
    @Override
    public void onResponse(Call<PhoneAddress> call, Response<PhoneAddress> response) {
        tv_show.setText(response.body().toString());

    }

    @Override
    public void onFailure(Call<PhoneAddress> call, Throwable t) {
        Log.i("onFailure","请求失败");
    }
});

4 Retrofit的使用(异步POST

       1 添加Retrofit库的依赖  

implementation("com.squareup.okhttp3:okhttp:4.10.0") 
implementation 'com.squareup.retrofit2:retrofit:2.4.0' 
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'

        2 添加网络权限

<uses-permission android:name="android.permission.INTERNET"/>

        3 创建接收服务器返回数据的类

public class LoginInfo {
    private int success;
    private String info;

    @Override
    public String toString() {
        return "LoginInfo{" +
                "success=" + success +
                ", info='" + info + '\'' +
                '}';
    }
}

        4 创建用于描述网络请求的接口 (接收请求体)

        
public interface PostRequest_Interface {
    @POST("login")
    Call<LoginInfo> postCall(@Body RequestBody requestBody);
}

        5 创建Retrofit实例

        6 创建网络请求接口实例

        7 发送网络请求

        8 处理返回结果

 private void postData(String num) {
        Retrofit retrofit=new Retrofit.Builder()
                .baseUrl("http://192.168.17.181:8080/TestWeb_war_exploded/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        PostRequest_Interface request=retrofit.create(PostRequest_Interface.class);

        MediaType type=MediaType.Companion.parse("application/json;charset=utf-8");
        RequestBody body=RequestBody.Companion.create(num,type);
        Call<LoginInfo> call=request.postCall(body);
        call.enqueue(new Callback<LoginInfo>() {
            @Override
            public void onResponse(Call<LoginInfo> call, Response<LoginInfo> response) {
                Log.i("onResponse",response.body().toString());
            }

            @Override
            public void onFailure(Call<LoginInfo> call, Throwable t) {
                Log.i("onFailure","失败");
            }
        });
    }

5Retrofit+OkHTTP+RecycleView的实现步骤

        第一步: 创建项目

        第二步:导入依赖

implementation "com.github.bumptech.glide:glide:4.12.0" 

implementation("com.squareup.okhttp3:okhttp:4.10.0") 

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

implementation 'com.squareup.retrofit2:converter-gson:2.0.2'

        第三步:添加网络权限

<uses-permission android:name="android.permission.INTERNET" />

        第四步:在activity_main.xml添加Recycle,并给其设置id

<?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=".MainActivity"
    android:orientation="vertical"
    android:padding="5dp">


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

        第五步:创建子布局 news_item.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:orientation="vertical"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:cardCornerRadius="5dp"
    android:padding="5dp"
    app:cardElevation="5dp"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="190dp"
        android:layout_margin="5dp"
        android:orientation="horizontal">


        <ImageView
            android:id="@+id/news_show"
            android:layout_width="190dp"
            android:layout_height="190dp"
            app:srcCompat="@drawable/ic_launcher_background" />

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

            <TextView
                android:layout_marginTop="5dp"
                android:id="@+id/news_title"
                android:layout_marginStart="10dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="TextView" />

            <TextView
                android:layout_marginTop="20dp"
                android:id="@+id/news_desc"
                android:layout_marginStart="10dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="TextView" />
        </LinearLayout>
    </LinearLayout>
</androidx.cardview.widget.CardView>

       第六步:创建实体类  

package com.hopu.day23_practice.model;

import java.util.List;

public class News {
        private boolean success;
        private String title;
        private String subtitle;
        private String update_time;
        private List<Data> data;
        public void setSuccess(boolean success) {
            this.success = success;
        }
        public boolean getSuccess() {
            return success;
        }

        public void setTitle(String title) {
            this.title = title;
        }
        public String getTitle() {
            return title;
        }

        public void setSubtitle(String subtitle) {
            this.subtitle = subtitle;
        }
        public String getSubtitle() {
            return subtitle;
        }

        public String getUpdate_time() {
            return update_time;
        }

        public void setUpdate_time(String update_time) {
            this.update_time = update_time;
        }

        public void setData(List<Data> data) {
            this.data = data;
        }
        public List<Data> getData() {
            return data;

        }

    public class Data {

        private int index;
        private String title;
        private String desc;
        private String pic;
        private String hot;
        private String url;
        private String mobilUrl;
        public void setIndex(int index) {
            this.index = index;
        }
        public int getIndex() {
            return index;
        }

        public void setTitle(String title) {
            this.title = title;
        }
        public String getTitle() {
            return title;
        }

        public void setDesc(String desc) {
            this.desc = desc;
        }
        public String getDesc() {
            return desc;
        }

        public void setPic(String pic) {
            this.pic = pic;
        }
        public String getPic() {
            return pic;
        }

        public void setHot(String hot) {
            this.hot = hot;
        }
        public String getHot() {
            return hot;
        }

        public void setUrl(String url) {
            this.url = url;
        }
        public String getUrl() {
            return url;
        }

        public void setMobilUrl(String mobilUrl) {
            this.mobilUrl = mobilUrl;
        }
        public String getMobilUrl() {
            return mobilUrl;
        }

        @Override
        public String toString() {
            return "Data{" +
                    "index=" + index +
                    ", title='" + title + '\'' +
                    ", desc='" + desc + '\'' +
                    ", pic='" + pic + '\'' +
                    ", hot='" + hot + '\'' +
                    ", url='" + url + '\'' +
                    ", mobilUrl='" + mobilUrl + '\'' +
                    '}';
        }
    }

    @Override
    public String toString() {
        return "News{" +
                "success=" + success +
                ", title='" + title + '\'' +
                ", subtitle='" + subtitle + '\'' +
                ", update_time='" + update_time + '\'' +
                ", data=" + data +
                '}';
    }
}

        第七步:创建适配器

public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> {

    List<News.Data> list;
    public void setResource(List<News.Data> list){
        this.list=list;

        notifyDataSetChanged();
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view=LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item,parent,false);
        ViewHolder viewHolder=new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        News.Data data=list.get(position);
        Glide.with(holder.view).load(data.getPic()).into(holder.news_show);
        holder.news_title.setText(data.getTitle());
        holder.news_desc.setText(data.getDesc());
    }

    @Override
    public int getItemCount() {
        if (list==null){
            return 0;
        }else {
            return list.size();
        }
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        ImageView news_show;
        TextView news_title;
        TextView news_desc;
        View view;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            view=itemView;
            news_desc=itemView.findViewById(R.id.news_desc);
            news_title=itemView.findViewById(R.id.news_title);
            news_show=itemView.findViewById(R.id.news_show);
        }
    }
}

        第八步:设置适配器

    //声明容器
    NewsAdapter newsAdapter;
    RecyclerView rv_news;

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

        rv_news=findViewById(R.id.rv_news);
        newsAdapter=new NewsAdapter();
        LinearLayoutManager layoutManager=new LinearLayoutManager(this);
        rv_news.setLayoutManager(layoutManager);
        rv_news.setAdapter(newsAdapter);
        initData();
    }

        第九步:进行网络请求

                1. 创建请求接口

public interface News_Interface {

    @GET("api/hotlist?type=zhihuHot")
    Call<News> getNews();
}
                2. 开始网络请求
                3. 处理返回结果
private void initData() {
        Retrofit retrofit=new Retrofit.Builder()
                .baseUrl("https://api.vvhan.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        News_Interface news_interface=retrofit.create(News_Interface.class);
        Call<News> call=news_interface.getNews();

        call.enqueue(new Callback<News>() {
            @Override
            public void onResponse(Call<News> call, Response<News> response) {
                Log.i("onResponse",response.body().toString());
                newsAdapter.setResource(response.body().getData());
            }

            @Override
            public void onFailure(Call<News> call, Throwable t) {
                Log.i("onFailure","请求失败");
            }
        });
    }