我在我的应用中注意到我的自定义视图的onDraw()
不断被调用。我认为这是我的代码的问题,所以我做了最简单的测试应用程序。不过,onDraw()
仍在不断被召唤。
以下是活动:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
自定义视图:
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));
}
}
这是在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)
在SO上有许多类似标题的问题,但只有一个给出了可能的答案:https://stackoverflow.com/a/7741500/3681880
他们说:这里没有无限循环。发生的事情是操作系统正在尽快重新绘制您的活动。
这是真的吗?对于性能或电池续航时间不是那么糟糕吗?如果系统只是自动调用invalidate()
,为什么还要调用onDraw()
?
答案 0 :(得分:1)
正如@southerton在上面的评论中所提到的,EditText
需要无限期地使自己无效,以便为其光标设置动画。
答案 1 :(得分:0)
有同样的问题。无限循环onDraw()
方法的另一个可能原因是,当您使用GlobalLayoutListener onGlobalLayout()
以某种方式使用自定义视图onDraw()
方法执行某些操作时,您不会将其删除