獲取伺服器資料通過Gson解析顯示Listview上
之前寫了一篇博文是獲取伺服器資料並解析顯示到listview上,上次使用的解析是通過jsonarray和jsonobject完成,解析json的資料還是可以,但是發現解析複雜點的資料真的很麻煩,然後查了一下Gson的解析方式寫了一個demo,發現省事了許多.上程式碼:
效果圖: 專案結構圖:
1.json資料:
[ { "title": "網路部", "date": "2017", "counnt": "16", "pic":"http://cdn-img.easyicon.net/png/11184/1118405.gif" }, { "title": "運營部", "date": "2017", "counnt": "6", "pic":"http://cdn-img.easyicon.net/png/11184/1118405.gif" }, { "title": "金融部", "date": "2017", "counnt": "20", "pic":"http://cdn-img.easyicon.net/png/11184/1118405.gif" }, { "title": "其他", "date": "2017", "counnt": "8", "pic":"http://cdn-img.easyicon.net/png/11184/1118405.gif" } ]
2、匯入使用的架包okhttp(網路請求庫)、Gson(谷歌Gson解析庫)、Picasso(圖片載入快取庫)
Gson庫我直接在Androidstudio中新增,其他兩個庫我是複製到libs中
3、activity_main.xml佈局
一個簡單的listview控制元件
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.wdl.gson.MainActivity"> <ListView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/lv"/> </RelativeLayout>
建立佈局listview_item,,用來顯示每個listview的item內容,佈局中程式碼:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.wdl.adapter.useradapter"> <LinearLayout android:layout_width="match_parent" android:orientation="horizontal" android:layout_height="wrap_content"> <ImageView android:id="@+id/img" android:layout_gravity="center" android:layout_width="100dp" android:layout_height="50dp" android:gravity="center" android:src="@mipmap/ic_launcher" /> <LinearLayout android:layout_width="match_parent" android:orientation="vertical" android:layout_height="wrap_content"> <TextView android:id="@+id/tv1" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:layout_marginTop="10dp" android:text="部門"/> <TextView android:id="@+id/tv2" android:layout_width="match_parent" android:gravity="center" android:layout_height="wrap_content" android:text="時間"/> <TextView android:id="@+id/tv3" android:layout_width="match_parent" android:gravity="center" android:layout_height="wrap_content" android:layout_marginBottom="10dp" android:text="人數"/> </LinearLayout> </LinearLayout> </LinearLayout>
4、建立實體類user,提供get,set方法(每個的名稱必須和json資料的名稱一致,否則執行顯示為null)
public class user {
private String title;//部門
private String date;//時間
private String counnt;//人數
private String pic;//圖片
public user(String title, String date, String counnt,String pic) {
this.title = title;
this.date = date;
this.counnt = counnt;
this.pic=pic;
}
public String getTitle() {
return title;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
public void setTitle(String title) {
this.title = title;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getCounnt() {
return counnt;
}
public void setCounnt(String counnt) {
this.counnt = counnt;
}
}
5、修改MainActivity.java中程式碼:
public class MainActivity extends AppCompatActivity {
public String date;
public ListView lv;
public ArrayList<user> listuser;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv= (ListView) findViewById(R.id.lv);
init();
//listview點選事件
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this,""+listuser.get(position).getTitle(),Toast.LENGTH_LONG).show();
}
});
}
//獲取json資料部分
private void init() {
new Thread(new Runnable() {
public void run() {
OkHttpClient okHttpClient = new OkHttpClient();
//伺服器返回的地址
Request request = new Request.Builder()
.url("http://192.168.1.154/user.json").build();
try {
Response response = okHttpClient.newCall(request).execute();
//獲取到資料
date = response.body().string();
//線上程中沒有辦法實現主執行緒操作
Message message = new Message();
message.what = 1;
han.sendMessage(message);
//把資料傳入解析josn資料方法
Gsonjx(date);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
public android.os.Handler han = new android.os.Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
Toast.makeText(MainActivity.this,""+date,Toast.LENGTH_LONG).show();
break;
case 2:
lv.setAdapter(new useradapter(MainActivity.this, listuser));//呼叫listview介面卡
break;
}
}
};
private void Gsonjx(String date) { //gson解析部分
JsonParser parser = new JsonParser();
JsonArray jsonArray = parser.parse(date).getAsJsonArray();
Gson gson = new Gson();
listuser = new ArrayList<>();
for (JsonElement user : jsonArray) {
user userBean = gson.fromJson(user, user.class);
listuser.add(userBean);
}
Message message = new Message();
message.what = 2;
han.sendMessage(message);
}
}
6、建立介面卡useradapter
public class useradapter extends BaseAdapter {
public Context con;
public List<user> list;
public LayoutInflater inflater;
public useradapter(Context context, List<user> user){
this.con=context;
this.list=user;
inflater=LayoutInflater.from(con);
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view= inflater.inflate(R.layout.listview_item,null);
TextView tv1= (TextView) view.findViewById(R.id.tv1);
TextView tv2= (TextView) view.findViewById(R.id.tv2);
TextView tv3= (TextView) view.findViewById(R.id.tv3);
ImageView img= (ImageView) view.findViewById(R.id.img);
tv1.setText("部門:"+list.get(position).getTitle());
tv2.setText("時間:"+list.get(position).getDate());
tv3.setText("人數:"+list.get(position).getCounnt());
//判斷獲取的json中圖片是否為空
if (TextUtils.isEmpty(list.get(position).getPic().toString())){
Picasso
.with(con)
.cancelRequest(img);
img.setImageDrawable(con.getResources().getDrawable(R.mipmap.ic_launcher));//當圖片為空時顯示原始機器人圖
}else {
//圖片載入
Picasso
.with(con)
.load(list.get(position).getPic().toString())
.placeholder(R.mipmap.ic_launcher)//圖片載入中時顯示原始機器人圖
.into(img);
}
return view;
}
}
7、最後一步新增許可權:
在AndroidManifest.xml中新增訪問網路許可權
<uses-permission android:name="android.permission.INTERNET" />
8、錯誤資訊
(1)、如果你發現執行結果的資訊顯示為null,請檢查實體類裡的變數名稱是否和json資料的內容相同
(2)、如果你發現報錯的資訊是: com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated object at line 20 column 10 path $[2].counnt,請使用json工具檢查json資料是否正確。
二、使用Gson解析稍微複雜json資料
json資料:
{
"result": "true",
"counnts": 4,
"user": [
{
"title": "網路部",
"date": "2017",
"counnt": "16",
"pic": "http://cdn-img.easyicon.net/png/11184/1118405.gif"
},
{
"title": "運營部",
"date": "2017",
"counnt": "6",
"pic": "http://cdn-img.easyicon.net/png/11184/1118405.gif"
},
{
"title": "金融部",
"date": "2017",
"counnt": "20",
"pic": "http://cdn-img.easyicon.net/png/11184/1118405.gif"
},
{
"title": "其他",
"date": "2017",
"counnt": "8",
"pic": "http://cdn-img.easyicon.net/png/11184/1118405.gif"
}
]
}
1、建立實體類
public class UserBean {
//變數名需要與json欄位的名稱一致
private String result;
private int counnts;
private List<user> user;
public class user{
private String title;
private String date;
private String counnt;
private String pic;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getCounnt() {
return counnt;
}
public void setCounnt(String counnt) {
this.counnt = counnt;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public int getCounnts() {
return counnts;
}
public void setCounnts(int counnts) {
this.counnts = counnts;
}
public List<UserBean.user> getUser() {
return user;
}
public void setUser(List<UserBean.user> user) {
this.user = user;
}
}
2、更改解析方法程式碼
private void Gsonjx(String date) {
UserBean resultBean = new Gson().fromJson(date,UserBean.class);
List<UserBean.user> listuser = resultBean.getUser();
Message message = new Message();
message.what = 2;
han.sendMessage(message);
}
一些listview適配程式碼就不貼了和上面一樣就改了一下Gsonjx()方法裡的程式碼