1

我有一个播放在线广播的简单应用程序。为了从在线 php 服务显示标题,我使用 AsyncTask 并从 onCreate 方法调用它。在 android 4 中一切正常,但在 android 2 中它被错误粉碎

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

然后在互联网上我发现,我必须使用类似的代码

new Thread(new Runnable() {

        @Override
        public void run() {
            MainActivity.this.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    //my code
                }
            });
        }
    }).start();

但是在我使用这个技巧之后,在我的 android 4 和 android 2 版本中看不到任何按钮和文本视图。这是我的代码:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //thread for update title every second
    new Thread(new Runnable() {

        @Override
        public void run() {
            MainActivity.this.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    while(true) {
                        try {
                            new ShowTitle()
                                .execute("http://info.radiostyle.ru/inc/getinfo.php?getcurentsong=20383&mount=lezgifm");
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            String tag = "Update title";
                            Log.e(tag, "Update title crashed", e);
                        }
                    }
                }
            });
        }
    }).start();
}

 //get title string from online source
private String getMusicTitle(String url) {
    Document doc = null;
    String title = "Music Title";
    try {
        url = "http://info.radiostyle.ru/inc/getinfo.php?getcurentsong=20383&mount=lezgifm";
        InputStream input = new URL(url).openStream();
        doc = Jsoup.parse(input, "CP1251", url);
        title = doc.body().text();//doc.select(".products_name").first().text();

    } catch (IOException e) {
        Log.e(TAG, "Failed to load HTML code", e);
        Toast.makeText(this, "Failed to load title", Toast.LENGTH_SHORT).show();
    }
    return title;
}

//class for show the audio title
private class ShowTitle extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... urls) {
        return getMusicTitle(urls[0]);
    }

    protected void onPostExecute(final String result) {
        lblMusicName.setText(result);
    }

}

编辑:(我的工作代码)

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    new ShowTitle()
        .execute("http://info.radiostyle.ru/inc/getinfo.php?getcurentsong=20383&mount=lezgifm");
}

private String getMusicTitle(String url) {
    Document doc = null;
    String title = "Music Title";
    try {
        url = "http://info.radiostyle.ru/inc/getinfo.php?getcurentsong=20383&mount=lezgifm";
        InputStream input = new URL(url).openStream();
        doc = Jsoup.parse(input, "CP1251", url);
        title = doc.body().text();

    } catch (IOException e) {
        Log.e(TAG, "Failed to load HTML code", e);
        title = "Failed to load title";
    }
    return title;
}

private class ShowTitle extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... urls) {
        while (true) {
            String str = getMusicTitle(urls[0]);
            publishProgress(str);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                String tag = "Update title";
                Log.e(tag, "Update title crashed", e);
            }
        }
    }

    protected void onProgressUpdate(String... result) {
        lblMusicName.setText(result[0]);
    }

}
4

2 回答 2

2

在这里 :

 try {
       //....your code here
    } catch (IOException e) {
        Log.e(TAG, "Failed to load HTML code", e);
       Toast.makeText(this, "Failed to load title", 
                           Toast.LENGTH_SHORT).show();  //<<< this line
    }

您正在尝试显示来自doInBackground(来自非 ui 线程)的 Toast 消息。用于onPostExecute根据 doInBackground 返回的结果显示 Toast 消息或更新 UI

第二个问题在这里:

while(true) {
  try {
        ...
      Thread.sleep(1000); //<<< here calling Thread.sleep on Main UI Thread
   } catch (InterruptedException e) {
      String tag = "Update title";
      Log.e(tag, "Update title crashed", e);
 }

这将始终在 AsyncTask 执行后冻结 Ui 线程。所以需要移出Thread.sleep(1000)代码runOnUiThread

于 2013-05-21T10:25:48.603 回答
1

runOnUiThreadAsyncTask是两个不同的东西。您以错误的方式使用它。

像这样尝试:-

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

            new ShowTitle().execute("http://info.radiostyle.ru/inc/getinfo.php?getcurentsong=20383&mount=lezgifm");
        }

 //get title string from online source
private String getMusicTitle(String url) {
    Document doc = null;
    String title = "Music Title";
    try {
        url = "http://info.radiostyle.ru/inc/getinfo.php?getcurentsong=20383&mount=lezgifm";
        InputStream input = new URL(url).openStream();
        doc = Jsoup.parse(input, "CP1251", url);
        title = doc.body().text();//doc.select(".products_name").first().text();

    } catch (IOException e) {
        Log.e(TAG, "Failed to load HTML code", e);
        title = "Failed to load title";

    }
    return title;
}

//class for show the audio title
private class ShowTitle extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... urls) {
        String str = getMusicTitle(urls[0]);
        while(true) {
           publishProgress(str);
           try {

                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        String tag = "Update title";
                        Log.e(tag, "Update title crashed", e);
                    }
        }
        return str;
    }

    @Override
    protected void onProgressUpdate(String... progress) {
        if(returnVal.startsWith("Failed")) {
             Toast.makeText(this, returnVal, Toast.LENGTH_SHORT).show();
        } else {
             lblMusicName.setText(result);
        }
    }


}

您必须在onProgressUpdate

于 2013-05-21T10:33:10.437 回答