Reputation: 511786
I noticed in my app that the onDraw()
for my custom view was getting called constantly. I thought it was a problem with my code so I made the simplest test app I could. Still, onDraw()
is being continuously called.
Here is the activity:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
And the custom view:
public class MyEditText extends EditText {
int counter=0;
// Constructors
public MyEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyEditText(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
counter++;
Log.i("Test", Integer.toString(counter));
}
}
Here is the stack trace when pausing within onDraw():
test [Android Application]
DalvikVM [localhost:8693]
Thread [<1> main] (Suspended (breakpoint at line 29 in MyEditText))
<VM does not provide monitor information>
MyEditText.onDraw(Canvas) line: 29
MyEditText(View).draw(Canvas) line: 13577
MyEditText(View).getDisplayList(DisplayList, boolean) line: 12528
MyEditText(View).getDisplayList() line: 12572
MyEditText(View).draw(Canvas, ViewGroup, long) line: 13301
RelativeLayout(ViewGroup).drawChild(Canvas, View, long) line: 3042
RelativeLayout(ViewGroup).dispatchDraw(Canvas) line: 2912
RelativeLayout(View).getDisplayList(DisplayList, boolean) line: 12526
RelativeLayout(View).getDisplayList() line: 12572
RelativeLayout(View).draw(Canvas, ViewGroup, long) line: 13301
FrameLayout(ViewGroup).drawChild(Canvas, View, long) line: 3042
FrameLayout(ViewGroup).dispatchDraw(Canvas) line: 2912
FrameLayout(View).draw(Canvas) line: 13580
FrameLayout.draw(Canvas) line: 467
FrameLayout(View).getDisplayList(DisplayList, boolean) line: 12528
FrameLayout(View).getDisplayList() line: 12572
FrameLayout(View).draw(Canvas, ViewGroup, long) line: 13301
LinearLayout(ViewGroup).drawChild(Canvas, View, long) line: 3042
LinearLayout(ViewGroup).dispatchDraw(Canvas) line: 2912
LinearLayout(View).getDisplayList(DisplayList, boolean) line: 12526
LinearLayout(View).getDisplayList() line: 12572
LinearLayout(View).draw(Canvas, ViewGroup, long) line: 13301
PhoneWindow$DecorView(ViewGroup).drawChild(Canvas, View, long) line: 3042
PhoneWindow$DecorView(ViewGroup).dispatchDraw(Canvas) line: 2912
PhoneWindow$DecorView(View).draw(Canvas) line: 13580
PhoneWindow$DecorView(FrameLayout).draw(Canvas) line: 467
PhoneWindow$DecorView.draw(Canvas) line: 2284
PhoneWindow$DecorView(View).getDisplayList(DisplayList, boolean) line: 12528
PhoneWindow$DecorView(View).getDisplayList() line: 12572
HardwareRenderer$Gl20Renderer(HardwareRenderer$GlRenderer).draw(View, View$AttachInfo, HardwareRenderer$HardwareDrawCallbacks, Rect) line: 1168
ViewRootImpl.draw(boolean) line: 2221
ViewRootImpl.performDraw() line: 2093
ViewRootImpl.performTraversals() line: 1904
ViewRootImpl.doTraversal() line: 1070
ViewRootImpl$TraversalRunnable.run() line: 4296
Choreographer$CallbackRecord.run(long) line: 725
Choreographer.doCallbacks(int, long) line: 555
Choreographer.doFrame(long, int) line: 525
Choreographer$FrameDisplayEventReceiver.run() line: 711
Handler.handleCallback(Message) line: 615
Choreographer$FrameHandler(Handler).dispatchMessage(Message) line: 92
Looper.loop() line: 137
ActivityThread.main(String[]) line: 4914
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 511
ZygoteInit$MethodAndArgsCaller.run() line: 808
ZygoteInit.main(String[]) line: 575
NativeStart.main(String[]) line: not available [native method]
Thread [<10> Binder_2] (Running)
Thread [<9> Binder_1] (Running)
There are lots of similarly titled questions to mine on SO but only one gave a possible answer: https://stackoverflow.com/a/7741500/3681880
They said:
There isn't an infinite loop here. What is going on is the OS is redrawing your activity as fast as possible.
Is that true? Isn't that bad for performance or battery life or something? And why would you ever have to call invalidate()
if the system is just calling onDraw()
automatically?
Upvotes: 1
Views: 2618
Reputation: 342
Had the same problem. Another possible reason of infinite looping of onDraw()
method, is when you use a GlobalLayoutListener with onGlobalLayout()
performing some action with your custom view onDraw()
method in some way, and you don't remove it.
Upvotes: 0
Reputation: 511786
As @southerton mentioned in the comments above, the EditText
needs to invalidate itself indefinitely in order to animate its cursor.
Upvotes: 1