0

I am triyng to set ListView elements according to read datas from webservice.I use thread to communicate with web service.I took the datas from web service but when I tried to setadapter to listView , ı took fatal exception.What might be cause of this?Here is my code :

First part initialize the listView :

l = (ListView) findViewById(R.id.listView1);

        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                getData();
            }

        };
        //Toast.makeText(CardChooseActivity.this, adapter.getItem(position), Toast.LENGTH_SHORT).show();
        (new Thread(runnable)).start();

and the second part (getData method inside Runnable Thread) :

   JSONArray jArray = new JSONArray(successMessage);
        String[] s = new String[jArray.length()];
        for (int i = 0; i < jArray.length(); i++)
        {
                JSONObject json_data = jArray.getJSONObject(i);                                                        
                s[i]=json_data.getString("id");
                System.out.println("String inside : " + s[i]);
                //data.add(json_data.getString("id"));
        }

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

        l.setAdapter(adapter);

and my LogCat :

09-06 07:42:02.347: E/AndroidRuntime(418): FATAL EXCEPTION: Thread-10
09-06 07:42:02.347: E/AndroidRuntime(418): android.view.ViewRoot$CalledFromWrongThreadException:                 
Only the original thread that created a view hierarchy can touch its views.
09-06 07:42:02.347: E/AndroidRuntime(418):  at       
android.view.ViewRoot.checkThread(ViewRoot.java:2802)
09-06 07:42:02.347: E/AndroidRuntime(418):  at   
android.view.ViewRoot.focusableViewAvailable(ViewRoot.java:1596)
09-06 07:42:02.347: E/AndroidRuntime(418):  at    
android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:451)
09-06 07:42:02.347: E/AndroidRuntime(418):  at   
android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:451)
09-06 07:42:02.347: E/AndroidRuntime(418):  at   
android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:451)
09-06 07:42:02.347: E/AndroidRuntime(418):  at   
android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:451)
09-06 07:42:02.347: E/AndroidRuntime(418):  at   
android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:451)
09-06 07:42:02.347: E/AndroidRuntime(418):  at android.view.View.setFlags(View.java:4474)
09-06 07:42:02.347: E/AndroidRuntime(418):  at     
android.view.View.setFocusableInTouchMode(View.java:3104)
09-06 07:42:02.347: E/AndroidRuntime(418):  at     
android.widget.AdapterView.checkFocus(AdapterView.java:694)
09-06 07:42:02.347: E/AndroidRuntime(418):  at   
android.widget.ListView.setAdapter(ListView.java:437)
09-06 07:42:02.347: E/AndroidRuntime(418):  at  
com.example.example.CardChooseActivity.getData(CardChooseActivity.java:166)
09-06 07:42:02.347: E/AndroidRuntime(418):  at  
com.example.example.CardChooseActivity.access$0(CardChooseActivity.java:122)
09-06 07:42:02.347: E/AndroidRuntime(418):  at     

com.example.example.CardChooseActivity$1.run(CardChooseActivity.java:73) 09-06 07:42:02.347: E/AndroidRuntime(418): at java.lang.Thread.run(Thread.java:1096)

Thanks in advance.

dodotu
  • 117
  • 1
  • 5
  • 17

2 Answers2

1

If you use handler in android, it will take more time for the response to receive and ANR(Android Not responding) dialog will open which will force user to provide two options.whether to close application or to wait. To overcome this, use AsyncTask..

 Use AsyncTask to perform this.
    @Override
  public void onClick(View v) {
  new Data().execute();
  }
   });
     }
      class Data extends AsyncTask<Void, Void, Void> { 
    /**
     * Before starting background thread
     * Show Progress Bar Dialog
     * */
       @Override
      protected void onPreExecute() {
        super.onPreExecute();
        showDialog(progress_bar_type);
    }
 
    /**
     * Downloading file in background thread
     * */
    @Override
    protected Void doInBackground(Void... f_url) {
        int count;
        try {
               JSONArray jArray = new JSONArray(successMessage);
        final String[] s = new String[jArray.length()];
        for (int i = 0; i < jArray.length(); i++)
        {
                JSONObject json_data = jArray.getJSONObject(i);                                                        
                s[i]=json_data.getString("id");
                System.out.println("String inside : " + s[i]);
                //data.add(json_data.getString("id"));
        }
        } catch (Exception e) {
            Log.e("Error: ", e.getMessage());
        }
    }
 
    /**
     * Updating progress bar
     * */
 
    /**
     * After completing background task
     * Dismiss the progress dialog
     * **/
        @Override
        protected void onPostExecute(String file_url) {
        dismissDialog(progress_bar_type);
         adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, s);
        l.setAdapter(adapter);
       }
 
}
Shadow
  • 6,864
  • 6
  • 44
  • 93
0

Parse data from server to local array in run() method, after that pass array to adapter and set adapter to ListView, but in separate UI thread, you can't update UI from non-UI threads.

Here is an example how to parse data and load it to ListView using Handler.

Other way, use runOnUiThread().

Community
  • 1
  • 1
Veaceslav Gaidarji
  • 4,261
  • 3
  • 38
  • 61