Issue
I would like to manipulate canvas after loading a drawable from the resources on a background thread. Here is the code (the relevant part):
public class Test extends ReplacementSpan {
@Override
public void draw(
final Canvas canvas,
final CharSequence text,
final int start,
final int end,
final float x,
final int top,
final int y,
final int bottom,
final Paint paint) {
new Thread(new Runnable() {
@Override
public void run() {
drawable = context.getResources().getDrawable(resourceId);
drawable.setBounds(0, 0, size, size);
canvas.save();
int transY = bottom - size - paint.getFontMetricsInt().descent;
canvas.translate(x, transY);
drawable.draw(canvas);
canvas.restore();
}
}).start();
}
}
This code leads to a native crash without a stack trace:
Fatal signal 11 (SIGSEGV), code 1, fault addr 0xf8 in tid 10735
I've noticed that the crash appears when trying to perform any kind of operation on canvas. Putting the code that operates on canvas into new Handler(Looper.getMainLooper()).post(new Runnable() {...});
doesn't resolve the issue.
The code works fine if done on the main thread, but it leads to noticeable lags when scrolling.
Is there a way to load the drawable on a background thread and then draw it on canvas?
Solution
Is there a way to load the drawable on a background thread and then draw it on canvas?
Yes. Load the drawable outside of draw()
, on a background thread if you so choose.
Neither resourceId
nor size
are parameters to draw()
. Instead, you are providing those by some other means (constructor, setters, etc.). Obtain and configure your drawable at that point, not in draw()
. This limits your draw()
work to only the statements that involve the Canvas
.
BTW, I'm not 100% certain, but you may need to call mutate()
on that Drawable
before calling setBounds()
, if the same resource is used elsewhere in your app.
Answered By - CommonsWare
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.