0

I have an asyntask

public class AsynNetworkOperation extends AsyncTask<String,Void,Void>{

private Context context = null;
private ProgressDialog dialog = null;
private String title = "";
private WebRequest request = null;
private String accessMethod = "";
private HttpResponse response = null;
AsynResponse delegate = null;

public AsynNetworkOperation(Context context, String method, String dialogTitle)
{
    this.context = context;
    accessMethod = method;
    this.title = dialogTitle;
    delegate = (AsynResponse) context;
}

@Override
protected void onPreExecute() {
    // TODO Auto-generated method stub
    super.onPreExecute();
    dialog = new ProgressDialog(context);
    dialog.setMessage(title);
    dialog.setCanceledOnTouchOutside(false);
    dialog.show();
}

@Override
protected Void doInBackground(String... data) {
    // TODO Auto-generated method stub
    request = new WebRequest(context);
    if(accessMethod.equals(ServiceUri.AccessMethod.GET)){
        response = request.makeHttpGetCall(data[0]);
    }
    return null;
}

@Override
protected void onPostExecute(Void result) {
    // TODO Auto-generated method stub
    super.onPostExecute(result);
    dialog.dismiss();
    delegate.responseResult(response);
    //dispose();
}

private void dispose()
{
    context = null;
    dialog = null;
    title = "";
    request = null;
    accessMethod = "";
    delegate = null;
}

}

and interface

public interface AsynResponse {

public void responseResult(HttpResponse response);

}

and then I have an SqliteHelper class

   //constructor 
public SQLLiteDbHelper(Context context,int dbVersion) {
    super(context,DATABASE_NAME, null, dbVersion);
    this.context = context;
    Log.d("tag","db version is "+DATABASE_VERSION);
    crypt = new Cryptography();
    utils = new Utils(context);
}
@Override
public void onCreate(final SQLiteDatabase db) {
    String s;

try {
    new AsynNetworkOperation(context, ServiceUri.AccessMethod.GET, "loading").execute(ServiceUri.SERVICE_URI+"s?d=abc"); 
} catch (Throwable t) {
    Toast.makeText(context, t.toString(), Toast.LENGTH_LONG).show();
    Log.d("tag",t.toString());
}
}

and a MainActivity class

public class MainActivity extends ListActivity implements AsynResponse{
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    searchText = (EditText) findViewById(R.id.searchText);
    utils = new Utils(MainActivity.this);
    db=(new SQLLiteDbHelper(MainActivity.this,utils.getInt(Key.Db_version))).getReadableDatabase(); 
    request = new WebRequest(this);
    status = new AsynGetEmployeeStatus();
}
   public void responseResult(HttpResponse response){
    HttpEntity et = response.getEntity();
String strr = utils.getResponseBody(et);  //it throw exception network on main thread
}
}

and get responsebody code is

    public String getResponseBody(final HttpEntity entity) throws Exception {

    InputStream instream = entity.getContent();

    if (instream == null) {
        return null;
    }

    if (entity.getContentLength() > Integer.MAX_VALUE) {
        return null;
    }

    StringBuilder buffer = new StringBuilder();
    BufferedReader reader = new BufferedReader(new InputStreamReader(instream, HTTP.UTF_8));

    String line = null;
    try {
        while ((line = reader.readLine()) != null) {
            buffer.append(line);
        }
    } 
    finally {
        instream.close();
        reader.close();
        line=null;
    }
    return buffer.toString();
}

it is working fine on emulator and but it is throwing network on main thread exception on device.I dont know why it is throwing exception.There are other network opeartion also which use the same asyntask but that work fine on device. only in this case it is throwing exception. Please help me finding the problem.

thanks

Waqar Ahmed
  • 5,005
  • 2
  • 23
  • 45
  • @Vyger..thats not a duplicate. it is code specific. i know when this exception throws.i have added all permissions.the code and asyntask works fine but only in this case it is throwing exception if i wrap String strr = utils.getResponseBody(et); in thread then it works fine.i dont know why it is not working. – Waqar Ahmed Apr 08 '14 at 11:53
  • 2
    Start by examining the stacktrace to see where the network code in main thread is. – laalto Apr 08 '14 at 11:53
  • @laalto..when it goes into getResponseBody method, it crashes at while ((line = reader.readLine()) != null) line – Waqar Ahmed Apr 08 '14 at 11:54
  • if i wrap into thread then its work fine. I am not getting why it is throwing exception while i am reading the content.because i have already the http response. – Waqar Ahmed Apr 08 '14 at 11:55

2 Answers2

4

when it goes into getResponseBody method, it crashes at while ((line = reader.readLine()) != null) line

Apparently, you are calling getResponseBody() on the main application thread. Do that work in doInBackground() of your AsyncTask.

I am not getting why it is throwing exception while i am reading the content.because i have already the http response.

No, you do not. You started the HTTP request. You have not finished the HTTP request until you close the InputStream you get from the HttpEntity. That InputStream is reading off of the socket that represents the HTTP connection.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • then why it is working fine on emulator.? – Waqar Ahmed Apr 08 '14 at 11:58
  • 1
    @wqrahd: It is not "working find on emulator". Your UI is frozen on the emulator while you are in `getResponseBody()`. If by "working fine" you mean "it is not throwing this exception", the `NetworkOnMainThreadException` is thrown automatically on Android 4.0+, and perhaps you are using an Android 2.x emulator. – CommonsWare Apr 08 '14 at 12:01
  • I get your point but still i think there is something im not getting..:( – Waqar Ahmed Apr 08 '14 at 12:01
  • i have send different header for different activity in response and i return httpresponse from asyntask. i now get that i should read stream in asyntask task too.. can you please tell me how to get header now because there is only one asyntask for every activity and different headers for different activity. – Waqar Ahmed Apr 08 '14 at 12:04
  • @wqrahd: "there is only one asyntask for every activity and different headers for different activity" -- if I am interpreting you correctly, pass in the headers into the `AsyncTask`, either via a constructor or as parameters to `execute()` (which are then delivered to `doInBackground()`). – CommonsWare Apr 08 '14 at 12:05
  • no..i am getting headers in response. not sending header. – Waqar Ahmed Apr 08 '14 at 12:06
  • I want to get header from HttpResponse. – Waqar Ahmed Apr 08 '14 at 12:08
  • @wqrahd: Then you deliver the headers to the activity by the same means as you will deliver the results of reading in the stream to the activity. For example, you could implement `hereAreTheHeaders()` on the activity, and call that from `onPostExecute()` (or, conceivably, call that from `doInBackground()`, if being on the background thread is what the activity needs). – CommonsWare Apr 08 '14 at 12:10
  • i have decided to pass headers as parameter delegate.responseResult(jsonResponse, headers);...does it correct..? – Waqar Ahmed Apr 08 '14 at 12:14
-2
add StrictMode:


if (android.os.Build.VERSION.SDK_INT > 9) {
                StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
                StrictMode.setThreadPolicy(policy);
                                                      }
Trupti
  • 284
  • 5
  • 7