1. 程式人生 > >獲取伺服器資料通過Gson解析顯示Listview上

獲取伺服器資料通過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()方法裡的程式碼