【问题标题】:JSON Parsing - NullPointerException at third Level ListViewJSON 解析 - 第三级 ListView 的 NullPointerException
【发布时间】:2014-08-12 00:01:48
【问题描述】:

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

在 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();

        }
    }

【问题讨论】:

  • 显示您的 HotelAdapter() 类。
  • 错误出现在您的 HotelAdapter 类中。
  • 已放置 HotelAdapter 类代码,立即查看
  • 检查你是否从包中获取数据。 batches.getHotel() 是否包含数据。
  • HotelActivity.java 中的batches 是什么?

标签: android json


【解决方案1】:

这是您至少要了解第三级 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();
            }

【讨论】:

    【解决方案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);
                    }
                });
            }
        }
    

    【讨论】:

      【解决方案3】:

      您在两个地方遇到了同样的问题。不能直接分配 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.

      【讨论】:

      • 好吧..这是一个问题..另一个是当您检索捆绑包时。
      • 查看我上面的评论
      • 这没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。
      • @Duraiamuthan 那是 OPs 问题的解决方案,她只需要在另一个有相同问题的地方实施它即可 :)
      • @Sonali 的答案有帮助吗?
      猜你喜欢
      • 1970-01-01
      • 2012-11-06
      • 2014-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多