我们项目当中的每个app都需要用到网络和服务器进行交互,在Android项目开发中使用HTTP协议完成 通信的话,基本上都要用到OkHttp或者Retrofit。 OkHttp和Retrofit是目前应用最为广泛的网络组件。
准确来说, Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。
原因:
网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责网络请求接口的封装。 App应用程序通过
Retrofit请求网络,实际上是使用Retrofit接口层封装请求参数、 Header、 Url 等信息,之后由 OkHttp
完成后续的请求操作。在服务端返回数据之后, OkHttp 将原始的结果交给 Retrofit, Retrofit根据用户 的需求对结果进行解析。所以,网络请求的本质仍旧是OkHttp完成的, retrofit只是帮使用者来进行工 作简化的,比如配置网络,处理数据等工作,提高这一系列操作的复用性。这也就是网上流行的一个不 太准确的总结:
OkHttp是瑞士军刀, retrofit则是将瑞士军刀包装成了一个非常好用的指甲钳。
Retrofit并没有改变网络请求的本质,也无需改变,因为OkHttp已经足够强大, Retrofit的封装可以说是 很强大,里面涉及到一堆的设计模式,可以通过注解直接配置请求,可以使用不同的http客户端,虽然 默认是用http,可以使用不同Json Converter 来序列化数据,同时提供对RxJava的支持,使用Retrofit + OkHttp + RxJava可以说是目前比较潮的一套框架,但是需要有比较高的门槛。
OKhttp的意义: OkHttp是基于Http协议封装的一套请求客户端,虽然它也可以开线程,但根本上 它更偏向真正的请求,跟HttpClient,HttpUrlConnection的职责是一样的。
OkHttp的职责: OkHttp主要负责socket部分的优化,比如多路复用, buffer缓存,数据压缩等 等。
Retrofit主要负责应用层面的封装,就是说主要面向开发者,方便使用,比如请求参数,响应数据的处 理,错误处理等等。
Retrofit封装了具体的请求,线程切换以及数据转换。 网上一般都推荐RxJava+Retrofit+OkHttp框架, Retrofit负责请求的数据和请求的结果,使用接口的 方式呈现, OkHttp负责请求的过程, RxJava负责异步,各种线程之间的切换,用起来非常便利。
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 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.创建用于描述网络请求的接口
- public interface News_Interface {
-
-
-
- Call
getNews() ; - @GET("api/hotlist")
- Call
getPic(@Query("pic") String type) ; -
- Call
getPic() ; - }
5.创建Retrofit实例
5.创建网络请求接口实例
6.发送网络请求
7.处理返回结果
- private void retrofit() {
- //步骤4:创建Retrofit对象
- Retrofit retrofit=new Retrofit.Builder()
- .baseUrl("https://api.vvhan.com/")// 设置 网络请求 Url
- .addConverterFactory(GsonConverterFactory.create())//设置使用Gson解析(记得加入依赖)
- .build();
-
- // 步骤5:创建 网络请求接口 的实例
- News_Interface request=retrofit.create(News_Interface.class);
-
- //对 发送请求 进行封装
- Call<News> call=request.getNews();
-
- //步骤6:发送网络请求(异步)
- call.enqueue(new Callback<News>() {
- //请求成功时回调
- @Override
- public void onResponse(Call
call, Response response ) { - Log.i("news网络请求",response.body().toString());
- // 步骤7:处理返回的数据结果
- newsAdapter.setList(response.body().getData());
-
- }
- //请求失败时回调
- @Override
- public void onFailure(Call
call, Throwable t ) { - Log.i("news网络请求","失败");
- }
- });
第一步: 创建项目第
第二步:导入依赖
- 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
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/rv_news"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
第五步:创建子布局 news_item.xml
- <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- app:cardCornerRadius="5dp"
- app:cardElevation="5dp">
-
- <RelativeLayout
- android:layout_marginTop="20dp"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <ImageView
-
- android:scaleType="fitXY"
- android:id="@+id/news_pic"
- android:layout_width="190dp"
- android:layout_height="200dp"
- app:srcCompat="@drawable/ic_launcher_background" />
-
- <TextView
- android:maxLines="3"
- android:layout_marginLeft="20dp"
- android:id="@+id/news_title"
- android:layout_toRightOf="@id/news_pic"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="TextView" />
-
- <TextView
- android:maxLines="5"
- android:layout_below="@id/news_title"
- android:layout_alignStart="@id/news_title"
- android:layout_marginTop="30dp"
- android:id="@+id/news_desc"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="TextView" />
- RelativeLayout>
-
-
- androidx.cardview.widget.CardView>
第六步:创建实体类
-
- public class News {
-
- private boolean success;
- private String title;
- private String subtitle;
- private String update_time;
- private List<Data> data;
-
- public String getTitle() {
- return title;
- }
-
- public String getSubtitle() {
- return subtitle;
- }
-
- public String getUpdate_time() {
- return update_time;
- }
-
- public List<Data> getData() {
- return data;
- }
-
- public boolean isSuccess() {
- return success;
- }
-
- public void setSuccess(boolean success) {
- this.success = success;
- }
-
- public News(boolean success, String title, String subtitle, String update_time, List<Data> data) {
- this.success = success;
- this.title = title;
- this.subtitle = subtitle;
- this.update_time = update_time;
- this.data = data;
- }
-
- @Override
- public String toString() {
- return "News{" +
- "success=" + success +
- ", title='" + title + '\'' +
- ", subtitle='" + subtitle + '\'' +
- ", update_time='" + update_time + '\'' +
- ", data=" + data +
- '}';
- }
-
- public static class Data{
- private int index;
- private String title;
- private String desc;
- private String pic;
- private String hot;
- private String url;
- private String mobilUrl;
-
- public int getIndex() {
- return index;
- }
-
- public void setIndex(int index) {
- this.index = index;
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public String getDesc() {
- return desc;
- }
-
- public void setDesc(String desc) {
- this.desc = desc;
- }
-
- public String getPic() {
- return pic;
- }
-
- public void setPic(String pic) {
- this.pic = pic;
- }
-
- public String getHot() {
- return hot;
- }
-
- public void setHot(String hot) {
- this.hot = hot;
- }
-
- public String getUrl() {
- return url;
- }
-
- public void setUrl(String url) {
- this.url = url;
- }
-
- public String getMobilUrl() {
- return mobilUrl;
- }
-
- public void setMobilUrl(String mobilUrl) {
- this.mobilUrl = mobilUrl;
- }
- }
-
- }
第七步:创建适配器
-
-
- public class NewsAdapter extends RecyclerView.Adapter
.ViewHolder> { - private List<News.Data> list;
- public void setList(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_pic);
- holder.news_title.setText(data.getTitle());
- holder.news_desc.setText(data.getDesc());
- }
-
- @Override
- public int getItemCount() {
- return list == null ? 0 : list.size();
- }
-
- public class ViewHolder extends RecyclerView.ViewHolder {
- ImageView news_pic;
- TextView news_title,news_desc;
- View view;
- public ViewHolder(@NonNull View itemView) {
- super(itemView);
- view=itemView;
- news_pic=itemView.findViewById(R.id.news_pic);
- news_title=itemView.findViewById(R.id.news_title);
- news_desc=itemView.findViewById(R.id.news_desc);
- }
- }
- }
第八步:设置适配器
- public class MainActivity extends AppCompatActivity {
- private RecyclerView rv_news;
- private NewsAdapter newsAdapter;
- @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(MainActivity.this);
- rv_news.setLayoutManager(layoutManager);
- rv_news.setAdapter(newsAdapter);
- retrofit();
- }}
第九步:进行网络请求
- public interface News_Interface {
- @GET("api/hotlist?type=zhihuHot")
- Call
getNews() ; - }
第十步:开始网络请求,并处理返回结果
- private void retrofit() {
- Retrofit retrofit=new Retrofit.Builder()
- .baseUrl("https://api.vvhan.com/")
- .addConverterFactory(GsonConverterFactory.create())
- .build();
-
- News_Interface request=retrofit.create(News_Interface.class);
-
- Call
call=request.getNews(); - call.enqueue(new Callback
() { - @Override
- public void onResponse(Call
call, Response response) { - Log.i("news网络请求",response.body().toString());
- newsAdapter.setList(response.body().getData());
-
- }
-
- @Override
- public void onFailure(Call
call, Throwable t) { - Log.i("news网络请求","失败");
- }
- });
-
-
- }