android - adapter.notifyDataSetChanged 只有创建 View 层次结构的原始线程可以触及它的 View

标签 android android-volley adapter

我正在使用 volley 来发布并从服务器获取响应。我发布一些数据并获取一些其他数据并在 listview 中获取它们。我的问题是当我运行应用程序时它提示此错误,指向 adapter.notifyDataSetChanged();

E/Volley: [1945] NetworkDispatcher.processRequest: Unhandled exception android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
      android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
          at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7802)
          at android.view.ViewRootImpl.focusableViewAvailable(ViewRootImpl.java:3622)
          at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:760)
          at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:760)
          at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:760)
          at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:760)
          at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:760)
          at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:760)
          at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:760)
          at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:760)
          at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:760)
          at android.view.View.setFlags(View.java:12529)
          at android.view.View.setFocusableInTouchMode(View.java:8688)
          at android.widget.AdapterView.checkFocus(AdapterView.java:1122)
          at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:1217)
          at android.widget.AbsListView$AdapterDataSetObserver.onChanged(AbsListView.java:9487)
          at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
          at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50)
          at com.example.junaida.project1.fragments.CardFragment$3.parseNetworkResponse(CardFragment.java:179)
          at com.android.volley.NetworkDispatcher.processRequest(NetworkDispatcher.java:132)
          at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:87)
E/VOLLEY: com.android.volley.VolleyError: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

这是我的代码

 try {
        RequestQueue requestQueue = Volley.newRequestQueue(getContext());
        String URL = "http://192.168.0.105/WebApplication7/api/subjects";
        JSONObject jsonBody = new JSONObject();
        // jsonBody.put("tblRegisteredUsers_nickName", username.getText().toString().trim());
        jsonBody.put("id", "2016");
        jsonBody.put("Type", "1");
        jsonBody.put("Year","1");


        final String requestBody = jsonBody.toString();

        StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {

                if (response.equals("success")) {
                    //login authenticated. Start the next activity of your app
                    Toast.makeText(getActivity(), response.toString(), Toast.LENGTH_LONG).show();
                    // Toast.makeText(getApplicationContext(), "registered successfully ", Toast.LENGTH_SHORT).show();
                    Intent intent = new Intent(getActivity(), MainActivity.class);
  //                        intent.putExtra("id", Id);
  //                        intent.putExtra("year", year);
                    startActivity(intent);
                } else {
                    //login failed. prompt to re-enter the credentials
                    Toast.makeText( mActivity.getApplicationContext(), "Failed to log In", Toast.LENGTH_SHORT).show();

                    Log.i("VOLLEY", response);
                    Toast.makeText (mActivity.getApplicationContext(), response.toString(), Toast.LENGTH_LONG).show();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("VOLLEY", error.toString());
            }
        })

        {
            @Override
            public String getBodyContentType() {
                return "application/json; charset=utf-8";
            }

            @Override
            public byte[] getBody() throws AuthFailureError {
                try {
                    return requestBody == null ? null : requestBody.getBytes("utf-8");
                } catch (UnsupportedEncodingException uee) {
                    VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
                    return null;
                }
            }

            @Override
            protected Response<String> parseNetworkResponse(NetworkResponse response) {
                String responseString;
                String json = null;

                try {
                    json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                responseString = String.valueOf(json).trim();
                ArrayList<Response4> list_response = new ArrayList<Response4>();
                Type listType = new TypeToken<List<Response4>>() {}.getType();
                list_response = new Gson().fromJson(responseString, listType);
                //String check = list.get(0).getMessagesName();

                for (int i = 0;i<list_response.size();i++) {

 //                        JSONObject obj = response.getJSONObject(i);
                    ListItemsData listItemData = new ListItemsData();
                    listItemData.setItem(list_response.get(i).getMessagesName());
                    listItemData.setUrl(list_response.get(i).getMessageURLNew());

                    //listItemData.setUrl((obj.getString("url")));
                    list.add(listItemData);


                    //Id = list.get(0).getId();
                    // year = list.get(0).getYear();
                    //Response2 yourModel = new Gson().fromJson(responseString, Response2.class);
                }

                adapter.notifyDataSetChanged();
                //  String Check =  yourModel.getMessagetitle();
                return Response.success(list_response.toString(), HttpHeaderParser.parseCacheHeaders(response));
            }
        };

        requestQueue.add(stringRequest);
    } catch (JSONException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
  return rootView;
    }

当我运行代码时,它会打印出上述错误,指向 adapter.notifyDataSetChanged(); 那么 adpater 与此有​​什么关系?

最佳答案

我刚刚通过这样做解决了这个问题

 getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        adapter.notifyDataSetChanged();
                    }
                });

关于android - adapter.notifyDataSetChanged 只有创建 View 层次结构的原始线程可以触及它的 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47844633/

相关文章:

Android - 如何在 Child 中获取 JSON 数组

java - 如何将 json 从 android 发送到 php?

android - GridView 行删除和动画 - Android

Android Sync Adapter - 手动同步

android - react-native:固定标题的阴影低于 ScrollView

android - 安装已签名的 APK 不会在 Android Wear 上安装应用

android - flutter run无法确定任务 ':app:compileDebugJavaWithJavac'的依赖项

android - 如何使用如下所示的 body 发出 android Volley 请求

java - 更简单地使用 TypeAdapterFactory

更改目标 sdk 时 Android 项目不运行