淺析Android整合OKHttp與Gson實(shí)例
Json 介紹
JsonObject 對(duì)應(yīng)Json字符串中用{}包裹的數(shù)據(jù),相當(dāng)于一個(gè)實(shí)體類(lèi)
JsonArray對(duì)應(yīng)Json字符串中用[]包裹的數(shù)據(jù),相當(dāng)于一個(gè)數(shù)組
下面為從某個(gè)服務(wù)器中拉去的數(shù)據(jù),其中data為數(shù)據(jù)核心部分,minfo為一個(gè)數(shù)組,其中包含所需要渲染的數(shù)據(jù),filter為一個(gè)數(shù)據(jù)實(shí)體,包含篩選條件信息。
{
"status":"200",
"msg
":"success",
"source":"156",
"data":{
"data_type":"2",
"minfo":Array[30],
"filter":{
"orderby":[
{
"title":"Popular",
"id":"1"
},
Object{...},
Object{...}
],
"genre":Array[27],
"pub":Array[12],
"type":Array[3],
"country":Array[49]
}
}
}
創(chuàng)建對(duì)應(yīng)格式化實(shí)體類(lèi)
從服務(wù)器端拉去的Json字符串,需要?jiǎng)?chuàng)建對(duì)應(yīng)的實(shí)體類(lèi)進(jìn)行接收,本文介紹一種插件,用于Android端格式化建立實(shí)體類(lèi)
安裝插件GsonFormatPlus
點(diǎn)擊設(shè)置->plugins->搜索并安裝插件GsonFormatPlus插件

創(chuàng)建實(shí)體類(lèi)
第一步,在需要?jiǎng)?chuàng)建實(shí)體類(lèi)的地方右擊空白處,在彈出的顯示框中選擇Generate

第二步,然后在選擇剛才安裝的插件GsonFormatPlus

第三步,最后將Json字符串復(fù)制上去,點(diǎn)擊OK即可自動(dòng)創(chuàng)建

踩坑筆記
如果你不想一次性創(chuàng)建所有的Json數(shù)據(jù)對(duì)于的實(shí)體類(lèi),也就是說(shuō),你所請(qǐng)求的Json字符串你不想創(chuàng)建在一個(gè)實(shí)體類(lèi)中,比如下面Json字符串為例,下面的minfo是一個(gè)數(shù)組,如果你想把這個(gè)數(shù)組內(nèi)的數(shù)據(jù)單獨(dú)建立一個(gè)實(shí)體類(lèi),你需要把這個(gè)字段定義為JsonArray類(lèi)型,注意不是全大寫(xiě),全大寫(xiě)是另外一個(gè)類(lèi),會(huì)出錯(cuò),JsonObject同理。這樣可以讓數(shù)據(jù)更加層次分明,在不同的地方引用時(shí),較為方便。
private JsonArray orderby;
{
"status":"200",
"msg
":"success",
"source":"156",
"data":{
"data_type":"2",
"minfo":Array[30],
"filter":{
"orderby":[
{
"title":"Popular",
"id":"1"
},
Object{...},
Object{...}
],
"genre":Array[27],
"pub":Array[12],
"type":Array[3],
"country":Array[49]
}
}
}
Json數(shù)據(jù)解析
引入依賴(lài)
implementation 'com.squareup.okhttp3:okhttp:3.1.0'
implementation 'com.squareup.okio:okio:1.5.0'
implementation 'com.google.code.gson:gson:2.8.0'
OkHttp封裝
將請(qǐng)求體用map進(jìn)行鍵值對(duì)進(jìn)行添加,然后使用表單進(jìn)行提交。在建立Request對(duì)象將請(qǐng)求體進(jìn)行上傳,然后在newCall中接受服務(wù)器回調(diào),此類(lèi)是一個(gè)封裝類(lèi),只取出第一層數(shù)據(jù)體,因?yàn)椴煌慕涌谒祷氐臄?shù)據(jù)內(nèi)容不一樣,Json體也不一樣,所有此處只對(duì)第一層進(jìn)行解析,然后在不同的地方調(diào)用時(shí),在進(jìn)行具體解析。
/**
* @param url connect server address
* @param map request param
* @param callback bind success or fail callback*/
public void Post(String url,Map<String,Object> map,HttpCallback callback) {
OkHttpClient client = new OkHttpClient();
FormBody.Builder requestBuild = new FormBody.Builder();
for (Map.Entry<String,Object> mEntry : map.entrySet()) {
requestBuild.add(mEntry.getKey(),mEntry.getValue()+"");
}
RequestBody requestBody = requestBuild.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("getInternetData","error message = "+e.getMessage());
callback.onFailure(ErrorParam.POSTINGERROR);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String body = response.body().string();
int code = response.code();
if (code == 200){
try {
JSONObject jsonObject = new JSONObject(body);
int status_code = jsonObject.getInt("status");
if (status_code == 200){
String data = jsonObject.getString("data");
callback.onResponse(data);
}else {
callback.onFailure(ErrorParam.NETWORKERROR);//net error
}
} catch (JSONException e) {
Log.e("getBannerData","error");
callback.onFailure(ErrorParam.RESOLVINGERROR);//resolve error
e.printStackTrace();
}
}else {
callback.onFailure(ErrorParam.SERVERERROR);//service error
}
}
});
}
JsonObject解析
* resolve jsonboject*/
public static <T> T fromJson(String josn,Class<T> c){
Gson gson = new Gson();
T t = null;
return t = gson.fromJson(josn,c);
}
JsonArray解析
public static <T> List<T> fromListJson(String json,Class<T> c){
List<T> list = new ArrayList<>();
Gson gson = new Gson();
JsonArray array = new JsonParser().parse(json).getAsJsonArray();
for (final JsonElement element: array) {
list.add(gson.fromJson(element,c));
}
return list;
}
回調(diào)
建立一個(gè)回調(diào)接口,將解析結(jié)果暴露給外部
public interface HttpCallback<T> {
void onFailure(int error);
void onResponse(T data) throws JSONException;
}
完整封裝
因?yàn)殡[私,服務(wù)器接口和請(qǐng)求體暫不外露,其余內(nèi)容如下所示
public class OKHttpUtils {
private static Map<String,Object> map = new HashMap<>();
private static OKHttpUtils singleton;
private OKHttpUtils(){
}
public static OKHttpUtils getInstance(){
if (singleton == null){
Sync();
}
return singleton;
}
private static synchronized void Sync(){
if (singleton == null){
singleton = new OKHttpUtils();
InitMap();
}
}
/**
* @param url connect server address
* @param map request param
* @param callback bind success or fail callback*/
public void Post(String url,Map<String,Object> map,HttpCallback callback) {
OkHttpClient client = new OkHttpClient();
FormBody.Builder requestBuild = new FormBody.Builder();
for (Map.Entry<String,Object> mEntry : map.entrySet()) {
requestBuild.add(mEntry.getKey(),mEntry.getValue()+"");
}
RequestBody requestBody = requestBuild.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("getInternetData","error message = "+e.getMessage());
callback.onFailure(ErrorParam.POSTINGERROR);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String body = response.body().string();
Log.d("sss",body.toString());
int code = response.code();
if (code == 200){
try {
JSONObject jsonObject = new JSONObject(body);
int status_code = jsonObject.getInt("status");
if (status_code == 200){
String data = jsonObject.getString("data");
callback.onResponse(data);
}else {
callback.onFailure(ErrorParam.NETWORKERROR);//net error
}
} catch (JSONException e) {
Log.e("getBannerData","error");
callback.onFailure(ErrorParam.RESOLVINGERROR);//resolve error
e.printStackTrace();
}
}else {
callback.onFailure(ErrorParam.SERVERERROR);//service error
}
}
});
}
/**
* public request param*/
private static void InitMap(){
//因?yàn)殡[私,請(qǐng)求體省略
}
public Map<String,Object> getMap(){
return map;
}
public String setUrl(String port){
return PortParam.BaseUrl+port;
}
/**
* resolve jsonboject*/
public static <T> T fromJson(String josn,Class<T> c){
Gson gson = new Gson();
T t = null;
return t = gson.fromJson(josn,c);
}
/**
* resolve jsonarray*/
public static <T> List<T> fromListJson(String json,Class<T> c){
List<T> list = new ArrayList<>();
Gson gson = new Gson();
JsonArray array = new JsonParser().parse(json).getAsJsonArray();
for (final JsonElement element: array) {
list.add(gson.fromJson(element,c));
}
return list;
}
}
Json解析
然后在外部進(jìn)行服務(wù)器地址、請(qǐng)求體上傳,在進(jìn)行進(jìn)一步解析,在下面通過(guò)剛剛建立的回調(diào)接口,在OnFailure()中進(jìn)行錯(cuò)誤解析回調(diào),并處理;在OnResponse()中進(jìn)行json字符串獲取,此字符串已經(jīng)被解析了一層,在根據(jù)不同的接口回調(diào),做出不同響應(yīng)即可,此處將獲取的json字符串轉(zhuǎn)為數(shù)組形式。
private void Post(){
OKHttpUtils utils = OKHttpUtils.getInstance();
Map<String,Object> map = utils.getMap();
//內(nèi)容省略...map.put("","");
utils.Post(utils.setUrl(PortParam.TvShowsPort), map, new HttpCallback() {
@Override
public void onFailure(int error) {
switch (error){
case ErrorParam.NETWORKERROR:
break;
case ErrorParam.SERVERERROR:
break;
case ErrorParam.RESOLVINGERROR:
break;
case ErrorParam.POSTINGERROR:
handler.sendEmptyMessage(4);
break;
}
}
@Override
public void onResponse(Object data) throws JSONException {
array = new JSONArray(data.toString());
handler.sendEmptyMessage(0);
}
});
}
然后使用rxjava進(jìn)行監(jiān)聽(tīng),此框架一目了然,subscribe()建立被觀察者,subscribe()建立觀察者,然后onNext()、onComplete(),此處回調(diào)的數(shù)據(jù)較多,又分為不同的場(chǎng)景,頭部有一個(gè)輪播圖baner數(shù)據(jù),下面有一個(gè)RecyclerView嵌套R(shí)ecyclerView,需要根據(jù)判斷解析的Display_type判斷其顯示方式,從而決定RecyclerView是橫向顯示還是豎向顯示。最后通過(guò)handler異步渲染UI。
private void UpdateUI(){
Observable.create(new ObservableOnSubscribe<FeaturedData>() {
@Override
public void subscribe(@NotNull ObservableEmitter<FeaturedData> observableEmitter) throws Exception {
if (featuredDataList != null){
for (int i = 0; i < featuredDataList.size(); i++) {
if (featuredDataList.get(i).getData_type().equals("1")){
observableEmitter.onNext(featuredDataList.get(i));
}
}
observableEmitter.onComplete();
}
}
}).subscribe(new Observer<FeaturedData>() {
@Override
public void onSubscribe(@NotNull Disposable disposable) {
}
@Override
public void onNext(@NotNull FeaturedData featuredData) {
if (featuredData.getName().equals("Banner")){
try {
JSONArray array = new JSONArray(featuredData.getData().toString());
featureBannerDataList = OKHttpUtils.fromListJson(array.toString(),FeatureBannerData.class);
//update banner
handler.sendEmptyMessage(2);
} catch (JSONException e) {
e.printStackTrace();
}
}else if (featuredData.getDisplay_type().equals("1")){
//v
JSONArray jsonArray = null;
JSONObject object = null;
try {
jsonArray = new JSONArray(featuredData.getData().toString());
object = jsonArray.getJSONObject(0);
} catch (JSONException e) {
e.printStackTrace();
}
FeatureInnerData data = OKHttpUtils.fromJson(object.toString(),FeatureInnerData.class);
data.setSlide_way(1);
featureInnerDataList.add(data);
}else {
//H
JSONArray jsonArray = null;
JSONObject object = null;
try {
jsonArray = new JSONArray(featuredData.getData().toString());
object = jsonArray.getJSONObject(0);
} catch (JSONException e) {
e.printStackTrace();
}
FeatureInnerData data = OKHttpUtils.fromJson(object.toString(),FeatureInnerData.class);
data.setSlide_way(2);
featureInnerDataList.add(data);
}
}
@Override
public void onError(@NotNull Throwable throwable) {
}
@Override
public void onComplete() {
handler.sendEmptyMessage(3);
}
});
}
到此這篇關(guān)于淺析Android整合OKHttp與Gson實(shí)例的文章就介紹到這了,更多相關(guān)Android OKHttp Gson內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android安裝應(yīng)用 INSTALL_FAILED_DEXOPT 問(wèn)題及解決辦法
這篇文章主要介紹了Android安裝應(yīng)用 INSTALL_FAILED_DEXOPT 解決辦法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
Android中用Bmob實(shí)現(xiàn)短信驗(yàn)證碼功能的方法詳解
本文給大家分享通過(guò)第三方平臺(tái)Bmob實(shí)現(xiàn)發(fā)送驗(yàn)證碼和校驗(yàn)驗(yàn)證碼的功能,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧2016-09-09
Android自定義View弧線(xiàn)進(jìn)度控件
這篇文章主要為大家詳細(xì)介紹了Android自定義View弧線(xiàn)進(jìn)度控件,點(diǎn)擊開(kāi)始按鈕時(shí),逐漸的出現(xiàn)進(jìn)度,感興趣的小伙伴們可以參考一下2016-07-07
android實(shí)現(xiàn)歌詞自動(dòng)滾動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)歌詞自動(dòng)滾動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
Android EditText限制輸入字符的方法總結(jié)
這篇文章主要介紹了 Android EditText限制輸入字符的方法總結(jié)的相關(guān)資料,這里提供了五種方法來(lái)實(shí)現(xiàn)并進(jìn)行比較,需要的朋友可以參考下2017-07-07
Android實(shí)現(xiàn)調(diào)用系統(tǒng)圖庫(kù)與相機(jī)設(shè)置頭像并保存在本地及服務(wù)器
這篇文章主要介紹了Android實(shí)現(xiàn)調(diào)用系統(tǒng)圖庫(kù)與相機(jī)設(shè)置頭像并保存在本地及服務(wù)器 ,需要的朋友可以參考下2017-03-03
Android SeekBar實(shí)現(xiàn)禁止滑動(dòng)
這篇文章主要為大家詳細(xì)介紹了Android SeekBar實(shí)現(xiàn)禁止滑動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03
Android使用recyclerview打造真正的下拉刷新上拉加載效果
這篇文章先介紹如何使用這個(gè)recyclerview,WZMRecyclerview 是一個(gè)集成了 下拉刷新、上拉加載、滑到底部自動(dòng)加載、添加刪除頭尾部 四個(gè)主要功能的recyclerview,需要的朋友可以參考下2016-11-11
Android中Service實(shí)時(shí)向Activity傳遞數(shù)據(jù)實(shí)例分析
這篇文章主要介紹了Android中Service實(shí)時(shí)向Activity傳遞數(shù)據(jù)的方法,實(shí)例分析了Service組件基于線(xiàn)程操作實(shí)現(xiàn)數(shù)值實(shí)時(shí)傳遞的相關(guān)技巧,需要的朋友可以參考下2015-09-09

