Android Choreographer:渲染机制深度解析

需积分: 15 3 下载量 163 浏览量 更新于2024-07-15 1 收藏 2.29MB DOCX 举报
"Android系统中的Choreographer是自Android 4.1版本开始引入的一个关键组件,用于协调UI操作,包括输入处理、动画执行和视图绘制。它通过接收垂直同步信号(VSync)来确保这三个操作在每帧渲染时有序进行,从而优化用户体验并避免界面卡顿。Choreographer的源代码位于`android.view`包中,提供开发者接口以在特定的帧时机执行回调函数。" 在Choreographer的源码中,我们可以看到几个关键的接口,如`postFrameCallback`,允许开发者注册回调函数,这些函数将在下一帧渲染时被调用。回调函数有四种类型,对应于Input、Animation、Draw以及一种专门处理动画启动问题的类型。当VSync信号到来时,Choreographer按照Input、Animation、Draw的顺序执行这些操作。 Choreographer的工作流程如下:接收到VSync信号后,依次执行输入处理、动画和绘制。如果在第二个VSync信号到来之前,所有操作都已完成,那么界面会更新为新一帧的内容。反之,如果在第二个信号到达时,绘制还未完成,就会发生丢帧现象,导致界面显示旧的帧内容,从而可能造成用户感知到的卡顿。 丢帧是性能问题的一个重要指标,因为它意味着系统未能在规定时间内完成一帧的更新。每个Looper线程都有自己的Choreographer实例,其他线程可以向它们post回调,这样就能跨线程进行UI操作的协调。 为了优化性能和避免丢帧,开发者需要注意以下几点: 1. 减少主线程的计算量,尽可能地将耗时操作移到后台线程。 2. 使用硬件加速,启用View的硬件渲染模式。 3. 有效管理动画,避免同时运行大量复杂的动画。 4. 在合适的时机执行绘制操作,如使用`View.postInvalidateOnAnimation()`而不是直接调用`View.invalidate()`来延迟绘制直到下一个动画帧。 理解Choreographer的工作原理对于优化Android应用的性能至关重要,尤其是涉及流畅动画和响应式用户界面的设计时。通过合理利用Choreographer,开发者可以确保UI操作与系统的VSync信号同步,从而提供更佳的用户体验。

android.os.BadParcelableException: ClassNotFoundException when unmarshalling: at android.os.Parcel.readParcelableCreator(Parcel.java:3364) at android.os.Parcel.readParcelable(Parcel.java:3272) at android.view.InsetsSourceControl.<init>(InsetsSourceControl.java:71) at android.view.InsetsSourceControl$1.createFromParcel(InsetsSourceControl.java:116) at android.view.InsetsSourceControl$1.createFromParcel(InsetsSourceControl.java:114) at android.os.Parcel.readTypedObject(Parcel.java:3119) at android.os.Parcel.readTypedArray(Parcel.java:3089) at android.view.IWindowSession$Stub$Proxy.relayout(IWindowSession.java:1739) at android.view.ViewRootImpl.relayoutWindow(ViewRootImpl.java:7702) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2816) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2133) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8439) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1089) at android.view.Choreographer.doCallbacks(Choreographer.java:907) at android.view.Choreographer.doFrame(Choreographer.java:842) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1074) at android.os.Handler.handleCallback(Handler.java:967) at android.os.Handler.dispatchMessage(Handler.java:104) at android.os.Looper.loop(Looper.java:243) at android.app.ActivityThread.main(ActivityThread.java:8021) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:591) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1164)

2023-06-10 上传

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.hjschoolhelper210301201_1, PID: 13135 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference at com.example.hjschoolhelper210301201_1.ClubinfoAdpter.getView(ClubinfoAdpter.java:44) at android.widget.AbsListView.obtainView(AbsListView.java:2458) at android.widget.ListView.makeAndAddView(ListView.java:2067) at android.widget.ListView.fillDown(ListView.java:793) at android.widget.ListView.fillFromTop(ListView.java:855) at android.widget.ListView.layoutChildren(ListView.java:1838) at android.widget.AbsListView.onLayout(AbsListView.java:2255) at android.view.View.layout(View.java:23693) at android.view.ViewGroup.layout(ViewGroup.java:6413) at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1855) at android.view.View.layout(View.java:23693) at android.view.ViewGroup.layout(ViewGroup.java:6413) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at android.view.View.layout(View.java:23693) at android.view.ViewGroup.layout(ViewGroup.java:6413) at androidx.appcompat.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:536) at android.view.View.layout(View.java:23693) at android.view.ViewGroup.layout(ViewGroup.java:6413) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at android.view.View.layout(View.java:23693) at android.view.ViewGroup.layout(ViewGroup.java:6413) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1891) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1729) at android.widget.LinearLayout.onLayout(LinearLayout.java:1638) at android.view.View.layout(View.java:23693) at android.view.ViewGroup.layout(ViewGroup.java:6413) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at com.android.internal.policy.DecorView.onLayout(DecorView.java:799) at android.view.View.layout(View.java:23693) at android.view.ViewGroup.layout(ViewGroup.java:6413) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:3999) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3372) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2328) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9087) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1231) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239) at android.view.Choreographer.doCallbacks(Choreographer.java:899) at android.view.Choreographer.doFrame(Choreographer.java:832) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7872) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

2023-05-17 上传