65.9K
CodeProject 正在变化。 阅读更多。
Home

Android JSON 解析教程

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (4投票s)

2016 年 7 月 18 日

CPOL

6分钟阅读

viewsIcon

36061

Android JSON 解析教程。

JSON (JavaScript Object Notation) 是一种与语言无关的数据格式,它使用人类可读的文本来传输由键值对组成的数据对象。

在本教程中,我们将解释 JSON 响应的结构以及如何解析响应以获取所需信息。为了解释这个概念,我们将使用两个示例 JSON 响应。

[{"rom":"32GB","screenSize":"5.5 inch","backCamera":"21MP","companyName":"Motorola","name":"Moto X Play","frontCamera":"5MP","battery":"3630mAH","operatingSystem":"Android 5.1","processor":"1.8GHz","url":"http://www.androidtutorialpoint.com/api/motorola_moto_x_play","ram":"2GB"},{"rom":"8GB","screenSize":"4 inch","backCamera":"5MP","companyName":"Samsung","name":"Galaxy S Duos 3","frontCamera":"0.3MP","battery":"1500mAH","operatingSystem":"Android 4.4","processor":"1.2GHz","url":"http://www.androidtutorialpoint.com/api/samsung_galaxy_s_dous_3","ram":"512MB"},{"rom":"64GB","screenSize":"4.7 inch","backCamera":"12MP","companyName":"Apple","name":"Iphone 6S","frontCamera":"5MP","battery":"1715mAH","operatingSystem":"iOS 9","processor":"1.84GHz","url":"http://www.androidtutorialpoint.com/api/apple_iphone_6s","ram":"2GB"},{"rom":"16GB","screenSize":"5.2 inch","backCamera":"12.3MP","companyName":"LG","name":"Nexus 5X","frontCamera":"5MP","battery":"1500mAH","operatingSystem":"Android 6","processor":"1.8GHz","url":"http://www.androidtutorialpoint.com/api/lg_nexus_5x","ram":"2GB"}]
{"rom":"32GB","screenSize":"5.5 inch","backCamera":"21MP","companyName":"Motorola","name":"Moto X Play","frontCamera":"5MP","battery":"3630mAH","operatingSystem":"Android 5.1","processor":"1.8GHz","url":"http://www.androidtutorialpoint.com/api/motorola_moto_x_play","ram":"2GB"}

这些链接分别包含 JSON 数组和 JSON 对象的示例 JSON 响应。在开始构建应用程序之前,让我们先深入了解一下 JSON 响应的结构。

Consider following JSON Response :

[
        {
            "rom":"32GB",
            "screenSize":"5.5 inch",
            "backCamera":"21MP",
            "companyName":"Motorola",
            "name":"Moto X Play",
            "frontCamera":"5MP",
            "battery":"3630mAH",
            "operatingSystem":"Android 5.1",
            "processor":"1.8GHz",
            "url":"http://www.androidtutorialpoint.com/api/motorola_moto_x_play",
            "ram":"2GB"
        },
        {
            "rom":"8GB",
            "screenSize":"4 inch",
            "backCamera":"5MP",
            "companyName":"Samsung",
            "name":"Galaxy S Duos 3",
            "frontCamera":"0.3MP",
            "battery":"1500mAH",
            "operatingSystem":"Android 4.4",
            "processor":"1.2GHz",
            "url":"http://www.androidtutorialpoint.com/api/samsung_galaxy_s_dous_3",
            "ram":"512MB"},{"rom":"64GB",
            "screenSize":"4.7 inch",
            "backCamera":"12MP",
            "companyName":"Apple",
            "name":"Iphone 6S",
            "frontCamera":"5MP",
            "battery":"1715mAH",
            "operatingSystem":"iOS 9",
            "processor":"1.84GHz",
            "url":"http://www.androidtutorialpoint.com/api/apple_iphone_6s",
            "ram":"2GB"
        },
        {
            "rom":"16GB",
            "screenSize":"5.2 inch",
            "backCamera":"12.3MP",
            "companyName":"LG",
            "name":"Nexus 5X",
            "frontCamera":"5MP",
            "battery":"1500mAH",
            "operatingSystem":"Android 6",
            "processor":"1.8GHz",
            "url":"http://www.androidtutorialpoint.com/api/lg_nexus_5x",
            "ram":"2GB"
        }
            ]

从上面可以看出,JSON 响应可以包含以下元素:

  1. JSON 数组 ([):在 JSON 文件中,方括号 ([) 代表一个 JSON 数组。
  2. JSON 对象 ({):在 JSON 文件中,花括号 ({) 代表一个 JSON 对象。
  3. 键 (Key):JSON 对象包含一个键,它只是一个字符串。键/值对构成了 JSON 对象。
  4. 值 (Value):每个键都有一个值,它可以是字符串、整数或双精度数等。

Android 提供了以下类来处理 JSON 响应:
JSONObjectJSONArrayJSONStringerJSONTokener。在本教程中,我们将重点介绍 org.json.JSONObjectorg.json.JSONArray

要解析 JSON 响应,首先需要确定 JSON 响应中你感兴趣的字段。例如,在上面链接中的 JSON 中,我们将使用所有字段。我们需要相应地编写我们的解析函数。

让我们一步一步来创建一个示例 JSON 解析应用程序。我们将演示如何解析 JSON 对象和 JSON 数组。在这个应用程序中,我们将从给定 URL 的 JSON 字符串中检索手机的详细信息,然后将它们显示为列表,点击每个手机后,将显示该手机的详细信息。

先决条件

  1. 您的 PC(Unix 或 Windows)上安装了 Android Studio。
  2. 一台配置了 Android Studio 的真实 Android 设备(智能手机或平板电脑)。

创建新项目

  1. 打开 Android Studio 并创建一个名为“JSONParser”的新项目,公司域为 application.example.com(我们使用了我们的公司域 androidtutorialpoint.com。您也可以使用您自己的)。
  2. 点击“下一步”并选择最小 SDK,我们保留了默认值。再次点击“下一步”并选择空白活动 (Blank Activity)
  3. 将活动命名为 JSONParseActivity,然后点击“下一步”。
  4. 将其他所有内容保留为默认值,然后点击“完成”。

将创建一个新项目,Gradle 将解析所有依赖项。
接下来创建一个手机类。Mobile 类代表手机的模型,即它包含 Mobile 所需的所有字段和方法(getter 和 setter)。因此,创建一个新的 Java 类 Mobile.java 并将以下代码放入其中。

Mobile.java

package com.androidtutorialpoint.jsonparser;
import java.io.Serializable;

public class Mobile implements Serializable{
    private String mName;
    private String mCompanyName;
    private String mOperatingSystem;
    private String mProcessor;
    private String mRam;
    private String mRom;
    private String mFrontCamera;
    private String mBackCamera;
    private String mScreenSize;
    private String mBattery;
    private String mUrl;
    public String getName() {
        return mName;
    }
    public void setName(String mName) {
        this.mName = mName;
    }
    public String getCompanyName() {
        return mCompanyName;
    }
    public void setCompanyName(String mCompanyName) {
        this.mCompanyName = mCompanyName;
    }
    public String getOperatingSystem() {
        return mOperatingSystem;
    }
    public void setOperatingSystem(String mOperatingSystem) {
        this.mOperatingSystem = mOperatingSystem;
    }
    public String getProcessor() {
        return mProcessor;
    }
    public void setProcessor(String mProcessor) {
        this.mProcessor = mProcessor;
    }
    public String getRam() {
        return mRam;
    }
    public void setRam(String mRam) {
        this.mRam = mRam;
    }
    public String getRom() {
        return mRom;
    }
    public void setRom(String mRom) {
        this.mRom = mRom;
    }
    public String getFrontCamera() {
        return mFrontCamera;
    }
    public void setFrontCamera(String mFrontCamera) {
        this.mFrontCamera = mFrontCamera;
    }
    public String getBackCamera() {
        return mBackCamera;
    }
    public void setBackCamera(String mBackCamera) {
        this.mBackCamera = mBackCamera;
    }
    public String getScreenSize() {
        return mScreenSize;
    }
    public void setScreenSize(String mScreenSize) {
        this.mScreenSize = mScreenSize;
    }
    public String getBattery() {
        return mBattery;
    }
    public void setBattery(String mBattery) {
        this.mBattery = mBattery;
    }
    public String getUrl() {
        return mUrl;
    }
    public void setUrl(String mUrl) {
        this.mUrl = mUrl;
    }
}

我们实现了 Serializable 接口,因为我们将把 Mobile 对象从一个活动传递到另一个活动。
接下来,创建两个函数 parseFeed()parseArrayFeed() 来分别解析 JSONObjectJSONArray。在解析 JSON 响应时,可能会遇到 org.json.JSONException,因此我们将把解析逻辑写在 try/catch 块中。
parseFeed()JSONObject 作为参数,并设置手机对象的所有属性。

JSONParser.java

package com.androidtutorialpoint.jsonparser;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;

public class JSONParser {
   public static ArrayList<Mobile> mMobiles = new ArrayList<>();
    public static Mobile parseFeed(JSONObject obj) {

        try {
                Mobile mobile = new Mobile();
                mobile.setName(obj.getString("name"));
                mobile.setCompanyName(obj.getString("companyName"));
                mobile.setOperatingSystem(obj.getString("operatingSystem"));
                mobile.setProcessor(obj.getString("processor"));
                mobile.setBackCamera(obj.getString("backCamera"));
                mobile.setFrontCamera(obj.getString("frontCamera"));
                mobile.setRam(obj.getString("ram"));
                mobile.setRom(obj.getString("rom"));
                mobile.setScreenSize(obj.getString("screenSize"));
                mobile.setUrl(obj.getString("url"));
                mobile.setBattery(obj.getString("battery"));
                return mobile;
            } catch (JSONException e1) {
            e1.printStackTrace();
            return null;
        }
    }

parseArrayFeed()JSONArray 作为参数,并返回一个 MobileArrayList

JSONParser.java

public static ArrayList<Mobile> parseArrayFeed(JSONArray arr) {
        JSONObject obj=null;
        Mobile mobile = null;
        mMobiles.clear();
        try {

            for(int i = 0;i<arr.length();i++) {
                obj = arr.getJSONObject(i);
                mobile= new Mobile();
                mobile.setName(obj.getString("name"));
                mobile.setCompanyName(obj.getString("companyName"));
                mobile.setOperatingSystem(obj.getString("operatingSystem"));
                mobile.setProcessor(obj.getString("processor"));
                mobile.setBackCamera(obj.getString("backCamera"));
                mobile.setFrontCamera(obj.getString("frontCamera"));
                mobile.setRam(obj.getString("ram"));
                mobile.setRom(obj.getString("rom"));
                mobile.setScreenSize(obj.getString("screenSize"));
                mobile.setUrl(obj.getString("url"));
                mobile.setBattery(obj.getString("battery"));
                mMobiles.add(mobile);
            }
            return mMobiles;
        } catch (JSONException e1) {
            e1.printStackTrace();
            return null;
        }
    }
}

打开 AndroidManifest.xml 并粘贴以下代码。请始终记住根据您的公司域更改包名。我们添加了 android.permission.INTERNET,因为我们将通过网络请求 JSON 数据。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.androidtutorialpoint.jsonparser" >
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".JSONParseActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".ParseJSONArray" >
        </activity>
        <activity android:name=".ParseJSONObject" >
        </activity>
        <activity android:name=".ParseJSONArrayObject" >
        </activity>
    </application>
</manifest>

我们创建了一个名为 JSONParseActivity 的活动,该活动包含两个按钮,用于决定是解码 JSONObject 还是 JSONArray,如图所示。

JSON Parsing Tutrial

将以下代码粘贴到 JSONParseActivity 中。

JSONParseActivity.java

package com.androidtutorialpoint.jsonparser;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class JSONParseActivity extends AppCompatActivity {

    private Button button_getJSONObject;
    private Button button_getJSONArray;
    private final String EXTRA_JSON_OBJECT_INDEX = "com.androidtutorialpoint.jsonparser";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_jsonparse);
        button_getJSONObject = (Button) findViewById(R.id.button_jsonobject);
        button_getJSONArray = (Button) findViewById(R.id.button_jsonarray);


        button_getJSONObject.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(getApplication(), ParseJSONObject.class);
                i.putExtra(EXTRA_JSON_OBJECT_INDEX, 0);
                startActivity(i);

            }
        });

        button_getJSONArray.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(getApplication(), ParseJSONArray.class);
                startActivity(i);
            }
        });
    }
}

在上面的活动中,我们为两个按钮定义了 setOnClickListener,并在点击它们时分别调用 ParseJSONObject.javaParseJSONArray.java。以下是 JSONParseActivity 的布局文件:

activity_jsonparse.xml

<?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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom=
    "@dimen/activity_vertical_margin" tools:context=".MainActivity"
    android:gravity="center">
    <Button
        android:id="@+id/button_jsonobject"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Parse JSONObject !!!"/>
    <Button
        android:id="@+id/button_jsonarray"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Parse JSONArray !!!"/>
</LinearLayout>

让我们先谈谈 ParseJSONObject.java。此活动显示从 MobileJSONObject URL 检索到的手机的详细信息,并显示手机的所有规格以及图像。创建一个 Java 类 ParseJSONObject.java 并粘贴以下代码。

ParseJSONObject.java

package com.androidtutorialpoint.jsonparser;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.TextView;

import com.android.volley.Request.Method;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONObject;

public class ParseJSONObject extends AppCompatActivity {

    private static final String TAG ="ParseJSONObject";
    private final String EXTRA_JSON_OBJECT_INDEX = "com.androidtutorialpoint.jsonparser";

    private Mobile mMobile;
    private TextView nameTextView;
    private TextView companyNameTextView;
    private TextView operatingSystemTextView;
    private TextView processorTextView;
    private TextView ramTextView;
    private TextView romTextView;
    private TextView frontCameraTextView;
    private TextView backCameraTextView;
    private TextView screenSizeTextView;
    private TextView batteryTextView;
    private ImageView photoImageView;
    private String photoUrl;

    String url = "http://androidtutorialpoint.com/api/MobileJSONObject.json";

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_parsejsonobject);

        nameTextView =(TextView)findViewById(R.id.edit_text_name);
        companyNameTextView =(TextView)findViewById(R.id.edit_text_company_name);
        operatingSystemTextView =(TextView)findViewById(R.id.edit_text_operating_system);
        processorTextView = (TextView)findViewById(R.id.edit_text_processor);
        ramTextView = (TextView)findViewById(R.id.edit_text_ram);
        romTextView = (TextView)findViewById(R.id.edit_text_rom);
        frontCameraTextView = (TextView)findViewById(R.id.edit_text_front_camera);
        backCameraTextView = (TextView)findViewById(R.id.edit_text_back_camera);
        screenSizeTextView = (TextView)findViewById(R.id.edit_text_screen_size);
        batteryTextView = (TextView)findViewById(R.id.edit_text_battery);
        photoImageView = (ImageView)findViewById(R.id.image_view_mobile_picture);



        final   ProgressDialog pDialog = new ProgressDialog(ParseJSONObject.this);
                pDialog.setMessage("Loading...");
                pDialog.show();

        JsonObjectRequest jsonObjReq = 
        new JsonObjectRequest(Method.GET,url, null,new Response.Listener<JSONObject>() {

                            @Override
                            public void onResponse(JSONObject response) {

                                mMobile = JSONParser.parseFeed(response);


                                nameTextView.setText
                                ("Name :" + mMobile.getName());
                                companyNameTextView.setText
                                ("Company :" + mMobile.getCompanyName());
                                operatingSystemTextView.setText
                                (" OS :" + mMobile.getOperatingSystem());
                                processorTextView.setText
                                ("Processor :" + mMobile.getProcessor());
                                ramTextView.setText
                                ("RAM :"+mMobile.getRam());
                                romTextView.setText
                                ("Memory :"+mMobile.getRom());
                                frontCameraTextView.setText
                                ("Front Camera :"+mMobile.getFrontCamera());
                                backCameraTextView.setText
                                ("Rear Camera :"+mMobile.getBackCamera());
                                screenSizeTextView.setText
                                ("Screen Size :"+mMobile.getScreenSize());
                                batteryTextView.setText
                                ("Battery :"+mMobile.getBattery());
                                photoUrl = (mMobile.getUrl());

                                ImageLoader imageLoader = 
                                new ImageLoader(Volley.newRequestQueue(getApplicationContext()),
                                        new LruBitmapCache());

                                // If you are using normal ImageView
                                imageLoader.get(photoUrl, new ImageLoader.ImageListener() {

                                    @Override
                                    public void onErrorResponse(VolleyError error) {
                                        Log.e(TAG, "Image Load Error: " + 
                                        error.getMessage());
                                    }

                                    @Override
                                    public void onResponse
                                    (ImageLoader.ImageContainer response, boolean arg1) {
                                        if (response.getBitmap() != null) {
                                            // load image into imageview
                                            photoImageView.setImageBitmap(response.getBitmap());
                                            pDialog.hide();

                                        }
                                    }
                                });

                                Log.d(TAG, response.toString());
                            }
                        }, new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        VolleyLog.d(TAG, "Error: " + error.getMessage());
                        // hide the progress dialog
                        pDialog.hide();
                    }
                });

                   // Adding request to request queue
           Volley.newRequestQueue(getApplicationContext()).add(jsonObjReq);
        }
    }

代码非常简单。

  1. 我们在 OnCreate() 方法中引用了布局元素。
  2. 然后,我们使用 **Volley 库**提交网络请求,以从 URL 获取 JSON 响应。
  3. 在收到网络请求的响应后,我们调用 JSON 解析器,然后为 TextViewImageView 小部件设置值。

上述活动的布局如下:

activity_parsejsonobject.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android" >
<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"
    android:scrollbars="vertical"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"  
    tools:context=".MainActivity"
    android:gravity="center">
    <ImageView
        android:id="@+id/image_view_mobile_picture"
        android:layout_width="200dp"
        android:layout_height="200dp" />
    <TextView
        android:id="@+id/edit_text_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Model :"
        android:layout_marginTop="16dp"
        android:layout_centerHorizontal="true"
        />
    <TextView
        android:id="@+id/edit_text_company_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Company :"
        android:layout_marginTop="16dp"
        android:layout_centerHorizontal="true"
        />
    <TextView
        android:id="@+id/edit_text_operating_system"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="OS :"
        android:layout_marginTop="16dp"
        android:layout_centerHorizontal="true"
        />
    <TextView
        android:id="@+id/edit_text_processor"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Processor :"
        android:layout_marginTop="16dp"
        android:layout_centerHorizontal="true"
        />
    <TextView
        android:id="@+id/edit_text_ram"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="RAM  :"
        android:layout_marginTop="16dp"
        android:layout_centerHorizontal="true"
        />
    <TextView
        android:id="@+id/edit_text_rom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Memory :"
        android:layout_marginTop="16dp"
        android:layout_centerHorizontal="true"
        />
    <TextView
        android:id="@+id/edit_text_front_camera"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Front Camera :"
        android:layout_marginTop="16dp"
        android:layout_centerHorizontal="true"
        />
    <TextView
        android:id="@+id/edit_text_back_camera"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Rear Camera :"
        android:layout_marginTop="16dp"
        android:layout_centerHorizontal="true"
        />
    <TextView
        android:id="@+id/edit_text_screen_size"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Screen Size :"
        android:layout_marginTop="16dp"
        android:layout_centerHorizontal="true"
        />
    <TextView
        android:id="@+id/edit_text_battery"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Battery :"
        android:layout_marginTop="16dp"
        android:layout_centerHorizontal="true"
        />
</LinearLayout>
</ScrollView>

布局也相当简单。我们有一个包含在 ScrollView 中的 LinearLayout,以便允许滚动。我们有一个 ImageView 和一些 TextView 作为 LinearLayout 的子元素来显示有关手机的信息。
接下来,创建一个 Java 类 ParseJSONArray 来托管一个 Fragment,该 Fragment 将列出 JSON 数组 URL 中的手机。将以下代码放入其中。

ParseJSONArray.java

package com.androidtutorialpoint.jsonparser;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
public class ParseJSONArray extends AppCompatActivity {
   
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_parsejsonarray);
        FragmentManager fm = getSupportFragmentManager();
        Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);
        if (fragment == null) {
            fragment = new ListMobiles();
            fm.beginTransaction()
                    .add(R.id.fragmentContainer, fragment)
                    .commit();
        }
    }
}

ParseJsonArray 活动创建一个布局资源文件。它只包含一个 FrameLayout,该 FrameLayout 将作为 Fragment 的容器。

activity_parsejsonarray.xml

 

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fragmentContainer"
    android:paddingBottom="50dp"
/>

创建一个 Java 类 ListMobiles,它将显示手机列表。

ListMobiles.java

package com.androidtutorialpoint.jsonparser;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import java.util.ArrayList;

public class ListMobiles extends ListFragment {

    private final String TAG = "ListMobiles";
    private ArrayList<Mobile>  mMobileList;
    String url = "http://androidtutorialpoint.com/api/MobileJSONArray.json";
    private final String EXTRA_JSON_OBJECT = "mobileObject";

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        final   ProgressDialog pDialog = new ProgressDialog(getActivity());
        pDialog.setMessage("Loading...");
        pDialog.show();

        JsonArrayRequest jsonArrayReq = new JsonArrayRequest(url,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {

                        Log.d(TAG,response.toString());
                        Log.d(TAG,"Len "+response.length());
                        mMobileList = JSONParser.parseArrayFeed(response);

                        pDialog.hide();
                        MobileAdapter adapter = new MobileAdapter(mMobileList);
                        setListAdapter(adapter);
                    }
                }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                VolleyLog.d(TAG, "Error: " + error.getMessage());
                // hide the progress dialog
                pDialog.hide();
            }
        });
        // Adding request to request queue
        Volley.newRequestQueue(getActivity()).add(jsonArrayReq);
    }

    private class MobileAdapter extends ArrayAdapter<Mobile> {
        public MobileAdapter(ArrayList<Mobile> mobiles) {
            super(getActivity(), 0, mobiles);
        }
        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
                // If we weren't given a view, inflate one

            Log.d(TAG,"pos "+position);
            if (convertView == null) {
                convertView = getActivity().getLayoutInflater()
                        .inflate(R.layout.category_list_item_1, null);
            }
               Mobile c = mMobileList.get(position);
            TextView nameTextView =
                        (TextView) convertView.findViewById(R.id.textview_name);
                nameTextView.setText(c.getName());

            nameTextView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    Intent i = new Intent(getActivity(),ParseJSONArrayObject.class);
                    Bundle args = new Bundle();
                    //args.putSerializable(EXTRA_JSON_MOBILE_OBJECT, mMobileList.get(position));
                    i.putExtra(EXTRA_JSON_OBJECT, mMobileList.get(position));
                    startActivity(i);
                }
            });
            return convertView;
        }
    }
}

在上面的代码中,我们创建了一个自定义的 ArrayAdapter 来列出手机。

  1. 首先,我们重写 getView() 方法,在该方法中,我们 inflater(解析)category_list_item_1.xml 文件,我们稍后将展示该文件。然后,我们从 mMobileList 中获取相应位置的 Mobile 项目,并返回 View
  2. 我们还创建了一个 OnClickListener,它将启动 ParseJSONArrayObject 类,并将您点击的手机传递给它。我们将在稍后讨论这个类。
  3. onCreate 方法中,我们通过 Volley 库执行网络请求以获取 JSONArray 请求。收到响应后,我们将其解析以获取 MobileList,然后将其设置到 MobileAdapter 上。

我们将 inflater 以下布局来显示条目。因此,请创建一个布局资源文件 category_list_item_1.xml。为避免复杂性,我们保留了此布局,并且仅在 LinearLayout 中使用了一个 TextView

category_list_item_1.xml

<?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"
    android:gravity="center">
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:padding="10dp"
        android:id="@+id/textview_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
    ></TextView>
</LinearLayout>

现在,让我们来谈谈 ParseJSONArrayObject 类,该类在点击 MobileList 中的项目时被调用。创建一个 Java 类 ParseJSONArrayObject 并粘贴以下代码。

ParseJSONArrayObject.java

package com.androidtutorialpoint.jsonparser;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
public class ParseJSONArrayObject extends AppCompatActivity{
    private static final String TAG ="ParseJSONObject";
    private Mobile mMobile;
    private TextView nameTextView;
    private TextView companyNameTextView;
    private TextView operatingSystemTextView;
    private TextView processorTextView;
    private TextView ramTextView;
    private TextView romTextView;
    private TextView frontCameraTextView;
    private TextView backCameraTextView;
    private TextView screenSizeTextView;
    private TextView batteryTextView;
    private ImageView photoImageView;
    private String photoUrl;
    private final String EXTRA_JSON_OBJECT = "mobileObject";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_parsejsonobject);
        mMobile = (Mobile)getIntent().getSerializableExtra(EXTRA_JSON_OBJECT);
        nameTextView =(TextView)findViewById(R.id.edit_text_name);
        companyNameTextView =(TextView)findViewById(R.id.edit_text_company_name);
        operatingSystemTextView =(TextView)findViewById(R.id.edit_text_operating_system);
        processorTextView = (TextView)findViewById(R.id.edit_text_processor);
        ramTextView = (TextView)findViewById(R.id.edit_text_ram);
        romTextView = (TextView)findViewById(R.id.edit_text_rom);
        frontCameraTextView = (TextView)findViewById(R.id.edit_text_front_camera);
        backCameraTextView = (TextView)findViewById(R.id.edit_text_back_camera);
        screenSizeTextView = (TextView)findViewById(R.id.edit_text_screen_size);
        batteryTextView = (TextView)findViewById(R.id.edit_text_battery);
        photoImageView = (ImageView)findViewById(R.id.image_view_mobile_picture);
        final ProgressDialog pDialog = new ProgressDialog(ParseJSONArrayObject.this);
        pDialog.setMessage("Loading...");
        pDialog.show();
                        nameTextView.setText
                        ("Name :" + mMobile.getName());
                        companyNameTextView.setText
                        ("Company :" + mMobile.getCompanyName());
                        operatingSystemTextView.setText
                        (" OS :" + mMobile.getOperatingSystem());
                        processorTextView.setText
                        ("Processor :" + mMobile.getProcessor());
                        ramTextView.setText("RAM :"+mMobile.getRam());
                        romTextView.setText
                        ("Memory :"+mMobile.getRom());
                        frontCameraTextView.setText
                        ("Front Camera :"+mMobile.getFrontCamera());
                        backCameraTextView.setText
                        ("Rear Camera :"+mMobile.getBackCamera());
                        screenSizeTextView.setText
                        ("Screen Size :"+mMobile.getScreenSize());
                        batteryTextView.setText
                        ("Battery :"+mMobile.getBattery());
                        photoUrl = (mMobile.getUrl());
                        ImageLoader imageLoader = 
                        new ImageLoader(Volley.newRequestQueue(getApplicationContext()),
                                new LruBitmapCache());
                        imageLoader.get(photoUrl, new ImageLoader.ImageListener() {
                            @Override
                            public void onErrorResponse(VolleyError error) {
                                Log.e(TAG, "Image Load Error: " + error.getMessage());
                            }
                            @Override
                            public void onResponse(ImageLoader.ImageContainer response, boolean arg1) {
                                if (response.getBitmap() != null) {
                                    // load image into imageview
                                    photoImageView.setImageBitmap(response.getBitmap());
                                    pDialog.hide();
                                }
                            }
                        });
    }
}

此活动与 ParseJSONObject 活动相似,但在这种情况下,我们是在 Bundle 中接收 Mobile 对象。
onCreate 方法中:

  1. 我们从 Intent 中提取 Mobile 对象。
  2. 从布局中引用 Layout 元素。
  3. 最后,我们设置 TextView 并创建一个网络请求来设置 ImageView

此外,请创建新的 Java 类 LruBitmapCache.java。此类用作 Volley 中 Image Loader 的缓存。

LruBitmapCache.java

package com.androidtutorialpoint.jsonparser;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

import com.android.volley.toolbox.ImageLoader.ImageCache;

public class LruBitmapCache extends LruCache<String, Bitmap> implements
        ImageCache {
    public static int getDefaultLruCacheSize() {
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;

        return cacheSize;
    }

    public LruBitmapCache() {
        this(getDefaultLruCacheSize());
    }

    public LruBitmapCache(int sizeInKiloBytes) {
        super(sizeInKiloBytes);
    }

    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight() / 1024;
    }

    @Override
    public Bitmap getBitmap(String url) {
        return get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        put(url, bitmap);
    }
}

现在,在 Android 设备或模拟器上运行该应用程序。请记住使用 Wifi 或移动数据打开互联网,因为我们没有添加任何逻辑来检查我们 Android 应用中的 Internet 连接。

大概就这些了。希望您现在对 Android 中的 JSON 解析有了完整的了解。如果您有任何疑问或建议,请评论。

© . All rights reserved.