Android JSON 解析教程






4.85/5 (4投票s)
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 响应可以包含以下元素:
- JSON 数组 ([):在 JSON 文件中,方括号 ([) 代表一个 JSON 数组。
- JSON 对象 ({):在 JSON 文件中,花括号 ({) 代表一个 JSON 对象。
- 键 (Key):JSON 对象包含一个键,它只是一个字符串。键/值对构成了 JSON 对象。
- 值 (Value):每个键都有一个值,它可以是字符串、整数或双精度数等。
Android 提供了以下类来处理 JSON 响应:
JSONObject、JSONArray、JSONStringer 和 JSONTokener。在本教程中,我们将重点介绍 org.json.JSONObject 和 org.json.JSONArray。
要解析 JSON 响应,首先需要确定 JSON 响应中你感兴趣的字段。例如,在上面链接中的 JSON 中,我们将使用所有字段。我们需要相应地编写我们的解析函数。
让我们一步一步来创建一个示例 JSON 解析应用程序。我们将演示如何解析 JSON 对象和 JSON 数组。在这个应用程序中,我们将从给定 URL 的 JSON 字符串中检索手机的详细信息,然后将它们显示为列表,点击每个手机后,将显示该手机的详细信息。
先决条件
- 您的 PC(Unix 或 Windows)上安装了 Android Studio。
- 一台配置了 Android Studio 的真实 Android 设备(智能手机或平板电脑)。
创建新项目
- 打开 Android Studio 并创建一个名为“JSONParser”的新项目,公司域为application.example.com(我们使用了我们的公司域androidtutorialpoint.com。您也可以使用您自己的)。
- 点击“下一步”并选择最小 SDK,我们保留了默认值。再次点击“下一步”并选择空白活动 (Blank Activity)。
- 将活动命名为 JSONParseActivity,然后点击“下一步”。
- 将其他所有内容保留为默认值,然后点击“完成”。
将创建一个新项目,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() 来分别解析 JSONObject 和 JSONArray。在解析 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 作为参数,并返回一个 Mobile 的 ArrayList。
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,如图所示。
将以下代码粘贴到 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.java 和 ParseJSONArray.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);
        }
    }
代码非常简单。
- 我们在 OnCreate()方法中引用了布局元素。
- 然后,我们使用 **Volley 库**提交网络请求,以从 URL 获取 JSON 响应。
- 在收到网络请求的响应后,我们调用 JSON 解析器,然后为 TextView和ImageView小部件设置值。
上述活动的布局如下:
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 来列出手机。
- 首先,我们重写 getView()方法,在该方法中,我们 inflater(解析)category_list_item_1.xml 文件,我们稍后将展示该文件。然后,我们从mMobileList中获取相应位置的Mobile项目,并返回View。
- 我们还创建了一个 OnClickListener,它将启动ParseJSONArrayObject类,并将您点击的手机传递给它。我们将在稍后讨论这个类。
- 在 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 方法中:
- 我们从 Intent 中提取 Mobile对象。
- 从布局中引用 Layout元素。
- 最后,我们设置 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 解析有了完整的了解。如果您有任何疑问或建议,请评论。


