0

I am getting this exception

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

Below is the code:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_page2);



        lv = (ListView) findViewById(R.id.list_view);



        btnNew = (Button)findViewById(R.id.btnAddNew);
        btnNew.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent moveToNewUser = new Intent(getApplication(),ExecutiveInfo2.class);
                moveToNewUser.putExtra("ClickType","1");
                startActivity(moveToNewUser);
            }
        });

        new Connection2().execute();

        // Listview Data
       }

    private class Connection2 extends AsyncTask {

        @Override
        protected Object doInBackground(Object... arg0) {
            test2();
            return null;
        }

        @Override
        protected void onPostExecute(Object s) {
        super.onPostExecute(s);
      }

    }

    public void test2() {
        HttpURLConnection connection = null;
        try {
            sharedpreferences = getSharedPreferences("MyPrefs", this.MODE_PRIVATE);

             String storedUUID = sharedpreferences.getString("UUID", "");

            String url2= "http://crm.xqicai.com/sales/getExecutiveInfo?UUID="+storedUUID;
            //String url = "http://crm.xqicai.com/sales/login";
            URL postUrl = new URL(url2);

            connection = (HttpURLConnection) postUrl.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod("GET");
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);

            connection.setRequestProperty("Content-Type", "application/json");
            connection.connect();

            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));// 设置编�,�则中文乱�

            while (true) {
                String str = reader.readLine();
                if (str == null) {
                    break;
                }
                System.out.println(str);

                JSONObject mainObject = new JSONObject(str);
                Status = mainObject.getString("status");
                int j=0;
                if(Status.equals("0"))
                {
                    JSONObject uniObject = mainObject.getJSONObject("data");
                    JSONArray a = uniObject.getJSONArray("data");
                    for (int i = 0; i < a.length(); i++) {

                        JSONObject json_obj = a.getJSONObject(i);


                        String demo = json_obj.getString("realName");
                        fetchedNames[j]= demo;
                        j++;

                    }

                    // Adding items to listview

                    adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, fetchedNames);

                    lv.setAdapter(adapter);
                    }
                else
                {
                    JSONObject mainObject2 = new JSONObject(str);
                    errorMsg = mainObject2.getString("msg");
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(), errorMsg, Toast.LENGTH_SHORT).show();
                        }
                    });
                }
        }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

        }
 }

I'm only a beginner, so please forgive me for asking possibly a stupid question.

Saumik Bhattacharya
  • 891
  • 1
  • 12
  • 28
Gaurav
  • 1
  • 1
  • you need to call runOnUIThread() method to update the data in listview from background thread – dex Mar 14 '16 at 17:34
  • tried that also,but not working – Gaurav Mar 14 '16 at 17:35
  • A possible duplicate of [this](http://stackoverflow.com/questions/35750739/how-to-display-checkbox-on-every-entry-in-a-listview/35751284#35751284). – Saumik Bhattacharya Mar 14 '16 at 17:38
  • Possible duplicate of [Android "Only the original thread that created a view hierarchy can touch its views."](http://stackoverflow.com/questions/5161951/android-only-the-original-thread-that-created-a-view-hierarchy-can-touch-its-vi) – archived Mar 14 '16 at 18:43

3 Answers3

0

What line is giving the error? The problem is that you update a view created in the main thread, in your AsyncTask (a different thread). You should update this view in the onPostExecute of your AsyncTask (this is done in your main thread). I don't see immediately where you update the view.

EDIT: Your problem should be solved if you put these two lines

adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, fetchedNames);
lv.setAdapter(adapter);

below this line:

lv = (ListView) findViewById(R.id.list_view);

or in the:

protected void onPostExecute(Object s)
Kerkhofsd
  • 269
  • 1
  • 9
  • adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, fetchedNames); lv.setAdapter(adapter); – Gaurav Mar 14 '16 at 17:38
  • Hence, you created the 'lv = (ListView) findViewById(R.id.list_view);' on your main thread, but you manipulate it in a different thread (in the AsyncTask). You shouldn't create and set the adapter in your doInBackground, but somewhere else. – Kerkhofsd Mar 14 '16 at 17:41
  • Probably because fetchedNames is empty or null? You have to rework the code so that you can add the adapter in the main thread. – Kerkhofsd Mar 14 '16 at 17:58
0

Test that:

    ListView lv...
    lv.post(new Runnable() {
        @Override
        public void run() {
            //Update UI;
            lv.setAdapter(...);
        }
    })
Khang .NT
  • 1,504
  • 6
  • 24
  • 46
  • You really shouldn't update UI components (created in the main thread) in a different thread, hence this is not solving the problem. – Kerkhofsd Mar 14 '16 at 17:48
0

you can try use Handler with sendEmptyMessage() inside asynctask to pass by exception.

ex.

Handler mHandler = new Handler(Looper.getMainLooper()) {
                @Override
                public void handleMessage(Message inputMessage) {

                    // Adding items to listview

                    adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, fetchedNames);

                    lv.setAdapter(adapter);   
                }
});

note for code bellow:

//call mHandler.sendEmpyMessage() in asynctask:

if(Status.equals("0"))
                {
                    JSONObject uniObject = mainObject.getJSONObject("data");
                    JSONArray a = uniObject.getJSONArray("data");
                    for (int i = 0; i < a.length(); i++) {

                        JSONObject json_obj = a.getJSONObject(i);


                        String demo = json_obj.getString("realName");
                        fetchedNames[j]= demo;
                        j++;

                    }

                    // Adding items to listview
                    mHandler.sendEmpyMessage(0); //0 or any number is identify code from you want use to check with every action
GiapLee
  • 436
  • 2
  • 8