Retrofit學習筆記

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());
            }
        });
    }




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章