【问题标题】:how to parse json that has a child and child如何解析有孩子和孩子的json
【发布时间】:2018-05-28 08:08:17
【问题描述】:

在这个应用程序中,我计划将 json 解析为片段,当“is_broken”为真时,它只会在第一个片段上显示,而“is_repaired”为真时,它只会在第二个片段和“is_ok”上显示.在这个 json 中有一个数据有一个孩子,它将在同一个列表中被调用,但 json 的键也有相同的键,即“名称”

我正在尝试解析这个 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
          }
        }
      ]
    }

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

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 解析到列表中

【问题讨论】:

  • 您的 json 无效 数组的第二个节点在没有 } jsonobject 右大括号的情况下关闭。
  • 对不起,现在很好@SohailZahid
  • 你错过了"is_ok": true之后第8行的,,它应该像"is_ok": true,
  • 完成 :),我只是稍微进化一下,呵呵
  • 现在可以试一试了

标签: android json android-studio


【解决方案1】:

您在第 1 行收到 NullPointerException

str_json = json.getJSONArray("data");

调试并检查为什么你得到 json 为 null ,在解析之前保持一个 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(不推荐)

【讨论】:

  • 为什么String不能转成jsonObject?
  • 可以转换
【解决方案2】:

请不要再以这种方式解析 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/

【讨论】:

  • 这在很大程度上取决于用例和 JSON 的来源,什么是解析 JSON 的最佳方式。 Gson 是一种可能性,但通常不是必需的,甚至不是最佳选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-27
  • 1970-01-01
  • 1970-01-01
  • 2020-07-29
  • 1970-01-01
  • 2019-06-27
相关资源
最近更新 更多