JSON解析 - 第三级ListView的NullPointerException

时间:2014-06-21 10:21:23

标签: android json

我正在将JSON解析为ArrayList,但每次都获得NPE,

at com.example.parsingjson.HotelAdapter.getCount(HotelAdapter.java:26)

    return arrayList.size();

我的JSON看起来像这样:

{
    "search": [
        {
            "country": "India",
            "location": [
                {
                    "title": "New Delhi",
                    "hotel": [
                        {
                            "name": "Hotel 5 Star"
                        },
                        {
                            "name": "Hotel Premium"
                        }
                    ]
                },
                {
                    "title": "Bangalore",
                    "hotel": [
                        {
                            "name": "Hotel Comfort"
                        }
                    ]
                }
            ]
        },
        {
            "country": "USA",
            "location": [
                {
                    "title": "California",
                    "hotel": [
                        {
                            "name": "Hotel Zone"
                        }
                    ]
                }
            ]
        }
    ]
}

实际上我成功解析了JSON的前2级但是在尝试解析第三级JSON时获得 NullPointerException

日志说:

06-21 16:28:52.310: D/AbsListView(9439): Get MotionRecognitionManager
06-21 16:28:52.460: D/libEGL(9439): loaded /system/lib/egl/libEGL_mali.so
06-21 16:28:52.490: D/libEGL(9439): loaded /system/lib/egl/libGLESv1_CM_mali.so
06-21 16:28:52.495: D/libEGL(9439): loaded /system/lib/egl/libGLESv2_mali.so
06-21 16:28:52.495: D/(9439): Device driver API match
06-21 16:28:52.495: D/(9439): Device driver API version: 10
06-21 16:28:52.495: D/(9439): User space API version: 10 
06-21 16:28:52.495: D/(9439): mali: REVISION=Linux-r2p4-02rel0 BUILD_DATE=Tue Sep 25 15:06:14 KST 2012 
06-21 16:28:52.515: D/OpenGLRenderer(9439): Enabling debug mode 0
06-21 16:28:53.405: D/dalvikvm(9439): GC_CONCURRENT freed 190K, 10% free 12379K/13703K, paused 2ms+26ms, total 45ms
06-21 16:28:55.540: D/GestureDetector(9439): [Surface Touch Event] mSweepDown False, mLRSDCnt : -1 mTouchCnt : 3 mFalseSizeCnt:0
06-21 16:28:55.630: D/batchname::(9439): USA
06-21 16:28:55.735: D/AbsListView(9439): Get MotionRecognitionManager
06-21 16:28:55.740: D/Location-fetchedname::(9439): USA
06-21 16:28:55.745: D/Location-checkdata:(9439): [com.example.parsingjson.Location@42780ab8]
06-21 16:28:55.865: E/SpannableStringBuilder(9439): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
06-21 16:28:55.865: E/SpannableStringBuilder(9439): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
06-21 16:28:57.470: D/GestureDetector(9439): [Surface Touch Event] mSweepDown False, mLRSDCnt : -1 mTouchCnt : 3 mFalseSizeCnt:0
06-21 16:28:57.570: D/dalvikvm(9439): GC_CONCURRENT freed 265K, 11% free 12543K/13959K, paused 5ms+4ms, total 30ms
06-21 16:28:57.805: D/AbsListView(9439): Get MotionRecognitionManager
06-21 16:28:57.805: D/Hotel-fetchedname::(9439): California
06-21 16:28:57.810: D/Hotel-checkdata:(9439): null
06-21 16:28:57.820: D/AndroidRuntime(9439): Shutting down VM
06-21 16:28:57.820: W/dalvikvm(9439): threadid=1: thread exiting with uncaught exception (group=0x41a052a0)
06-21 16:28:57.835: E/AndroidRuntime(9439): FATAL EXCEPTION: main
06-21 16:28:57.835: E/AndroidRuntime(9439): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.parsingjson/com.example.parsingjson.HotelActivity}: java.lang.NullPointerException
06-21 16:28:57.835: E/AndroidRuntime(9439):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2110)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2135)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at android.app.ActivityThread.access$700(ActivityThread.java:140)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1237)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at android.os.Looper.loop(Looper.java:137)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at android.app.ActivityThread.main(ActivityThread.java:4921)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at java.lang.reflect.Method.invokeNative(Native Method)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at java.lang.reflect.Method.invoke(Method.java:511)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1036)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:803)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at dalvik.system.NativeStart.main(Native Method)
06-21 16:28:57.835: E/AndroidRuntime(9439): Caused by: java.lang.NullPointerException
06-21 16:28:57.835: E/AndroidRuntime(9439):     at com.example.parsingjson.HotelAdapter.getCount(HotelAdapter.java:26)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at android.widget.ListView.setAdapter(ListView.java:466)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at com.example.parsingjson.HotelActivity.onCreate(HotelActivity.java:42)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at android.app.Activity.performCreate(Activity.java:5191)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
06-21 16:28:57.835: E/AndroidRuntime(9439):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2074)
06-21 16:28:57.835: E/AndroidRuntime(9439):     ... 11 more
06-21 16:29:07.220: I/Process(9439): Sending signal. PID: 9439 SIG: 9

第一级: CountryActivity.java

@Override
        protected Void doInBackground(Void... params) {
            // url
            jsonobjectMaps = JSONfunctions.getJSONfromURL("URL");
            try {

                arraylistSearch = new ArrayList<Search>();
                JSONArray jsonArrayBatches = jsonobjectMaps.getJSONArray("search");             
                for (int i = 0; i < jsonArrayBatches.length(); i++) {                   
                    jsonobjectMaps = jsonArrayBatches.getJSONObject(i);
                    Search batches = new Search();
                    batches.setCountry(jsonobjectMaps.getString("country"));

                    arraylistStudent = new ArrayList<Location>();
                    JSONArray jsonArrayStudents = jsonobjectMaps.getJSONArray("location");
                    for (int j = 0; j < jsonArrayStudents.length(); j++) {
                        jsonobjectMaps = jsonArrayStudents.getJSONObject(j);
                        Location students = new Location();
                        students.setTitle(jsonobjectMaps.getString("title"));
                        arraylistStudent.add(students);

                        arraylistHotel = new ArrayList<Hotel>();
                        JSONArray jsonArrayHotel = jsonobjectMaps.getJSONArray("hotel");
                        for (int k = 0; k < jsonArrayHotel.length(); k++) {
                            jsonobjectMaps = jsonArrayHotel.getJSONObject(k);
                            Hotel hotel = new Hotel();
                            hotel.setName(jsonobjectMaps.getString("name"));
                            arraylistHotel.add(hotel);
                        }
                    }       

                    arraylistSearch.add(batches);
                    batches.setLocation(arraylistStudent);
                }
            } catch (JSONException e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void args) {
            // Locate the listview in listview_main.xml
            listview = (ListView) findViewById(R.id.listview);
            // Pass the results into ListViewAdapter.java
            adapter = new CountryAdapter(CountryActivity.this, arraylistSearch);
            // Set the adapter to the ListView
            listview.setAdapter(adapter);
            // Close the progressdialog
            mProgressDialog.dismiss();

        }
    }

3 个答案:

答案 0 :(得分:2)

以下是代码段,您至少要了解第三级JSON解析的工作原理..

jsonobjectMaps = JSONfunctions.getJSONfromURL("https://dl.dropboxusercontent.com/s/om6509fnyio3165/hotel.json");
            try {
                JSONArray jsonArraySeaches = jsonobjectMaps.getJSONArray("search");
                arraylist = new ArrayList<Search>();
                for (int i = 0; i < jsonArraySeaches.length(); i++) {
                    Search search = new Search();
                    JSONObject jsonObjectSearch = jsonArraySeaches.getJSONObject(i);
                    search.setCountry(jsonObjectSearch.getString("country"));

                    arraylistLocation = new ArrayList<Location>();
                    JSONArray jsonArrayLocation = jsonObjectSearch.getJSONArray("location");

                    for (int j = 0; j < jsonArrayLocation.length(); j++) {
                        JSONObject jsonobjectLocation = jsonArrayLocation.getJSONObject(j);
                        Location location = new Location();
                        location.setTitle(jsonobjectLocation.getString("title"));

                        arraylistHotel= new ArrayList<Hotel>();
                        JSONArray jsonArrayHotel= jsonobjectLocation.getJSONArray("hotel");

                        for (int k = 0; k < jsonArrayHotel.length(); k++) {
                            JSONObject jsonobjectHotel = jsonArrayHotel.getJSONObject(k);
                            Hotel hotel = new Hotel();
                            hotel.setName(jsonobjectHotel.getString("name"));
                            arraylistHotel.add(hotel);
                        }
                        location.setHotels(arraylistHotel);
                        arraylistLocation.add(location);
                    }
                    search.setLocations(arraylistLocation);
                    arraylist.add(search);
                }
            } catch (JSONException e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }

答案 1 :(得分:2)

这是下载JSON数据并将其绑定到listview代码。您可以在此处找到它。

private class DownloadJSON extends AsyncTask<Void, Void, Void> {

        private ArrayList<Location> arraylistLocation;
        private ArrayList<Hotel> arraylistHotel;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mProgressDialog = new ProgressDialog(MainActivity.this);
            mProgressDialog.setMessage("Loading...");
            mProgressDialog.setIndeterminate(false);
            mProgressDialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            jsonobjectMaps = JSONfunctions.getJSONfromURL("https://dl.dropboxusercontent.com/s/om6509fnyio3165/hotel.json");
            try {
                JSONArray jsonArraySeaches = jsonobjectMaps.getJSONArray("search");
                arraylist = new ArrayList<Search>();
                for (int i = 0; i < jsonArraySeaches.length(); i++) {
                    Search search = new Search();
                    JSONObject jsonObjectSearch = jsonArraySeaches.getJSONObject(i);
                    search.setCountry(jsonObjectSearch.getString("country"));

                    arraylistLocation = new ArrayList<Location>();
                    JSONArray jsonArrayLocation = jsonObjectSearch.getJSONArray("location");

                    for (int j = 0; j < jsonArrayLocation.length(); j++) {
                        JSONObject jsonobjectLocation = jsonArrayLocation.getJSONObject(j);
                        Location location = new Location();
                        location.setTitle(jsonobjectLocation.getString("title"));

                        arraylistHotel= new ArrayList<Hotel>();
                        JSONArray jsonArrayHotel= jsonobjectLocation.getJSONArray("hotel");

                        for (int k = 0; k < jsonArrayHotel.length(); k++) {
                            JSONObject jsonobjectHotel = jsonArrayHotel.getJSONObject(k);
                            Hotel hotel = new Hotel();
                            hotel.setName(jsonobjectHotel.getString("name"));
                            arraylistHotel.add(hotel);
                        }
                        location.setHotels(arraylistHotel);
                        arraylistLocation.add(location);
                    }
                    search.setLocations(arraylistLocation);
                    arraylist.add(search);
                }
            } catch (JSONException e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void args) {
            // Locate the listview in listview_main.xml
            listview = (ListView) findViewById(R.id.listview);
            // Pass the results into ListViewAdapter.java
            adapter = new ListViewAdapter(MainActivity.this, arraylist);
            // Set the adapter to the ListView
            listview.setAdapter(adapter);
            // Close the progressdialog
            mProgressDialog.dismiss();

            listview.setOnItemClickListener(new OnItemClickListener() {

                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    // TODO Auto-generated method stub
                    Bundle bundle = new Bundle();
                    bundle.putSerializable("data", arraylist);
                    bundle.putInt("index", position);
                    Intent sendtosecond = new Intent(MainActivity.this, SecondListActivity.class);
                    sendtosecond.putExtra("bundle", bundle);
                    startActivity(sendtosecond);
                }
            });
        }
    }

答案 2 :(得分:0)

你在两个地方遇到同样的问题。 ArrayList对象不能直接分配。您需要clone()或使用复制构造函数

错误在HotelAdapter.java

this.arrayList = arrayList;

你应该做

this.arrayList = arrayList.clone();
arrayList.clear(); //clean up

并在Location.java

中执行此操作
public void setHotel(ArrayList<Hotel> hotel) {
    this.hotel = hotel.clone();
    hotel.clean();
}

或者您可以使用

this.hotel = new ArrayList<Hotel>(hotel);

您的问题是由于this.