Search code examples
androidjsonmultithreadinghttprequestandroid-4.2-jelly-bean

Unable to start receiver: android.os.NetworkOnMainThreadException with android JellyBean


I'm trying to develop a widget that updates itself every minute by a json resource, my problem is that when i try to launch it on jellybean it crashes, while with gingerbread works.

I saw here that i must move all internet connection to the main thread, right? At the moment i've a class called HttpRequest:

public class HttpRequest {    
    private String url;

    public HttpRequest(String url)
    {       
        this.url = url;
    }

    public String GetContent() throws ClientProtocolException, IOException
    {
        HttpClient client = new DefaultHttpClient();
        HttpGet request = new HttpGet(url);
        HttpResponse response = client.execute(request);

        String html = "";
        InputStream in = response.getEntity().getContent();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        StringBuilder str = new StringBuilder();
        String line = null;
        while((line = reader.readLine()) != null)
        {
            str.append(line);
        }
        in.close();
        html = str.toString();
        return html;
    }
}

Every minute is called updateAppWidget() that is a method of WidgetProvider class. Inside updateAppWidget() there is:

HttpRequest r = new HttpRequest("http://www.hwlogos.com/test.json");
remoteViews.setTextViewText(R.id.ip, r.GetContent());

Can you tell me how solve it steep by steep? thanks


Solution

  • As proposed, AsyncTask is the way to go. Change your code like this:

    private class HttpRequestTask extends AsyncTask<Context, Void, String> {
    
        private Context context;
    
        protected String doInBackground(Context... contextParam) {
            context = contextParam[0];
            HttpClient client = new DefaultHttpClient();
            HttpGet request = new HttpGet("http://www.hwlogos.com/test.json");
            HttpResponse response = client.execute(request);
    
            String html = "";
            InputStream in = response.getEntity().getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            StringBuilder str = new StringBuilder();
            String line = null;
            while((line = reader.readLine()) != null)
            {
                str.append(line);
            }
            in.close();
            html = str.toString();
            return html;
         }
    
         protected void onPostExecute(String html) {
             AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
             RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
             remoteViews.setTextViewText(R.id.ip, html);
             appWidgetManager.updateAppWidget(new ComponentName(context, WidgetProvider .class), remoteViews);
         }
    }
    

    Note the code in onPostExecute that does the extra work required to update an app widget.

    Then start the asynchronous task like this:

     new HttpRequestTask().execute(context);