Retrofit学习笔记

本文介绍了Retrofit的基本使用,包括添加依赖、创建Retrofit实例、设置转换工厂和基础URL,以及如何发起网络请求。同时,总结了使用过程中可能遇到的问题,如Base URL不能为空、必须以'/'结尾,以及JSON解析错误等,并提供了相应的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Retrofit:  与okhttp共同出自于Square公司,retrofit就是对okhttp做了一层封装,把网络请求都交给了OkHttp,只需要通过简单的配置就能使用其来进行网络请求。

使用Retrofit的准备工作

1.添加Retrofit依赖

compile 'com.squareup.retrofit2:retrofit:2.1.0'
2.添加响应转换器依赖,Retrofit默认不集成响应转换器的

compile 'com.squareup.retrofit2:converter-gson:2.1.0'
最后不要忘了,声明网络请求的权限

开始创建Retrofit

步骤一:
Retrofit将HTTP API转化为了接口的形式,因此,我们提供如下接口:
public interface HttpJson {
   @GET
    Call<Apps> getAppLists(@Url String url);
}
步骤二:

 Retrofit retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(UrlPath)
                .build();
        httpJson = retrofit.create(HttpJson.class);
        Call<Apps> appLists = httpJson.getAppLists(UrlPath);

addConverterFactory()为了添加json 解析工具

baseUrl()注意:只能传入以/结尾的网址

httpJson 接口 的一个具体实现,

步骤三

得到call对象,并且可以使用enqueue 或者 execute来执行发起请求,enqueue是是异步执行,而 execute是同步执行。

 appLists.enqueue(new Callback<Apps>() {
            @Override
            public void onResponse(Call<Apps> call, Response<Apps> response) {
                if(response.body() !=null) { 
                    Log.d("LXM", response.body()+ "");
                }
                else{
                    Log.d("LXM","response is null");
                }
            }

            @Override
            public void onFailure(Call<Apps> call, Throwable t) {
                Log.d("LXM",t.getMessage());
            }
        });
我们所请求的数据,都会在response.body()中返回

问题总结

1.Base URL required

出现这个错误是因为,Base URL为空,这是因为源码在构建的过程中,会检查 Base URL,如果Base URL为空,则会抛出这个异常

2.java.lang.IllegalArgumentException: baseUrl must end in /:

Base URL规定,它最后一定要以/结尾

我们知道,很多时候,我们的网址掺杂了很多参数,是无法做到/结尾的,此时,我们要借助@URL,如下:

public interface HttpJson {
   @GET
    Call<Apps> getAppLists(@Url String url);
}
注意:@GET在这里是没有任何参数,当使用了@URL时,会默认使用传进来的URL的参数,这个特殊的用法可以支持URL是动态变化的情况,并且解决了Base URL必须以/结尾的规定

3. Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

Json数据为嵌套形式时,对象抽取不当,如下

{ "ret": "0",
 "data": { "appList": [
 		{ "fileSize": "12431425", "appName": "贝瓦儿歌", "icon": "http://img.sky.fs.skysrt.com///uploads/20160607/20160607140722707425.png", "appRunType": 0},
		{ "fileSize": "14022612", "appName": "逸趣休闲", "icon": "http://img.sky.fs.skysrt.com///uploads/20161022/20161022144435531698.png", "appRunType": 0}, 
		{ "fileSize": "14047310", "appName": "风尚舞汇", "icon": "http://img.sky.fs.skysrt.com///uploads/20161022/20161022144303406615.png", "appRunType": 0}, 
		{ "fileSize": "1271215", "appName": "精华E课堂", "icon": "http://img.sky.fs.skysrt.com///uploads/20140705/20140705094119947612.png", "appRunType": 0}
			], 
	 "total": 4,
	 "count": 4, 
	 "page": 1 },
 "msg": "success" }
我们可以看到,这个json文件中最外层,有三个对象,分别是"ret","data","msg"

而"data"对象又包含四个对象"appList","total",count","page"

其中,appList对象的值是一组数组,此时,要想正确获取对象值,需要三个类

APPS,包含"ret","data","msg"对象

APPListmsg, 包含"appList","total",count","page",

AppList.为“data”数组中单项的对象类

代码如下

json最外层的数据结构

public class Apps {
    private String ret;
    private APPListmsg data;
    private String msg;
        public void setData(AppLists data) {
        this.data = data;
    }
    public AppLists getData() {
        return data;
    }

    public void setRet(String ret) {
        this.ret = ret;
    }
    public String getRet() {
        return ret;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
    public String getMsg() {
        return msg;
    }
}
数组中数据的数据结构
public class AppList {
    private String fileSize;
    private String appName;
    private String icon;
    private String appRunType;
    public AppList(){}
    public AppList(String fileSize, String appName, String icon, String appRunType){
        this.fileSize = fileSize;
        this.appName = appName;
        this.icon = icon;
        this.appRunType = appRunType;
    } 

    public String getAppRunType() {
        return appRunType;
    }
    public void setAppRunType(String appRunType) {
        this.appRunType = appRunType;
    }

    public String getIcon() {
        return icon;
    }
    public void setIcon(String icon) {
        this.icon = icon;
    }

    public String getFileSize() {
        return fileSize;
    }
    public void setFileSize(String fileSize) {
        this.fileSize = fileSize;
    }

    public String getAppName() {
        return appName;
    }
    public void setAppName(String appName) {
        this.appName = appName;
    }



}

data对象的数据结构

public class APPListmsg  {
    private List<AppList> appList;

    public List<AppList> getAppList() {
        return appList;
    }

    public void setAppLists(List<AppList> appList) {
        this.appList = appList;
    }
}

范例代码如下:

 public void test3(){
        Retrofit retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(UrlPath)
                .build();
        httpJson = retrofit.create(HttpJson.class);
        Call<Apps> appLists = httpJson.getAppLists(UrlPath);
        appLists.enqueue(new Callback<Apps>() {
            @Override
            public void onResponse(Call<Apps> call, Response<Apps> response) {
                if(response.body() !=null) {
                    List<AppList> apps = response.body().getData().getAppList();
                    Log.d("LXM", apps + "");
                    for (int i = 0; i < apps.size(); i++) {
                        Log.d("LXM", apps.get(i).getAppName());
                    }
                }
                else{
                    Log.d("LXM","response is null");
                }
            }

            @Override
            public void onFailure(Call<Apps> call, Throwable t) {
                Log.d("LXM",t.getMessage());
            }
        });
    }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值