TheBlueCat
TheBlueCat

Reputation: 1195

Async Task Crashing my App

I'm trying to download strings from a HttpPost and I'm using the Async class to do this. But, when I run the App, it crashes. This is my first time using the Async class and I'm afraid I did some really silly, could you help me to find the error?

Just to note, I also want to update my listview when I get the strings. I tried to do this, buy putting them in a separate method.

Code:

public static final String PREFS_NAME = "MyPrefsFile";
    BufferedReader in = null;
    String data = null;
    String username;
    List headlines;
    List links;
    String password;
    ArrayAdapter adapter;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
            // listview method
            ContactsandIm();
        new loadcontactsandIm().execute(PREFS_NAME);

    }

    public class loadcontactsandIm extends AsyncTask<String, Integer, String> {
        @Override
        protected String doInBackground(String... arg0) {
            // TODO Auto-generated method stub

            // Create a new HttpClient and Post Header
            HttpClient httpclient = new DefaultHttpClient();

            /* login.php returns true if username and password is equal to saranga */
            HttpPost httppost = new HttpPost("http://gta5news.com/login.php");

            try {

                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
                nameValuePairs.add(new BasicNameValuePair("username", username));
                nameValuePairs.add(new BasicNameValuePair("password", password));
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                // Execute HTTP Post Request
                Log.w("HttpPost", "Execute HTTP Post Request");
                HttpResponse response = httpclient.execute(httppost);
                Log.w("HttpPost", "Execute HTTP Post Request");
                in = new BufferedReader(new InputStreamReader(response.getEntity()
                        .getContent()));
                StringBuffer sb = new StringBuffer("");
                String l ="";
                String nl ="";
                while ((l =in.readLine()) !=null) {
                    sb.append(l + nl);  
                }
                in.close();
                 data = sb.toString();
                 ListView lv = getListView();
                 lv.setTextFilterEnabled(true);

                headlines.add(data);




                setListAdapter(adapter);
                return null;

            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return data;
        }

        private StringBuilder inputStreamToString(InputStream is) {
            String line = "";
            StringBuilder total = new StringBuilder();
            // Wrap a BufferedReader around the InputStream
            BufferedReader rd = new BufferedReader(new InputStreamReader(is));
            // Read response until the end
            try {
                while ((line = rd.readLine()) != null) {
                    total.append(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            // Return full string
            return total;
        }

        }


    public void ContactsandIm() {
        headlines = new ArrayList();

        //get prefs
        SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
        String username = settings.getString("key1", null);
        String password = settings.getString("key2", null);
        if(username.equals("irock97"))  {
            Toast toast=Toast.makeText(this, "Hello toast", 2000);
            toast.setGravity(Gravity.TOP, -30, 50);
            toast.show();

        } else {
            Toast toast=Toast.makeText(this, "Hello toast", 2000);
            toast.setGravity(Gravity.TOP, -30, 150);
            toast.show();
        }
        ArrayAdapter adapter = new ArrayAdapter(this,
                android.R.layout.simple_list_item_1, headlines);


    }

}

LogCat:

03-25 13:47:37.356: E/AndroidRuntime(2484): FATAL EXCEPTION: AsyncTask #1
03-25 13:47:37.356: E/AndroidRuntime(2484): java.lang.RuntimeException: An error occured while executing doInBackground()
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.lang.Thread.run(Thread.java:1096)
03-25 13:47:37.356: E/AndroidRuntime(2484): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.view.ViewRoot.requestLayout(ViewRoot.java:594)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.view.View.requestLayout(View.java:8125)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.view.View.requestLayout(View.java:8125)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.view.View.requestLayout(View.java:8125)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.view.ViewGroup.removeAllViews(ViewGroup.java:2255)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:196)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.app.Activity.setContentView(Activity.java:1647)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.app.ListActivity.ensureList(ListActivity.java:314)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.app.ListActivity.getListView(ListActivity.java:299)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at com.gta5news.bananaphone.ChatService$loadcontactsandIm.doInBackground(ChatService.java:87)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at com.gta5news.bananaphone.ChatService$loadcontactsandIm.doInBackground(ChatService.java:1)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
03-25 13:47:37.356: E/AndroidRuntime(2484):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)

Upvotes: 0

Views: 2158

Answers (4)

Nesim Razon
Nesim Razon

Reputation: 9794

do you job in doInBackground, and use your jobs result on onPostExecute.

example:

public class TestActivity extends Activity 
{
  private GetTask getTask;
  public ListView fList;

  @Override
  public void onCreate(Bundle savedInstanceState) 
  {
    getTask = new GetTask(); 
    getTask.execute();
    fList = (ListView) findViewById(R.id.lstview);
  }

  public class GetTask extends AsyncTask<Void, Void, List> 
  {
    @Override
    protected List doInBackground(Void... params) {
      return load();
    }      

    @Override
    protected void onPostExecute(List result) {
        ArrayAdapter adapter = new ArrayAdapter(this,
                android.R.layout.simple_list_item_1, headlines);

      fList.setAdapter(adapter);
    }
  }

  private List load() { 
    // get your data from http
    // add to your list, probably you can use model.
    List headlines;
    headlines.add(data);

    return headlines;
  }


}

Upvotes: 2

Shankar Agarwal
Shankar Agarwal

Reputation: 34765

Firstly you must not handle any UI related task in doInBackground() to UI related task we have a method call onPostExecute() where we can handle all ui related tasks.. If you still dont want to use these method and handle it in doInBackground() then you do it in the below code::::

runOnUiThread(new Runnable() {
public void run() {
//your UI related code stuff    
    ListView lv = getListView();
    lv.setTextFilterEnabled(true);
    headlines.add(data);
    setListAdapter(adapter); //do what you like here
}
});

Upvotes: 1

Darren Kopp
Darren Kopp

Reputation: 77627

You can't interact with UI elements from any other thread than the main thread. You'll need to do all of the interaction of the ListView in the onPostExecute method.

Basically you will want to compile all the data from the web request in the doInBackground method, stored on your task instance, then on the onPostExecute get the list view and set the adapter and populate with the data.

Upvotes: 2

207
207

Reputation: 3804

You set your ListView adapter in doInBackground. Never manipulate the UI outside of UI thread

Upvotes: 2

Related Questions