3

I am trying to build my first android app, it uses AsyncTask to execute a post request. (to log into a website).

I got the app working fine with StrictMode turned off, but i would like it to be error free when executed in StrictMode also. Eventhough I redesigned my app using AsyncTask it still gives me this error:

android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)

From what I have read on the internet, using AsyncTask should have solved this. I don't want to use Java Threads because i want to learn to do it the correct way.

I build a new class to execute the task, it's called MyAsyncTask, here is de class code

<code>
package com.am.tuto;
import android.os.AsyncTask;// removed rest of imports for readability
public class MyAsyncTask extends AsyncTask<Void, Void, String> {
String u;
String p;

public MyAsyncTask(String u, String p)
{
    this.u=u;
    this.p=p;
}

@Override protected String doInBackground(Void... params) {
String msg="";
if ((u.length()>0)&&(p.length()>0))
{
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("http://irrationalgamers.com/test.php");
try 
{
    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
    nameValuePairs.add(new BasicNameValuePair("username", u));
    nameValuePairs.add(new BasicNameValuePair("password", p));
    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    HttpResponse response =httpclient.execute(httppost); // <----the error occurs
    HttpEntity entity = response.getEntity();
    String responseString = EntityUtils.toString(entity, "UTF-8");
    System.out.println(responseString);
    msg="success";
    msg=responseString;
} 

catch (ClientProtocolException e) 
{
// TODO Auto-generated catch block
} 
catch (IOException e) 
{
// TODO Auto-generated catch block
}  
}
else
{
   msg="failed";
}
return msg;
}

@Override protected void onPostExecute(String result) 
{
    MyBus.getInstance().post(new AsyncTaskResultEvent(doInBackground()));
}
}
</code>

I am thinking that it might be because i created my own constructor, but i feel I really have to pass it some parameters.

I can continue programming the app, but it would be nice to learn how to prevent this issue in the future. Every article i read on the error points me to AsyncTask, it's hard to find a solution for when already implemented...

Any thoughts on this would be highly aprreciated

Bart Hofma
  • 644
  • 5
  • 19
  • how you are starting `AsyncTask`? – ρяσѕρєя K Sep 19 '14 at 15:10
  • how do you run the AsyncTask? With get or execute? – Blackbelt Sep 19 '14 at 15:10
  • @blackbelt I am running it with execute – Bart Hofma Sep 19 '14 at 15:12
  • Format your code with some indentation. To your question, simply using AsyncTask doesn't solve the problem. Every method **except** `doInBackground()` runs on the UI so make sure you aren't doing any network stuff in any of the other methods. – codeMagic Sep 19 '14 at 15:14
  • @codemagic i think i'm doing all network related stuffin this method..... unless you see something I don't :) – Bart Hofma Sep 19 '14 at 15:16
  • 3
    `MyBus.getInstance().post(new AsyncTaskResultEvent(doInBackground()));` line causing issue in `onPostExecute` because `onPostExecute` always run on UI Thread and you are calling `doInBackground` from `onPostExecute` – ρяσѕρєя K Sep 19 '14 at 15:17
  • I'm not even looking to see until there is some indentation but probably what @ρяσѕρєяK said – codeMagic Sep 19 '14 at 15:18
  • Thank you, i will try to see if i can move it around, and i'll let you know if it works – Bart Hofma Sep 19 '14 at 15:19
  • @codemagic i'll try what he said , and i made some indentation anyway :) – Bart Hofma Sep 19 '14 at 15:22
  • It just throws me a new exception, it think the bus has to be run off of the main-thread.... Caused by: java.lang.IllegalStateException: Event bus [Bus "default"] accessed from non-main thread null – Bart Hofma Sep 19 '14 at 15:27
  • @BartHofma : what happen when you are running app without `MyBus.getInstance().post(new AsyncTaskResultEvent(doInBackground()));` line ? – ρяσѕρєя K Sep 19 '14 at 15:46
  • @ρяσѕρєя K then it works fine, also when i comment the network stuff, i think it is becoming clear to me. Thank you for you help :) – Bart Hofma Sep 19 '14 at 17:25

1 Answers1

2

Basically, ρяσѕρєя K answered your question. Some extra details: you should never call doInBackground yourself. The whole point of AsyncTask is that it manages passing the work to the background worker thread and returning the results to the UI thread. What doInBackground returns is what onPostExecute receives as a parameter.

Your onPostExecute should look like this:

@Override
protected void onPostExecute(String result) {
    MyBus.getInstance().post(new AsyncTaskResultEvent(result));
}
bolot
  • 2,854
  • 2
  • 18
  • 15
  • thank you for your input, I can't test my code over the weekend but i think my question is answered. Though I still don't understand when the doInBackground() method is being called, I'll accept the answer as it answers the question i put up :) Does it run on object creation? – Bart Hofma Sep 19 '14 at 17:34
  • ```AsyncTask``` will do that for you, you don't have to call it explicitly. So, what you do is enough: ```new MyAsyncTask(username, password).execute()``` – bolot Sep 19 '14 at 17:38
  • & ρяσѕρєя K Thank you for explaining it this well, instead of just copy/pasting a solution, I know where I made the mistake, and where to look if it happens again. I'll try out the code when i get home after the weekend :D – Bart Hofma Sep 19 '14 at 17:51
  • i just tried doing it like this and I just wanted to let you know it worked perfectly! Thanks again :) – Bart Hofma Sep 22 '14 at 07:33