如何解析有孩子和孩子的json

时间:2018-05-28 08:08:18

标签: android json android-studio

在这个应用程序中,我计划将json解析为碎片,当'is_broken'为真时,它只显示在第一个片段上,'is_repaired'为真,它只会显示在第二个片段上,也会显示'is_ok' 。在这个json中有一个有子的数据,它将在同一个列表中调用,但json的键也有相同的键,即'name'

我正在尝试解析这个json

     {
      "data": [
    {

            "name": "Table",
            "is_broken": false,
            "is_repaired": false,
            "is_ok": true,
           "asset_parent": {
             "name": "2nd Floor",
             "is_broken": false,
             "is_repaired": false,
             "is_ok": true,
             "asset_parent": {
               "name": "Grubi Building",
               "is_broken": false,
               "is_repaired": false,
               "is_ok": true
          }
          }
    },
{
          "name": "4th Floor",
          "is_broken": true,
          "is_repaired": false,
          "is_ok": false,
          "asset_parent": {
            "name": "Buni Building",
            "is_broken": true,
            "is_repaired": false,
            "is_ok": false
          }
        }
      ]
    }

我正在尝试解析数据,但只是将其放入listview中的父级名称。这个数据上有一个孩子,我试图在这个片段代码上把它称为它的父元素

public static String in_aset = "aset";
    public static String in_gedung = "rektorat";
    public static String in_ruang = "000";
    ProgressDialog pDialog;
    JSONArray str_json = null;
    ListView list, list2;
    AssetsAdapter adapter;
    ArrayList<HashMap<String, String>> data_map = new ArrayList<HashMap<String, String>>();
    @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_baik, container, false);

            new daftarAset().execute();

            return view;
        }

        class daftarAset extends AsyncTask<String, String, String> {
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                pDialog = new ProgressDialog(getActivity());
                pDialog.setMessage("Loading...");
                pDialog.setIndeterminate(false);
                pDialog.setCancelable(true);
                pDialog.show();
            }

            @Override
            protected String doInBackground(String... params) {
                String link_url = "https://example.com/api/assets";
                JSONParser jParser = new JSONParser();
                JSONObject json = jParser.AmbilJson(link_url);
                try {
                    str_json = json.getJSONArray("data");
                    for (int i = 0; i < str_json.length(); i++) {
                        JSONObject ar = str_json.getJSONObject(i);
                        String aset = ar.getString("name").trim();
                        HashMap map = new HashMap();
                        map.put(in_aset, aset);
                        data_map.add(map);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        list = (ListView) getView().findViewById(R.id.baik_list);
                        adapter = new AssetsAdapter(getActivity(), data_map);
                        list.setAdapter(adapter);
                        setListViewHeightBasedOnChildren(list);
                    }
                });
                return null;
            }

            @Override
            protected void onPostExecute(String s) {
                pDialog.dismiss();
            }

        }

        public static void setListViewHeightBasedOnChildren(ListView listView) {
            ListAdapter listAdapter = listView.getAdapter();
            if (listAdapter == null) return;
            int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.UNSPECIFIED);
            int totalHeight = 0;
            View view = null;
            for (int i = 0; i < listAdapter.getCount(); i++) {
                view = listAdapter.getView(i, view, listView);
                if (i == 0)
                    view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, ViewGroup.LayoutParams.WRAP_CONTENT));
                view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
                totalHeight += view.getMeasuredHeight();
            }
            ViewGroup.LayoutParams params = listView.getLayoutParams();
            params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
            listView.setLayoutParams(params);
            listView.requestLayout();
        }

and this is the adapter of code above

    public class AssetsAdapter extends BaseAdapter {
    private Activity activity;
    private ArrayList<HashMap<String, String>> data;
    private static LayoutInflater inflater = null;

    public AssetsAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
        activity = a;
        data =  d;
        inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View vi = convertView;
        if (convertView == null) vi = inflater.inflate(R.layout.list_chart, null);
        TextView textCucu = (TextView) vi.findViewById(R.id.aset1);
        TextView textAnak = (TextView) vi.findViewById(R.id.lokasi);
        TextView textBapak = (TextView) vi.findViewById(R.id.waktu);
        HashMap<String, String> getdata = new HashMap<String, String>();
        getdata = data.get(position);
        textCucu.setText(getdata.get(BaikFragment.in_aset));
        textAnak.setText(getdata.get(BaikFragment.in_ruang));
        return vi;
    }
}

TextView textCucu,textAnak,textBapak与listview相反,带有键'name'的json必须使用具有子节点的json的相同listview输入。 但当我尝试上面的代码时,我得到了这个错误消息

    E/JSON Parser: Error parsing data org.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot be converted to JSONObject
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
                  Process: com.mqa.android.monas, PID: 30517
                  java.lang.RuntimeException: An error occured while executing doInBackground()
                      at android.os.AsyncTask$3.done(AsyncTask.java:304)
                      at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
                      at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
                      at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                      at java.lang.Thread.run(Thread.java:818)
                   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'org.json.JSONArray org.json.JSONObject.getJSONArray(java.lang.String)' on a null object reference
                      at com.mqa.android.monas.Fragment.BaikFragment$daftarAset.doInBackground(BaikFragment.java:174)
                      at com.mqa.android.monas.Fragment.BaikFragment$daftarAset.doInBackground(BaikFragment.java:157)
                      at android.os.AsyncTask$2.call(AsyncTask.java:292)
                      at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
                      at java.lang.Thread.run(Thread.java:818) 
D/EGL_emulation: eglMakeCurrent: 0xb438b280: ver 2 0
D/EGL_emulation: eglMakeCurrent: 0xb438b280: ver 2 0
D/EGL_emulation: eglMakeCurrent: 0xb438b280: ver 2 0
D/EGL_emulation: eglMakeCurrent: 0xb438b280: ver 2 0
D/EGL_emulation: eglMakeCurrent: 0xb438b280: ver 2 0
D/EGL_emulation: eglMakeCurrent: 0xb438b280: ver 2 0
D/EGL_emulation: eglMakeCurrent: 0xb438b280: ver 2 0
E/WindowManager: android.view.WindowLeaked: Activity com.mqa.android.monas.Activity.AsetActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{dccaffa V.E..... R......D 0,0-1026,304} that was originally added here
                     at android.view.ViewRootImpl.<init>(ViewRootImpl.java:363)
                     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:271)
                     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
                     at android.app.Dialog.show(Dialog.java:298)
                     at com.mqa.android.monas.Fragment.BaikFragment$daftarAset.onPreExecute(BaikFragment.java:165)
                     at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:591)
                     at android.os.AsyncTask.execute(AsyncTask.java:539)
                     at com.mqa.android.monas.Fragment.BaikFragment.onCreateView(BaikFragment.java:96)
                     at android.support.v4.app.Fragment.performCreateView(Fragment.java:2354)
                     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1419)
                     at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740)
                     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1809)
                     at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:799)
                     at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580)
                     at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367)
                     at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
                     at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2199)
                     at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:651)
                     at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:145)
                     at android.support.v4.view.ViewPager.populate(ViewPager.java:1236)
                     at android.support.v4.view.ViewPager.populate(ViewPager.java:1084)
                     at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1614)
                     at android.view.View.measure(View.java:17547)
                     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                     at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:714)
                     at android.support.design.widget.HeaderScrollingViewBehavior.onMeasureChild(HeaderScrollingViewBehavior.java:91)
                     at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onMeasureChild(AppBarLayout.java:1361)
                     at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:784)
                     at android.view.View.measure(View.java:17547)
                     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                     at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
                     at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
                     at android.view.View.measure(View.java:17547)
                     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
                     at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
                     at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
                     at android.view.View.measure(View.java:17547)
                     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                     at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
                     at android.view.View.measure(View.java:17547)
                     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
                     at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
                     at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
                     at android.view.View.measure(View.java:17547)
                     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
                     at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
                     at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2615)
                     at android.view.View.measure(View.java:17547)
                     at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2015)


at android.view.ViewRootImpl.measureHierarchy(View

请帮忙。我如何使用相同的json键解析具有相同列表视图中的子项的json数据。或者我应该编写什么代码来解析json到列表中

2 个答案:

答案 0 :(得分:1)

您正在NullPointerException

str_json = json.getJSONArray("data");

调试并检查为什么将json作为null,在解析之前保持空检查

 try {
          if(json!=null){
                str_json = json.getJSONArray("data");
                for (int i = 0; i < str_json.length(); i++) {
                    JSONObject ar = str_json.getJSONObject(i);
                    String aset = ar.getString("name").trim();
                    HashMap map = new HashMap();
                    map.put(in_aset, aset);
                    data_map.add(map);
                }
             }
            } catch (JSONException e) {
                e.printStackTrace();
            }

或抓住Exception代替JSONException(不推荐)

答案 1 :(得分:-1)

请不要再以这种方式解析json。

Google已经部署了一个令人难以置信的库来以一种强大而简单的方式解析json。 只是:

Gson gson = new GsonBuilder()
gson.fromJson(jsonString)

有关如何设置此库的更多信息,请参阅教程的链接:http://borntocode.fr/android-mettre-en-place-et-utiliser-gson-pour-faciliter-lutilisation-du-json/