我有一个简单的应用程序,播放在线广播。为了显示来自在线php服务的标题我使用AsyncTask并从onCreate方法调用它。在android 4中,everythin还可以,但是在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]);
}
}
答案 0 :(得分: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
的Toast消息(来自非ui线程)。使用onPostExecute
显示Toast Message或根据doInBackground返回的结果更新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。因此需要在Thread.sleep(1000)
代码块之外移动runOnUiThread
答案 1 :(得分:1)
runOnUiThread
和AsyncTask
是两回事。你以错误的方式使用它。
试试这样: -
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