淺析Android整合OKHttp與Gson實例
Json 介紹
JsonObject 對應Json字符串中用{}包裹的數(shù)據(jù),相當于一個實體類
JsonArray對應Json字符串中用[]包裹的數(shù)據(jù),相當于一個數(shù)組
下面為從某個服務器中拉去的數(shù)據(jù),其中data為數(shù)據(jù)核心部分,minfo為一個數(shù)組,其中包含所需要渲染的數(shù)據(jù),filter為一個數(shù)據(jù)實體,包含篩選條件信息。
{
"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)建對應格式化實體類
從服務器端拉去的Json字符串,需要創(chuàng)建對應的實體類進行接收,本文介紹一種插件,用于Android端格式化建立實體類
安裝插件GsonFormatPlus
點擊設置->plugins->搜索并安裝插件GsonFormatPlus插件

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

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

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

踩坑筆記
如果你不想一次性創(chuàng)建所有的Json數(shù)據(jù)對于的實體類,也就是說,你所請求的Json字符串你不想創(chuàng)建在一個實體類中,比如下面Json字符串為例,下面的minfo是一個數(shù)組,如果你想把這個數(shù)組內(nèi)的數(shù)據(jù)單獨建立一個實體類,你需要把這個字段定義為JsonArray類型,注意不是全大寫,全大寫是另外一個類,會出錯,JsonObject同理。這樣可以讓數(shù)據(jù)更加層次分明,在不同的地方引用時,較為方便。
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ù)解析
引入依賴
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封裝
將請求體用map進行鍵值對進行添加,然后使用表單進行提交。在建立Request對象將請求體進行上傳,然后在newCall中接受服務器回調(diào),此類是一個封裝類,只取出第一層數(shù)據(jù)體,因為不同的接口所返回的數(shù)據(jù)內(nèi)容不一樣,Json體也不一樣,所有此處只對第一層進行解析,然后在不同的地方調(diào)用時,在進行具體解析。
/**
* @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)
建立一個回調(diào)接口,將解析結(jié)果暴露給外部
public interface HttpCallback<T> {
void onFailure(int error);
void onResponse(T data) throws JSONException;
}
完整封裝
因為隱私,服務器接口和請求體暫不外露,其余內(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(){
//因為隱私,請求體省略
}
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解析
然后在外部進行服務器地址、請求體上傳,在進行進一步解析,在下面通過剛剛建立的回調(diào)接口,在OnFailure()中進行錯誤解析回調(diào),并處理;在OnResponse()中進行json字符串獲取,此字符串已經(jīng)被解析了一層,在根據(jù)不同的接口回調(diào),做出不同響應即可,此處將獲取的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進行監(jiān)聽,此框架一目了然,subscribe()建立被觀察者,subscribe()建立觀察者,然后onNext()、onComplete(),此處回調(diào)的數(shù)據(jù)較多,又分為不同的場景,頭部有一個輪播圖baner數(shù)據(jù),下面有一個RecyclerView嵌套RecyclerView,需要根據(jù)判斷解析的Display_type判斷其顯示方式,從而決定RecyclerView是橫向顯示還是豎向顯示。最后通過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);
}
});
}
到此這篇關于淺析Android整合OKHttp與Gson實例的文章就介紹到這了,更多相關Android OKHttp Gson內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Android自定義控件實現(xiàn)帶文本與數(shù)字的圓形進度條
這篇文章主要為大家詳細介紹了Android自定義控件實現(xiàn)帶文本與數(shù)字的圓形進度條,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-12-12
Android編程實現(xiàn)自定義ImageView圓圖功能的方法
這篇文章主要介紹了Android編程實現(xiàn)自定義ImageView圓圖功能的方法,結(jié)合實例形式分析了Android自定義ImageView及實現(xiàn)圓圖效果的具體步驟與相關操作技巧,需要的朋友可以參考下2017-08-08
Android提高之使用NDK把彩圖轉(zhuǎn)換灰度圖的方法
這篇文章主要介紹了Android使用NDK把彩圖轉(zhuǎn)換灰度圖的方法,在Android項目開發(fā)中有一定的實用價值,需要的朋友可以參考下2014-08-08
實現(xiàn)輪轉(zhuǎn)廣告帶底部指示的自定義ViewPager控件
在項目中經(jīng)常需要使用輪轉(zhuǎn)廣告的效果,在android-v4版本中提供的ViewPager是一個很好的工具,而一般我們使用Viewpager的時候,都會選擇在底部有一排指示物指示當前顯示的是哪一個page,下面我們就做這個功能的實現(xiàn)2013-11-11

