返回错误:android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触及其视图

时间:2015-02-24 16:04:23

标签: android user-interface listview error-handling crash

嗨我正在查看详细信息然后当我点击右下方按钮,返回列表视图时,我有错误" android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创建视图的原始线程层次结构可以触及它的观点。" 但我不知道如何解决这个问题:

public class Record extends ListActivity {
    // Progress Dialog
    private ProgressDialog pDialog;

    // JSON parser class
    JSONParser jsonParser = new JSONParser();

    //testing on Emulator:
    private static final String READ_SPECIFIC_RECORD_URL = "http://192.168.1.178:8888/searchdb/record.php";

    //JSON IDS:
    private static final String TAG_TITLE = "title";
    private static final String TAG_POSTS = "posts";
    private static final String TAG_ADDRESS = "address";
    private static final String TAG_OPHOURS = "ophours";
    private static final String TAG_CONTACT = "contact";
    private static final String TAG_CONTACT2 = "contact2";
    private static final String TAG_CAT = "cat";
    private static final String TAG_BRAND = "brand";
    private static final String TAG_COMPANY = "company";
    private static final String TAG_RATINGS = "avgrating";


    //An array of all of our comments
    private JSONArray mComments = null;
    //manages all of our comments in a list.
    private ArrayList<HashMap<String, String>> mCommentList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        //note that use read_comments.xml instead of our single_post.xml
        setContentView(R.layout.details);

    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        //loading the comments via AsyncTask
        new LoadRecordDetails().execute();
    }

    /**
     * Retrieves json data of comments
     */
    /**
     * Retrieves recent post data from the server.
     */
    public void updateJSONdata() {

        // Instantiate the arraylist to contain all the JSON data.
        // we are going to use a bunch of key-value pairs, referring
        // to the json element name, and the content, for example,
        // message it the tag, and "I'm awesome" as the content..

        Bundle b = getIntent().getExtras();
        String id = b.getString("key");

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("id", id));

        Log.d("request!", "starting");

        //Posting user data to script
        JSONObject json = jsonParser.makeHttpRequest(
                READ_SPECIFIC_RECORD_URL, "POST", params);

        // full json response
        Log.d("Search attempt", json.toString());


        mCommentList = new ArrayList<HashMap<String, String>>();

        //when parsing JSON stuff, we should probably
        //try to catch any exceptions:
        try {

            mComments = json.getJSONArray(TAG_POSTS);

            // looping through all posts according to the json object returned
            for (int i = 0; i < mComments.length(); i++) {
                JSONObject c = mComments.getJSONObject(i);

                //gets the content of each tag
                String title = c.getString(TAG_TITLE);
                String address = c.getString(TAG_ADDRESS);
                String ophours = c.getString(TAG_OPHOURS);
                String contact = c.getString(TAG_CONTACT);
                String contact2 = c.getString(TAG_CONTACT2);
                String cat = c.getString(TAG_CAT);
                String brand = c.getString(TAG_BRAND);
                String company = c.getString(TAG_COMPANY);
                String avgrating = c.getString(TAG_RATINGS);


                // creating new HashMap
                HashMap<String, String> map = new HashMap<String, String>();

                map.put(TAG_TITLE, title);
                map.put(TAG_ADDRESS, address);
                map.put(TAG_OPHOURS, ophours);
                map.put(TAG_CONTACT, contact);
                map.put(TAG_CONTACT2, contact2);
                map.put(TAG_CAT, cat);
                map.put(TAG_BRAND, brand);
                map.put(TAG_COMPANY, company);
                map.put(TAG_RATINGS, avgrating);
                // adding HashList to ArrayList
                mCommentList.add(map);

                //annndddd, our JSON data is up to date same with our array list
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    /**
     * Inserts the parsed data into our listview
     */
    private void updateList() {
        // For a ListActivity we need to set the List Adapter, and in order to do
        //that, we need to create a ListAdapter.  This SimpleAdapter,
        //will utilize our updated Hashmapped ArrayList,
        //use our single_post xml template for each item in our list,
        //and place the appropriate info from the list to the
        //correct GUI id.  Order is important here.
        ListAdapter adapter = new SimpleAdapter(this, mCommentList,
                R.layout.single_record, new String[] { TAG_TITLE, TAG_ADDRESS,
                TAG_OPHOURS, TAG_CONTACT, TAG_CONTACT2, TAG_CAT, TAG_BRAND, TAG_COMPANY, TAG_RATINGS },
                new int[] { R.id.outletname, R.id.outletaddress, R.id.outletophours, R.id.outletcontact,
                        R.id.outletcontact2, R.id.outletcat, R.id.outletbrand, R.id.outletcompany, R.id.ratings});
        ((SimpleAdapter) adapter).setViewBinder(new MyBinder());

        setListAdapter(adapter);

        //Showing empty view when ListView is empty
        ListView listView = (ListView) findViewById(android.R.id.list);
        listView.setEmptyView(findViewById(android.R.id.empty));
    }

    //ratingsbar
    class MyBinder implements SimpleAdapter.ViewBinder {
        public boolean setViewValue(View view, Object data, String textRepresentation) {
            if(view.getId() == R.id.ratings){
                String stringval = (String) data;
                float ratingValue = Float.parseFloat(stringval);
                RatingBar ratingBar = (RatingBar) view;
                ratingBar.setRating(ratingValue);
                return true;
            }
            return false;
        }
    }
    //call


    public class LoadRecordDetails extends AsyncTask<Void, Boolean, Boolean> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(Record.this);
            pDialog.setMessage("Loading details...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(false);
            pDialog.show();
        }
        @Override
        protected Boolean doInBackground(Void... arg0) {

            updateJSONdata();
            return null;

        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            pDialog.dismiss();

            updateList();
        }
    }
}

来自logcat:

 02-24 23:38:26.033    5653-5789/com.example.searchtest W/dalvikvm﹕ threadid=19: thread exiting with uncaught exception (group=0x4172ac08)
02-24 23:38:26.038    5653-5789/com.example.searchtest E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #4
    Process: com.example.searchtest, PID: 5653
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:300)
            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:841)
     Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7069)
            at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1108)
            at android.view.ViewGroup.invalidateChild(ViewGroup.java:4542)
            at android.view.View.invalidate(View.java:11795)
            at android.view.View.invalidate(View.java:11736)
            at android.widget.ImageView.invalidateDrawable(ImageView.java:211)
            at android.graphics.drawable.Drawable.invalidateSelf(Drawable.java:393)
            at android.graphics.drawable.Drawable.setVisible(Drawable.java:624)
            at android.widget.ImageView.onDetachedFromWindow(ImageView.java:1265)
            at android.view.View.dispatchDetachedFromWindow(View.java:13543)
            at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2800)
            at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2800)
            at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2800)
            at android.view.ViewGroup.removeAllViewsInLayout(ViewGroup.java:4249)
            at android.widget.AbsListView.resetList(AbsListView.java:2388)
            at android.widget.ListView.resetList(ListView.java:527)
            at android.widget.ListView.setAdapter(ListView.java:468)
            at android.app.ListActivity.setListAdapter(ListActivity.java:265)
            at com.example.searchtest.Results.updateList(Results.java:90)
            at com.example.searchtest.Results.access$100(Results.java:23)
            at com.example.searchtest.Results$LoadResults.doInBackground(Results.java:154)
            at com.example.searchtest.Results$LoadResults.doInBackground(Results.java:138)
            at android.os.AsyncTask$2.call(AsyncTask.java:288)
            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:841)

谢谢! :d

1 个答案:

答案 0 :(得分:0)

日志文件告诉我们:

android.view.ViewRootImpl$CalledFromWrongThreadException: 
Only the original thread that created a view hierarchy can touch its views.

这个例子意味着你试图窃听不在这个帖子中的视图。

以下是解释:

有线程调用UI,在您的代码中还有一个名为AsyncTask的线程 在这一行:updateList();您正在调用试图隐藏UI thread中的视图的方法,如下所示:

ListView listView = (ListView) findViewById(android.R.id.list);

因此,要解决此问题,只需删除此行并将其放入onCreate,因此您的代码应如下所示:

public class Record extends ListActivity {
    .
    .
    .
    ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    //note that use read_comments.xml instead of our single_post.xml
    setContentView(R.layout.details);
    listView = (ListView) findViewById(android.R.id.list);
  }
}