【问题标题】:Cannot set text in TextView from a Async class [duplicate]无法通过异步类在 TextView 中设置文本 [重复]
【发布时间】:2018-12-12 16:13:39
【问题描述】:

在我的 CountryInfoActivity.java 中,我有一个 Async Class,它从该网站检索 JSONhttps://pt.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro=&explaintext=&titles=Portugal。 然后它将extract 节点解析为字符串,以便我可以在我的TextView 中设置它。 问题是,每当我在文本视图中设置文本时,我的应用程序崩溃。 JSON 解析是正确的,因为它正在检索我想要的所有信息......

这些是我用来检索数据的类,在最后一个中,我尝试将数据 textoSobrePais 设置到我的 TextView 中...顺便说一下,在我的 onCreate 方法中,我以这种方式调用课程new DownloadTask().execute(url);

public class DownloadTask extends AsyncTask<String,Integer,Void>{
@Override
protected Void doInBackground(String... params) {
    String url = params[0];
    getJSONFromURL(url);
    return null;
}
}



public String getJSONFromURL(String url){
    String json_string = null;
    try{
        URL obj = new URL(url);
        HttpURLConnection http = (HttpURLConnection) obj.openConnection();
        http.setRequestMethod("GET");
        int response = http.getResponseCode();
        Log.i("response",Integer.toString(response));
        BufferedReader reader  = new BufferedReader(new InputStreamReader(http.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine())!= null){
            sb.append(line+"\n");
        }
        reader.close();

        json_string = sb.toString();
        Log.i("json_string",json_string);
    } catch (UnsupportedEncodingException e){
        e.printStackTrace();
    } catch (ClientProtocolException e){
        e.printStackTrace();
    } catch (IOException e){
        e.printStackTrace();
    }
    ParseJson(json_string);
    return null;


}


public void ParseJson (String json){

JSONObject obj = null;
try {
    obj = new JSONObject(json);
} catch (JSONException e) {
    e.printStackTrace();
}
try {
    JSONArray pageIdObj = obj.getJSONObject("query").getJSONObject("pages").names();
    String page =  String.valueOf(pageIdObj.get(0));
    Log.i("ASdasd",page);
    textoSobrePais = obj.getJSONObject("query").getJSONObject("pages").getJSONObject(page).getString("extract");
    page = "";
    Log.i("texte",textoSobrePais);
    txtInfoPais = findViewById(R.id.txtInfoPais);
    txtInfoPais.setText(textoSobrePais);
} catch (JSONException e) {
    e.printStackTrace();
}

}

这是崩溃时给我的错误: https://pastebin.com/PJh5r36u

有人可以帮忙吗?

【问题讨论】:

  • 每一个让你想到将你的 code-sn-p 移动到 UI 线程上运行的答案都是可怕的。尝试了解 AsynTask 的其他回调方法,然后自己动手。
  • @PankajKumar 为什么可怕?你能说得更具体点吗?

标签: java android


【解决方案1】:

我们无法从后台线程更新 UI。您必须在主线程上设置文本

像这样在主线程上运行

runOnUiThread(new Runnable() {
            @Override
            public void run() {
                txtInfo.setText(textoPais);
            }
 });

【讨论】:

  • 我试过了,它没有崩溃,我在调用类后设置它们......问题是,即使 AsyncTask 正在运行,它也会运行(因为它在 doInBackground 中)所以,我需要它在 AsyncTask 完全运行时运行...
【解决方案2】:

您无法从非 UI 线程更新 UI 组件。在 UI 线程上运行 TextView 的更新如下:

 runOnUiThread(new Runnable() {
            @Override
            public void run() {
                txtInfoPais.setText(textoSobrePais);
            }
 });

【讨论】:

  • 我应该让txtInfoPais = findViewById(R.id.txtInfoPais) 取消它吗?
  • @AndréSilva 在 onCreate 中这样做
  • 谢谢,帮了我!
猜你喜欢
  • 2015-05-07
  • 2020-03-01
  • 2020-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多