Mustansar Saeed
Mustansar Saeed

Reputation: 2790

NetworkOnMainThreadException in AsyncTask

I am getting the NetworkOnMainThreadException while executing the two network requests in AsyncTask. In first request I get the Response XML and in second request, I download the Image InputStream to be used in BitmapFactory.decodeStream. Please find below the exception:

NetworkOnMainThreadException

07-10 08:20:49.961: W/System.err(8570): android.os.NetworkOnMainThreadException
07-10 08:20:49.961: W/System.err(8570):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
07-10 08:20:49.961: W/System.err(8570):     at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:163)
07-10 08:20:49.971: W/System.err(8570):     at libcore.io.IoBridge.recvfrom(IoBridge.java:513)
07-10 08:20:49.971: W/System.err(8570):     at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
07-10 08:20:49.971: W/System.err(8570):     at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
07-10 08:20:49.971: W/System.err(8570):     at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
07-10 08:20:49.981: W/System.err(8570):     at java.io.BufferedInputStream.read(BufferedInputStream.java:304)

AyncTask

public class FetchDataTask extends AsyncTask {

    @Override
    protected Object doInBackground(Object... object) {
        String url = (String)object[0];
        TASK_TYPE type = (TASK_TYPE)object[1];
        Object[] objects = new Object[4];
        switch(type)
        {
        case FETCH_NOTICES:
            publishProgress("Fetching notices ...");

             // Request # 1 to get the JSON XML

            String data = apiRequestGET(url);
            ArrayList<Notices> notices = extractUserFriendsDataFromXML(data);
            Notices notice = notices.get(0);

            publishProgress("Fetching done.");
            objects[0] = type;
            objects[1] = new ArrayList<Notices>(notices.subList(1, notices.size()));
            objects[2] = notice.getUniversityTitle();
            try {

             // Request # 2 to get the InputStream

                objects[3] = (InputStream) new URL(notice.getUniversityLogo()).getContent();
            } catch (MalformedURLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            return objects; 
        }

        return null;
    }

    private String apiRequestGET(String requestString)
    {
        HttpClient httpClient = new DefaultHttpClient();
        HttpContext localContext = new BasicHttpContext();
        HttpGet httpGet = new HttpGet(requestString);

        String responseText = null;
        try 
        {
            HttpResponse response = httpClient.execute(httpGet, localContext);
            System.out.println("Some Response" +response);
            HttpEntity entity = response.getEntity();
            responseText = EntityUtils.toString(entity);
        }
        catch (Exception e1) 
        {
            return e1.getLocalizedMessage();
        }
        return responseText;
    }

}

Can anyone please tell me what I am doing wrong? Two network requests in doInBackground can not be done?

Thanks in advance!

Edit Full Stack Trace

07-10 08:52:18.672: W/System.err(9213): android.os.NetworkOnMainThreadException
07-10 08:52:18.682: W/System.err(9213):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
07-10 08:52:18.682: W/System.err(9213):     at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:163)
07-10 08:52:18.682: W/System.err(9213):     at libcore.io.IoBridge.recvfrom(IoBridge.java:513)
07-10 08:52:18.692: W/System.err(9213):     at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
07-10 08:52:18.692: W/System.err(9213):     at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
07-10 08:52:18.692: W/System.err(9213):     at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
07-10 08:52:18.702: W/System.err(9213):     at java.io.BufferedInputStream.read(BufferedInputStream.java:304)
07-10 08:52:18.702: W/System.err(9213):     at libcore.net.http.FixedLengthInputStream.read(FixedLengthInputStream.java:45)
07-10 08:52:18.702: W/System.err(9213):     at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:168)
07-10 08:52:18.702: W/System.err(9213):     at java.io.BufferedInputStream.read(BufferedInputStream.java:309)
07-10 08:52:18.712: W/System.err(9213):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
07-10 08:52:18.712: W/System.err(9213):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:529)
07-10 08:52:18.712: W/System.err(9213):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:601)
07-10 08:52:18.722: W/System.err(9213):     at com.alpha.noticeslist.NoticeListActivity.dataFetched(NoticeListActivity.java:145)
07-10 08:52:18.722: W/System.err(9213):     at com.alpha.web.FetchDataTask.onPostExecute(FetchDataTask.java:124)
07-10 08:52:18.732: W/System.err(9213):     at android.os.AsyncTask.finish(AsyncTask.java:631)
07-10 08:52:18.732: W/System.err(9213):     at android.os.AsyncTask.access$600(AsyncTask.java:177)
07-10 08:52:18.732: W/System.err(9213):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
07-10 08:52:18.732: W/System.err(9213):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-10 08:52:18.742: W/System.err(9213):     at android.os.Looper.loop(Looper.java:137)
07-10 08:52:18.742: W/System.err(9213):     at android.app.ActivityThread.main(ActivityThread.java:5041)
07-10 08:52:18.752: W/System.err(9213):     at java.lang.reflect.Method.invokeNative(Native Method)
07-10 08:52:18.752: W/System.err(9213):     at java.lang.reflect.Method.invoke(Method.java:511)
07-10 08:52:18.752: W/System.err(9213):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
07-10 08:52:18.752: W/System.err(9213):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
07-10 08:52:18.762: W/System.err(9213):     at dalvik.system.NativeStart.main(Native Method)

I get the error while a function called from onPostExecute inwhich InputStream is being passed as:

public void dataFetched(InputStream inputstream)
    {       
            Bitmap bitmap = BitmapFactory.decodeStream(inputstream);
            logo.setImageBitmap(bitmap);
    }

onPostExecute

@Override
    protected void onPostExecute(Object result){
        statusDialog.dismiss();
        Object[] objects = (Object[])result;
        TASK_TYPE type = (TASK_TYPE)objects[0];
        switch(type)
        {
        case FETCH_NOTICES:
        ((NoticeListActivity)callerActivity).dataFetched((InputStream)objects[3]);
        break;
        }
    }

Upvotes: 2

Views: 962

Answers (4)

dave.c
dave.c

Reputation: 10908

I think you are getting the error because although you get a reference to the InputStream in your background thread, you actually read from the stream when you call decodeStream in onPostExecute, which runs on the main thread

Move the call:

Bitmap bitmap = BitmapFactory.decodeStream(inputstream);

into doInBackground and pass the bitmap back rather than the inputstream

Upvotes: 2

DCoder
DCoder

Reputation: 3488

your class sholud be:

class FetchDataTask extends AsyncTask<Object, String, Void> 
    {

        @Override
        protected Void doInBackground(Object... params) {
            //code here

            publishProgress("");

            return null;
        }

        @Override
        protected void onProgressUpdate(String... values) {
            // TODO Auto-generated method stub
            super.onProgressUpdate(values);
        }
    }

you can execute like new FetchDataTask.execute([your parameter]);

Upvotes: 0

ngrashia
ngrashia

Reputation: 9884

Use the below code for async task:

private class FetchDataTask  extends AsyncTask <String, Void, Void>

{
Object[] objects = new Object[4];
protected void onPreExecute() {
}
@Override
protected Void doInBackground(String... paramsObj) {
    String url = (String)object[0];
    TASK_TYPE type = (TASK_TYPE)object[1];

    switch(type)
    {
    case FETCH_NOTICES:
        publishProgress("Fetching notices ...");

        // Request # 1 to get the JSON XML

        String data = apiRequestGET(url);
        ArrayList<Notices> notices = extractUserFriendsDataFromXML(data);
        Notices notice = notices.get(0);

        publishProgress("Fetching done.");
        objects[0] = type;
        objects[1] = new ArrayList<Notices>(notices.subList(1, notices.size()));
        objects[2] = notice.getUniversityTitle();
        try {

            // Request # 2 to get the InputStream

            objects[3] = (InputStream) new URL(notice.getUniversityLogo()).getContent();
        } catch (MalformedURLException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }

    return null;
}

protected void onPostExecute(Void unused) 
{
    // Do action with objects
}

}

From the calling method, use:

new FetchDataTask().execute();

Upvotes: 0

zozelfelfo
zozelfelfo

Reputation: 3776

Make sure that you are calling to myFetchDataTask.execute(). Are you calling to doInBackground() directly, if that is the case it will not work, if not, please post how you execute your AsyncTask.

Hope it helps!

Upvotes: 0

Related Questions