为什么onDraw()会连续调用?

时间:2014-08-26 06:50:22

标签: android ondraw

我在我的应用中注意到我的自定义视图的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()

2 个答案:

答案 0 :(得分:1)

正如@southerton在上面的评论中所提到的,EditText需要无限期地使自己无效,以便为其光标设置动画。

答案 1 :(得分:0)

有同样的问题。无限循环onDraw()方法的另一个可能原因是,当您使用GlobalLayoutListener onGlobalLayout()以某种方式使用自定义视图onDraw()方法执行某些操作时,您不会将其删除