1

我正在尝试开发一个通过 json 资源每分钟更新一次的小部件,我的问题是当我尝试在 jellybean 上启动它时它会崩溃,而姜饼可以工作。

我在这里看到我必须将所有互联网连接移动到主线程,对吗?目前我有一个名为 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;
    }
}

每分钟都被称为 updateAppWidget() ,它是 WidgetProvider 类的一个方法。在 updateAppWidget() 里面有:

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

你能告诉我如何陡峭地解决它吗?谢谢

4

3 回答 3

2

正如建议的那样,AsyncTask是要走的路。像这样更改您的代码:

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

请注意onPostExecute中的代码,它执行更新应用小部件所需的额外工作。

然后像这样启动异步任务:

 new HttpRequestTask().execute(context);
于 2012-10-13T14:48:34.037 回答
0

您需要将网络连接主线程移到后台线程。如果您在主线程上使用网络,更高版本的 Android 将使应用程序崩溃。

最直接的解决方案是使用一个AsyncTask,它将在一个单独的线程上做一些工作(做你的网络获取),然后让你在完成后在主线程上做后续工作。

这篇文章中有一个示例,在 SO 或 Google 上可以找到许多其他示例。

于 2012-10-13T14:43:34.417 回答
0

从下面的代码调用你的函数[来自线程]

第1步 :

而不是这两行

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

调用下面的代码行,

    Thread thread = new Thread()
    {
      @Override
      public void run() {
          try {

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

          } catch (Exception e) {
              e.printStackTrace();
          }
      }
    };

thread.start();

第2步:

如果上述功能对您不起作用,那么

使用此参考链接

我希望这对你有用。谢谢。

于 2012-10-13T15:10:41.530 回答