我有一堆按钮(自定义,有一些额外的方法可以应用其他背景,还原为原始版本),可以为其分配背景。但由于我不知道这些背景的大小有多大,我决定将背景设置在一个单独的Thread中。首先,我有这个代码:
public void updateButton(final Button b, final String d, final String s) {
b.nullify(); //Recycles previous background, else OOM error
b.setText(s);
if (d != null) {
new Thread() {
@Override
public void run() {
b.setBackgroundFromBase64(d);
}
}.run();
}
else b.setBackgroundToDefault(); //Sets standard android background
}
但我很快发现这不是要走的路。慢慢地,当我把这种方法召唤几千次时,记忆被淹没了。当我删除new Thread()
部分时,内存没有被淹没,因此Thread就是这个原因(Memory Analyzer Tool也告诉我了)。
然后我尝试了AsyncTask
:
private class UpdateButtonTask extends AsyncTask<Object, Void, Void> {
@Override
protected Void doInBackground(Object... objs) {
String s = (String)objs[0];
Button b = (Button)objs[1];
String d = (String) objs[2];
b.nullify(); //Recycles previous background, else OOM error
b.setText(s);
if (d != null) b.setBackgroundFromBase64(d);
else b.setBackgroundToDefault();
return null;
}
@Override
protected void onProgressUpdate(Void v) {
//As far as I know, I don't need this method
}
@Override
protected void onPostExecute(Void v) {
//Neither this one
}
}
并致电
new UpdateButtonTask().execute("Button", myButton, base64String);
按钮更新方法中的。但这也不起作用(按钮根本没有更新。没有文字,没有自定义背景)。我阅读了一些关于线程的文章和问题(this,this和this等等),但我似乎无法让它发挥作用。现在,没有线程,并希望手机足够快,不会在UI线程上造成麻烦似乎是最好的选择,但我宁愿有更可靠的东西,比如Thread。 我做错了什么?或者只是完整的问题如何在后台线程上更新按钮背景(因此在应用更大背景时UI不会停止工作)的吗
答案 0 :(得分:0)
我猜测问题是您正在尝试在非UI线程上更新UI。这会抛出异常并杀死您的AsyncTask
。
您应该将处理密集型任务分离到AsyncTask
,然后在主线程上应用UI更改(使用runOnUiThread(Runnable)
)。
由于你使用的是自定义按钮,我真的不知道你在非UI线程上不允许做什么。我猜测setText
函数会导致问题,如果你没有覆盖它。
首先应将doInBackground
方法的整个部分包装在try/catch
块中,然后记录异常以隔离问题。
答案 1 :(得分:-1)
可能这段代码会帮助你
new Thread(new Runnable() {
public void run() {
context.runOnUiThread(new Runnable() {
public void run() {
b.setBackgroundFromBase64(d);
}
});
}
}).start();