【问题标题】:Android activity is too busy to set TextView text?Android 活动太忙而无法设置 TextView 文本?
【发布时间】:2011-06-13 15:06:04
【问题描述】:

我有一个函数可以用 http 查询的条目填充我的 SQLite DB:

try {
        stringEntity = new StringEntity(SQL);
        httpPost.setEntity(stringEntity);
        httpResponse = httpClient.execute(httpPost);
        httpEntity = httpResponse.getEntity();
        bos = new ByteArrayOutputStream();
        httpEntity.writeTo(bos);

        data = bos.toString();

        reader = new BufferedReader(
                  new StringReader(data));

        try {
            //SAVE DATA IN MY DB || WORKS
        } catch(IOException e) {
          e.printStackTrace();
        }

    } catch (IOException e3) {
        // TODO Auto-generated catch block
        e3.printStackTrace();
    }

我尝试做的是在程序开始之前在我的活动上设置 textview 的文本(在我发布的代码中的第一个“try{..”之前)。 但文字不会改变,因为我的活动太忙而无法获取数据(我想。我没有其他解释..)

有什么建议吗?

谢谢, 前缀

更新 '' 从 AsyncTask 中获取数据''

 txtAction.setText("Loading...");

    AsyncTask<String, String, String> test = new cAsyncTask();

    try {
        data = test.execute(URL).get();

        reader = new BufferedReader(
                  new StringReader(data));

        while ((line = reader.readLine()) != null) {
            //SAVE DATA IN DB || WORKS
            }
        }

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

我的异步任务:

class cAsyncTask extends AsyncTask<String, String, String> {

protected String doInBackground(String... urls) {
    int count = urls.length;
    String data = "";
    DefaultHttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost;
    StringEntity stringEntity;
    HttpResponse httpResponse;
    HttpEntity httpEntity;
    ByteArrayOutputStream bos;
    String line;
    BufferedReader reader;
    for (int i = 0; i < count; i++) {
        httpPost = new HttpPost(urls[i].toString());
        try {
            stringEntity = new StringEntity(SQL);
            httpPost.setEntity(stringEntity);
            httpResponse = httpClient.execute(httpPost);
            httpEntity = httpResponse.getEntity();
            bos = new ByteArrayOutputStream();
            httpEntity.writeTo(bos);

            data = bos.toString();

        } catch (IOException e3) {
            // TODO Auto-generated catch block
            e3.printStackTrace();
        }
    }
    return data;
}

protected void onProgressUpdate(String... progress) {

}

protected void onPostExecute(String result) {
    String test = result;
}

【问题讨论】:

  • 你为什么要使用 AsyncTask.get()?来自文档手册AsyncTask.get():如有必要,等待计算完成,然后检索其结果。所以基本上你的卡在那里!

标签: android android-activity settext


【解决方案1】:

把你的代码繁忙的部分放到一个单独的线程中。

查看AsyncTask 实用程序

textview.setText("foo") 之后致电AsyncTask.execute(),你会没事的:)

问候

更新代码示例:

 txtAction.setText("Loading...");
 AsyncTask<String, String, String> test = new cAsyncTask();
 test.execute("http://...");

class cAsyncTask extends AsyncTask<String, String, String> {

protected String doInBackground(String... urls) {
    int count = urls.length;
    String data = "";
    DefaultHttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost;
    StringEntity stringEntity;
    HttpResponse httpResponse;
    HttpEntity httpEntity;
    ByteArrayOutputStream bos;
    String line;
    BufferedReader reader;
    for (int i = 0; i < count; i++) {
        httpPost = new HttpPost(urls[i].toString());
        try {
            stringEntity = new StringEntity(SQL);
            httpPost.setEntity(stringEntity);
            httpResponse = httpClient.execute(httpPost);
            httpEntity = httpResponse.getEntity();
            bos = new ByteArrayOutputStream();
            httpEntity.writeTo(bos);

            data = bos.toString();

        } catch (IOException e3) {
            // TODO Auto-generated catch block
            e3.printStackTrace();
        }
    }
     reader = new BufferedReader(
                  new StringReader(data));
       String line = "";
        while ((line = reader.readLine()) != null) {
            //SAVE DATA IN DB || WORKS
     }
    return data;
}


protected void onPostExecute(String result) {
    String test = result;
   textView.setText("Done!");
}

}

关键是将所有繁忙的代码放入doInBackGround 方法中,该方法将在单独的线程中运行。所有 UI 修改必须在同一个 UI 线程中,这可以在 onPostExecute 方法中完成,该方法将在同一个 UI 线程中执行

【讨论】:

  • 我尝试过但没有成功...我做错了什么? (我会在那里更新我的代码)
【解决方案2】:

您可以尝试在 TextView 上调用 invalidate()。但是对于繁重的数据加载方法,使用异步任务是最佳实践。这不会中断用户操作 UI 控件。

【讨论】:

    【解决方案3】:

    这与“太忙”无关,而是只有在方法返回时才会设置文本。并且随着您的网络,这将被延迟。

    顺便说一句。在 UI 线程上的 Honeycomb 网络上将引发异常并终止您的应用程序。

    【讨论】:

      猜你喜欢
      • 2020-07-01
      • 1970-01-01
      • 2020-03-01
      • 2013-10-27
      • 1970-01-01
      • 1970-01-01
      • 2012-09-13
      • 2016-12-07
      相关资源
      最近更新 更多