皮皮网

【confluence的源码】【spring 3 企业应用开发实战 源码】【cocos2d-x游戏源码】oncreate()源码分析

时间:2024-12-26 02:50:58 分类:时尚 来源:mui视频类源码

1.❤️ Android 源码解读-从setContentView深入了解 Window|Activity|View❤️
2.android 开发中有一句super.onCreate(savedInstanceState)我
3.找到卡顿来源,源码BlockCanary源码精简分析
4.Jetpack学习之----ViewModel

oncreate()源码分析

❤️ Android 源码解读-从setContentView深入了解 Window|Activity|View❤️

       Android系统中,分析Window、源码Activity、分析View之间的源码关系是紧密相连且相互作用的。了解这三者之间的分析confluence的源码关系,有助于深入理解Android应用的源码渲染和交互机制。

       在Android中,分析通常在创建Activity时会调用`setContentView()`方法,源码以指定显示的分析布局资源。这个方法主要作用是源码将指定的布局添加到一个名为`DecorView`的容器中,并最终将其显示在屏幕上。分析这一过程涉及到多个组件的源码交互,下面分步骤解析。分析

       在`Activity`类中,源码`setContentView()`方法调用`getWindow()`方法获取`Window`对象,而`Window`对象在`Activity`的`attach()`方法中被初始化。`Window`对象是spring 3 企业应用开发实战 源码一个抽象类,其默认实现为`PhoneWindow`,这是Android特定的窗口实现。

       `PhoneWindow`在创建时会通过`setWindowManager()`方法与`WindowManager`进行关联。`WindowManager`是系统级组件,用于管理所有的窗口,包括窗口的创建、更新、删除等操作。`WindowManager`的管理最终由`WindowManagerService`(WMS)执行,这是一个运行在系统进程中的服务。

       在`PhoneWindow`中,`installDecor()`方法会初始化`DecorView`和`mContentParent`。`mContentParent`是一个`ViewGroup`,用于存放`setContentView()`传入的布局。通过`mLayoutInflater`的`inflate()`方法,将指定的布局资源添加到`mContentParent`中。

       `DecorView`是cocos2d-x游戏源码一个特殊的`FrameLayout`,包含了`mContentParent`。在完成布局的添加后,`DecorView`本身并没有直接与`Activity`建立联系,也没有被绘制到屏幕上显示。`DecorView`的绘制和显示发生在`Activity`的`onResume()`方法执行后,这时`Activity`中的内容才真正可见。

       当`Activity`执行到`onCreate()`阶段时,其内容实际上并没有显示在屏幕上,直到执行到`onResume()`阶段,`Activity`的内容才被真正显示。这一过程涉及到`ActivityThread`中的`handleResumeActivity()`方法,该方法会调用`WindowManager`的`addView()`方法,将`DecorView`添加到`WindowManagerService`中,完成`DecorView`的绘制和显示。

       `WindowManagerService`通过`addView()`方法将`DecorView`添加到显示队列中,并且在添加过程中,会创建关键的unity3d 手机游戏源码`ViewRootImpl`对象,进一步管理`DecorView`的布局、测量和绘制。`ViewRootImpl`会调用`mWindowSession`的`addToDisplay()`方法,将`DecorView`添加到真正的显示队列中。

       `mWindowSession`是`WindowManagerGlobal`中的单例对象,其内部实际上是一个`IWindowSession`类型,通过`AIDL`接口与系统进程中的`Session`对象进行通信,最终实现`DecorView`的添加和显示。

       通过`setView()`方法的实现,可以看到除了调用`IWindowSession`进行跨进程添加`View`之外,还会设置输入事件处理。当触屏事件发生时,这些事件首先通过驱动层的优化计算,通过`Socket`跨进程通知`Android Framework`层,最终触屏事件会通过输入管道传送到`DecorView`处理。

       在`DecorView`内部,触屏事件会通过`onProcess`方法传递给`mView`,android即时通讯的源码即`PhoneWindow`中的`DecorView`。最终,事件传递到`PhoneWindow`中的`View.java`实现的`dispatchPointerEvent()`方法,并调用`Window.Callback`的`dispatchTouchEvent(ev)`方法。对于`Activity`来说,`dispatchTouchEvent()`方法最终还是会调用`PhoneWindow`的`superDispatchTouchEvent()`,然后传递给`DecorView`的`superDispatchTouchEvent()`方法,完成事件的分发和处理。

       综上所述,通过`setContentView()`的过程,我们可以清晰地看到`Activity`、`Window`、`View`之间的交互关系。整个过程主要由`PhoneWindow`组件主导,而`Activity`主要负责提供要显示的布局资源,其与屏幕的直接交互则通过`WindowManager`和`WindowManagerService`实现。

android 开发中有一句super.onCreate(savedInstanceState)我

       你要是感兴趣你可以去看源码,学习阶段你不用知道为什么,你可以把super.onCreate(savedInstanceState)删除看看会有什么效果。绝B 会报错。 super.xxxxx错误,Activity fragment必须掉用 super

找到卡顿来源,BlockCanary源码精简分析

       通过屏幕渲染机制我们了解到,Android的屏幕渲染是通过vsync实现的。软件层将数据计算好后,放入缓冲区,硬件层从缓冲区读取数据绘制到屏幕上,渲染周期是ms,这让我们看到不断变化的画面。如果计算时间超过ms,就会出现卡顿现象,这通常发生在软件层,而不是硬件层。卡顿发生的原因在于软件层的计算时间需要小于ms,而计算的执行地点则在Handler中,具体来说是在UI的Handler中。Android进程间的交互通过Binder实现,线程间通信通过Handler。

       软件层在收到硬件层的vsync信号后,会在Java层向UI的Handler中投递一个消息,进行view数据的计算。这涉及到测量、布局和绘制,通常在`ViewRootImpl`的`performTraversals()`函数中实现。因此,view数据计算在UI的Handler中执行,如果有其他操作在此执行且耗时过长,则可能导致卡顿,我们需要找到并优化这些操作。

       要找到卡顿的原因,可以通过在消息处理前后记录时间,计算时间差,将这个差值与预设的卡顿阈值比较。如果大于阈值,表示发生了卡顿,此时可以dump主线程堆栈并显示给开发者。实现这一功能的关键在于在Looper中设置日志打印类。通过`Looper.loop()`函数中的日志打印,我们可以插入自定义的Printer,并在消息执行前后计算时间差。另一种方法是在日志中添加前缀和后缀,根据这些标志判断时间点。

       BlockCanary是一个用于检测Android应用卡顿的工具,通过源码分析,我们可以了解到它的实现逻辑。要使用BlockCanary,首先需要定义一个继承`BlockCanaryContext`的类,并重写其中的关键方法。在应用的`onCreate()`方法中调用BlockCanary的安装方法即可。当卡顿发生时,BlockCanary会通知开发者,并在日志中显示卡顿信息。

       BlockCanary的核心逻辑包括安装、事件监控、堆栈和CPU信息的采集等。在事件发生时,会创建LooperMonitor,同时启动堆栈采样和CPU采样。当消息将要执行时,开始记录开始时间,执行完毕后停止记录,并计算执行时间。如果时间差超过预设阈值,表示发生了卡顿,并通过回调传递卡顿信息给开发者。

       堆栈和CPU信息的获取通过`AbstractSampler`类实现,它通过`post`一个`Runnable`来触发采样过程,循环调用`doSample()`函数。StackSampler和CpuSampler分别负责堆栈和CPU信息的采集,核心逻辑包括获取当前线程的堆栈信息和CPU速率,并将其保存。获取堆栈信息时,通过在`StackSampler`类中查找指定时间范围内的堆栈信息;获取CPU信息时,从`CpuSampler`类中解析`/proc/stat`和`/proc/mpid/stat`文件的CPU数据,并保存。

       总结而言,BlockCanary通过在消息处理前后记录时间差,检测卡顿情况,并通过堆栈和CPU信息提供详细的卡顿分析,帮助开发者定位和优化性能问题。

Jetpack学习之----ViewModel

        官方学习文档

        ViewModel就是存储页面相关的数据,并将这些数据和Activity、Fragment等有生命周期相关的组件相关联,赋予数据生命周期。

        特点:

        ViewModel的生命周期

        在viewModel对象创建时开始,一直到他所关联的界面控制器销毁时才销毁,这就说明了即使发生了横竖屏切换,界面相关的数据也是一直存在并且不受横竖屏切换的影响。

        通常我们是在Actvity的onCreate()方法中来创建ViewModel对象,该ViewModel对象会一直在内存中,直到这个Activity销毁时才释放资源。

        从上面ViewModel的工作原理可以得知:

        1、ViewModel 一旦创建好了,就会一直保存到当前界面控制器(Activity 、Fragment等)销毁时才会释放资源;

        2、不同的界面控制器,ViewModel 的对象时存在不同的Hashmap中的,他们也是不同的对象;局部单例;

        3、要做到全局单例ViewModel对象,可以将ViewModel放到Application中去;

        接下来从源码角度来分析一下原理:

        在构建Activity的对象时,在其父类ComponentActivity.java中实现了接口ViewModelStoreOwner,在其实现方法中生成ViewModelStore对象

        在界面控制器的构造函数中,就添加了对生命周期的观察者,而当观察者收到当前的界面控制器的生命周期是Lifecycle.Event.ON_DESTROY时,就会将mViewModelStore对象map中所有保存的viewModel清理掉,这样来达到释放资源。

        这里只处理了ON_DESTROY的生命周期状态,那么也就说明了在ViewModel对象实例创建成功后,不管界面控制器(如Activity)的生命周期(除ON_DESTROY外)如何发生变化,ViewModel都不会被清理掉。

        从这里看出来ViewModel对应key的唯一性

        ViewModel工作原理的核心技术点:

        观察者模式、工程模式、反射、Hashmap数据结构

        ViewModel在MVVM架构模型中,与DataBinding结合使用,会让你有起飞的感觉。后续会进一步加深使用。本篇仅以学会使用、了解原理为重点。

copyright © 2016 powered by 皮皮网   sitemap