I have a bunch of Buttons (custom, with a few extra methods to apply other backgrounds, and revert to original), which can be assigned a background. But since I don’t know how large these backgrounds will or can be, I decided to set the background in a separate Thread. First, I had this code:
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
}
but I soon found out that this wasn’t the way to go. Slowly, the memory got flooded when I called this method a few thousand times. When I removed the new Thread() part, the memory wasn’t flooded, so the Thread was the cause of this (Memory Analyzer Tool told me the same).
Then I tried the 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
}
}
and call
new UpdateButtonTask().execute("Button", myButton, base64String);
in the button update method. But that didn’t work either (the button wasn’t updated at all. No text, no custom background). I read some articles and questions about Threading (this, this, and this amongst others), but I can’t seem to get it working. For now, no Thread and hoping the phones are fast enough to not cause trouble on the UI thread seems to be the best option, but I’d rather have something more reliable, like a Thread.
What am I doing wrong? or maybe just the full question How can I update a Button background on a background Thread (so the UI doesn’t stop working when applying larger backgrounds)?
I’m guessing that the problem is that you’re trying to update the UI on a non-UI thread. This throws an exception and kills your
AsyncTask.You should separate the processing-intensive tasks to the
AsyncTaskand then apply UI changes on the main thread (usingrunOnUiThread(Runnable)).Since you’re using a custom button, I don’t really know what you’re not allowed to do on a non-UI thread. I’m guessing the
setTextfunction is causing problems, if you haven’t overridden it.You should start by wrapping the whole body of your
doInBackgroundmethod in atry/catchblock and logging the exception to isolate the problem.