Android бросает исключение NetworkOnMainThreadException

у меня есть асинтаск

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;
}

}

и интерфейс

public interface AsynResponse {

public void responseResult(HttpResponse response);

}

а потом у меня есть класс SqliteHelper

   //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());
}
}

и MainActivity класс

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
}
}

и получить код ответа

    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();
}

он отлично работает на emulator, но выдает network on main thread exception на device. Я не знаю, почему он выдает исключение. Есть и другие network opeartion, которые используют тот же asyntask, но отлично работают на устройстве. только в данном случае это throwing exception. Пожалуйста, помогите мне найти проблему.

Спасибо


person Waqar Ahmed    schedule 08.04.2014    source источник
comment
@Vyger .. это не дубликат. это зависит от кода. я знаю, когда выбрасывается это исключение. Я добавил все разрешения. Код и асинтаск работают нормально, но только в этом случае возникает исключение, если я оберну String strr = utils.getResponseBody (et); в потоке тогда он работает нормально. я не знаю, почему он не работает.   -  person Waqar Ahmed    schedule 08.04.2014
comment
Начните с изучения трассировки стека, чтобы увидеть, где находится сетевой код в основном потоке.   -  person laalto    schedule 08.04.2014
comment
@laalto.. когда он переходит в метод getResponseBody, он падает в строке while ((line = reader.readLine()) != null)   -  person Waqar Ahmed    schedule 08.04.2014
comment
если я заверну в нить, то все работает нормально. Я не понимаю, почему он выдает исключение, пока я читаю содержимое. Потому что у меня уже есть ответ http.   -  person Waqar Ahmed    schedule 08.04.2014


Ответы (2)


когда он переходит в метод getResponseBody, он падает в строке while ((line = reader.readLine()) != null)

Судя по всему, вы вызываете getResponseBody() в основном потоке приложения. Выполните эту работу в doInBackground() вашего AsyncTask.

Я не понимаю, почему он выдает исключение, пока я читаю содержимое. Потому что у меня уже есть ответ http.

Нет, ты не. Вы запустили HTTP-запрос. Вы не завершили HTTP-запрос, пока не закроете InputStream, полученный от HttpEntity. Этот InputStream считывает данные из сокета, представляющего HTTP-соединение.

person CommonsWare    schedule 08.04.2014
comment
тогда почему он отлично работает на эмуляторе.? - person Waqar Ahmed; 08.04.2014
comment
@wqrahd: не работает поиск в эмуляторе. Ваш пользовательский интерфейс зависает в эмуляторе, пока вы находитесь в getResponseBody(). Если под «нормальной работой» вы подразумеваете, что это исключение не выбрасывается, NetworkOnMainThreadException выдается автоматически на Android 4.0+, и, возможно, вы используете эмулятор Android 2.x. - person CommonsWare; 08.04.2014
comment
Я понимаю вашу точку зрения, но все же я думаю, что я что-то не понимаю .. :( - person Waqar Ahmed; 08.04.2014
comment
я отправляю разные заголовки для разных действий в ответ, и я возвращаю httpresponse из asyntask. теперь я понимаю, что я должен читать поток и в асинтаске.. не могли бы вы рассказать мне, как теперь получить заголовок, потому что для каждого действия есть только один асинтаск и разные заголовки для разных действий. - person Waqar Ahmed; 08.04.2014
comment
@wqrahd: есть только одна асинтаск для каждого действия и разные заголовки для разных действий - если я правильно вас интерпретирую, передайте заголовки в AsyncTask либо через конструктор, либо в качестве параметров в execute() (которые затем доставляются в doInBackground() ). - person CommonsWare; 08.04.2014
comment
нет.. я получаю заголовки в ответ. не отправляет заголовок. - person Waqar Ahmed; 08.04.2014
comment
Я хочу получить заголовок от HttpResponse. - person Waqar Ahmed; 08.04.2014
comment
@wqrahd: Затем вы доставляете заголовки в активность теми же средствами, что и результаты чтения в потоке в активность. Например, вы можете реализовать hereAreTheHeaders() в действии и вызвать его из onPostExecute() (или, возможно, вызвать его из doInBackground(), если для действия требуется работа в фоновом потоке). - person CommonsWare; 08.04.2014
comment
я решил передать заголовки в качестве параметра delegate.responseResult(jsonResponse, заголовки);... это правильно..? - person Waqar Ahmed; 08.04.2014
comment
в любом случае спасибо, сэр, за вашу помощь... :) - person Waqar Ahmed; 08.04.2014

person    schedule
comment
НЕ просто отключите эту ошибку. РЕШИТЬ НАСТОЯЩУЮ ПРОБЛЕМУ. - person CommonsWare; 08.04.2014
comment
@CommonsWare..does entity.getContent(); должен работать в другом потоке.?.. В другом случае он отлично работает на эмуляторе. - person Waqar Ahmed; 08.04.2014
comment
На самом деле я сделал так и подумал, что это правильный путь, спасибо за улучшение - person Trupti; 08.04.2014