An exception occurred: android.os.NetworkOnMainThreadException

680 views Asked by At

i get error An exception occurred: android.os.NetworkOnMainThreadException even when i already use AsyncTask. Error is on LongOperation.java at the line while ((line = reader.readLine()) != null) { here is the code:

AsyncTaskActivity.java:

package com.example.myfirstapp;

import java.util.concurrent.ExecutionException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class AsyncTaskActivity extends Activity implements OnClickListener {

    Button btn;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(this);
    }

    public void onClick(View view) {

        switch (view.getId()) {
        case R.id.button1:
            try {
                TextView txt = (TextView) findViewById(R.id.output);

                txt.setText(new LongOperation().execute("http://search.twitter.com/search.json?q=javacodegeeks").get());

            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            break;
        }

    }

}

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:indeterminate="false"
        android:max="10"
        android:padding="10dip" >
    </ProgressBar>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Progress" >
    </Button>

    <TextView
        android:id="@+id/output"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Replace" />

</LinearLayout>

LongOperation.java:

package com.example.myfirstapp;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.os.AsyncTask;
import android.util.Log;

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

    InputStream is = null;

    @Override
    protected String doInBackground(String... urls) {

        try {

            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(urls[0]);
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            HttpParams myParams = new BasicHttpParams();
            HttpConnectionParams.setConnectionTimeout(myParams, 10000);
            HttpConnectionParams.setSoTimeout(myParams, 10000);

            is = entity.getContent();

        } catch (Exception e) {
            Log.e("log_tag", "Error in http connection " + e.toString());
        }
        return is.toString();
    }

    @Override
    protected void onPostExecute(String result) {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            result = sb.toString();
            // System.out.println("Result = " + result);

        } catch (Exception e) {
            Log.e("log_tag", "Error converting result " + e.toString());
        }
    }

    @Override
    protected void onPreExecute() {
    }

    @Override
    protected void onProgressUpdate(Void... values) {
    }
}

is there anyone can help?

2

There are 2 answers

0
laalto On BEST ANSWER

onPostExecute() and onPreExecute() run on the main UI thread. Move network operations to doInBackground().

0
Raghunandan On
new LongOperation().execute("http://search.twitter.com/search.json?q=javacodegeeks").get()

Calling get() does not make it asynchronous anymore. Blocks the ui thread.

public final Result get ()

Waits if necessary for the computation to complete, and then retrieves its result.

You need

new LongOperation().execute("http://search.twitter.com/search.json?q=javacodegeeks")

I would use a interface as a callback to communicate the result back to the activity.

Something like the answer by blackbelt in the below link

How do I return a boolean from AsyncTask?

Also move all your network related operation to doInbackground and update ui in onPostExecute

Example:

public class MainActivity extends Activity implements LongOperation.callBack {

    Button btn;
    TextView txt;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        txt = (TextView) findViewById(R.id.textView1);
        btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                new LongOperation(MainActivity.this).execute("http://search.twitter.com/search.json?q=javacodegeeks");
            }

        });
    }

    @Override
    public void returnText(String value) {
        // TODO Auto-generated method stub
        txt.setText(value);
    }
    }

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:text="Button" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="48dp"
        android:text="TextView" />

</RelativeLayout>

LongOperation.java

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

    InputStream is = null;
    String _response;
    callBack cb;
    ProgressDialog pd;
    interface callBack
    {
        public void returnText(String value);
    };
    public LongOperation(Context context) {
        // TODO Auto-generated constructor stub
        cb = (callBack) context;
        pd = new ProgressDialog(context);
        pd.setMessage("LongOperation...");
    }

    @Override
    protected String doInBackground(String... urls) {

        try {

            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(urls[0]);
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            HttpParams myParams = new BasicHttpParams();
            HttpConnectionParams.setConnectionTimeout(myParams, 10000);
            HttpConnectionParams.setSoTimeout(myParams, 10000);
            HttpEntity resEntity = response.getEntity();
             _response=EntityUtils.toString(resEntity);
            is = entity.getContent();

        } catch (Exception e) {
            Log.e("log_tag", "Error in http connection " + e.toString());
        }
        return _response;
    }

    @Override
    protected void onPostExecute(String result) {
      super.onPostExecute(result);
      pd.dismiss();
      if(cb!=null)
      {
          cb.returnText(result);
      }
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pd.show();
    }

    @Override
    protected void onProgressUpdate(Void... values) {
    }
}