1.Android 面试知识点记录——Rxjava与协程
2.@Compose 注解到底做了什么?了解一下~
3.深入解析Android Lifecycle;从基本使用到源码实现,码解全面掌握生命周期管理
4.Android Media3 (一)— 简单播放视频
5.坑爹的码解shadow -- 总结 与 各种坑
6.Jetpack ComposeBOM是什么?
Android 面试知识点记录——Rxjava与协程
作者:浪人笔记
RxJava协程与操作符
在RxJava中,map操作符实现简单,码解它在原有Observable的码解基础上添加MapObservable观察者,将变换函数作为参数传递。码解MapObservable的码解小程序地址源码onNext方法接收元素,传递给变换函数进行变换,码解结果作为新元素发射。码解
而flatMap操作符实现相对复杂。码解它在原有Observable上添加FlatMapObservable观察者,码解并将变换函数作为参数传递。码解FlatMapObservable的码解onNext方法接收元素,传递给变换函数得到新Observable,码解注册到FlatMapSubscriber中等待下一次数据。码解数据处理完成后,码解调用FlatMapSubscriber的onComplete方法,合并所有得到的Observable成新Observable发射。
RxJava1.0与2.0区别
RxJava2.0在异常处理、背压支持、线程调度和性能等方面改进和提升。
背压概念与解决方案
背压是指数据产生速度大于消费速度,导致内存溢出等问题。RxJava1.x没有背压支持,使用onBackpressureBuffer、onBackpressureDrop缓解,而RxJava2.0引入Flowable支持背压,提供更多背压控制策略。
Flowable类型支持背压,通过onBackpressureBuffer、onBackpressureDrop、onBackpressureLatest等方法处理背压问题。Flowable方式类似Observable,使用时需指定背压策略。
subscribeOn与observeOn
subscribeOn只影响第一次指定的线程,后续操作不影响。subscribeOn理解为管道入口,observeOn理解为出口,数据处理后出口策略可变。
RxJava数据流回主线程
使用observeOn(AndroidSchedulers.mainThread()),动漫明星大战源码内部实现为Handler(Looper.getMainLooper())。
协程、进程、线程、协程区别
Kotlin协程基于挂起函数实现,不依赖操作系统和编译器,实现协程效果。
处理回调地狱与协程
协程通过挂起函数减少回调嵌套,提高代码可读性。使用withContext指定协程执行上下文,避免主线程阻塞。
开发中选择调度器
通常选择主线程、IO密集型和CPU密集型调度器,对应Kotlin协程中的上下文。
Android核心知识点记录
包含性能优化、车载技术、Framework底层原理、音视频开发、Jetpack全家桶、Kotlin、Gradle、OkHttp源码解析、Flutter等主题,涵盖Android开发者必备知识。
Android面试题集锦
整理多年面试题集,包括Android基础知识、性能优化、音视频、Jetpack全家桶、Kotlin、Gradle、OkHttp源码解析等内容,为开发者提供面试准备。
Android音视频面试题集
聚焦于Android音视频开发的关键问题,帮助开发者深入理解音视频技术。
@Compose 注解到底做了什么?了解一下~
理解@Compose注解背后的运作机制
在深入探讨@Compose注解的用途之前,需要了解一点,即@Compose注解的hive源码 查询修改解析并非由注解处理器实现,而是通过Kotlin编译插件(KCP)来完成。相较于注解处理器,KCP具备生成和修改代码的能力,这使得@Compose注解解析成为可能。
简要回顾KCP,它在编译过程中提供了一个关键的钩子,允许开发者解析符号并修改生成的字节码,Kotlin库中使用KCP实现的语法糖包括Kotlin-android-extension、@Parcelize等,而@Compose注解同样通过KCP解析。
KCP相比KAPT的优点主要在于其灵活性和功能强大性,但同时也带来了较高的开发成本,需要熟悉Gradle Plugin、Kotlin Plugin等工具以及编译器知识。在仅需处理注解生成代码的场景下,KSP(Kotlin Symbol Processing)是一个更合适的选择。
深入解析@Compose注解的实现
在Jetpack Compose中,@Compose注解的解析流程主要通过注册IrGenerationExtension来完成。通过注入$composer参数,@Compose注解有效地在所有Compose函数中引入了一种机制,使得Composer能够用于任何子树,从而实现构建和更新Composable树所需的所有信息。
为了支持智能重组机制,编译器还注入了$changed参数,用于判断组件的输入参数是否发生变化。通过位运算的方式表示参数状态,$changed参数确保了在输入相同的情况下,组件能够避免不必要的重组。
同样,$default参数用于指示参数是否使用默认值,进一步扩展了组件的灵活性。这些参数的注入,为Compose框架提供了一种高效、智能的实现方式,使得开发者只需添加一个@Compose注解,就能将普通函数转化为强大的Compose函数。
总结KCP与@Compose注解的运用
通过理解KCP的运作机制和@Compose注解的实现细节,可以发现KCP的jfinal handler源码解析强大功能以及其在简化复杂编译过程中的关键作用。对于需要解析注解生成代码的场景,KSP是一个更为合适的工具。然而,对于需要更多定制化功能的开发者,KCP提供了更灵活和强大的选择。在使用@Compose注解时,背后的复杂逻辑被巧妙隐藏,使得开发者能够专注于构建高效、可维护的组件,而无需深入理解底层实现细节。对于对源码感兴趣或寻求更深入理解的开发者,查阅源码是一个值得推荐的途径。
深入解析Android Lifecycle;从基本使用到源码实现,全面掌握生命周期管理
深入理解Android应用的生命周期管理,Lifecycle在Android Jetpack中发挥着核心作用。它帮助开发者对Activity和Fragment等组件的生命周期进行精确控制,通过一系列事件如Lifecycle.Event(如onCreate、onStart等)来执行相应的操作。
生命周期管理的关键在于LifecycleOwner(如Activity和Fragment)与LifecycleObserver的交互。前者是生命周期的主体,后者则是监听和响应这些事件的组件。开发者可以通过实现LifecycleObserver接口,注册回调方法,当组件状态改变时,这些方法会被自动调用。
在代码层面,Lifecycle的基本实现涉及Lifecycle接口、LifecycleRegistry和LifecycleObserver接口的使用。例如,创建LifecycleRegistry实例并添加观察者,当组件状态变化时,handleEvent方法会处理并通知观察者。源码分析深入Android Framework,揭示了LifecycleRegistry类及其实现细节,如LifecycleRegistry类中包含的关键类和方法,确保了生命周期管理的有序和准确性。
总之, Lifecycle是jquery bind事件源码Android应用开发中的重要工具,它简化了组件生命周期的管理,提高了代码的可维护性和应用的稳定性。深入理解并有效利用Lifecycle,是构建高效高质量Android应用不可或缺的一部分。
Android Media3 (一)— 简单播放视频
在Android应用开发中,有时需要集成视频播放功能,JetPack Media3作为官方推荐的视频播放解决方案,以ExoPlayer为核心,极大地简化了开发者的工作。本文将引导你快速入门Media3,实现视频播放。
首先,要在项目中引入Media3库。在app模块的build.gradle文件中,添加以下依赖代码:
// ...其他依赖
implementation 'com.google.android.exoplayer:exoplayer:2..1' // 请根据最新版本替换
implementation 'com.google.android.exoplayer:exoplayer-ui:2..1' // 用于PlayerView
在布局文件中,引入PlayerView,它是视频播放的核心容器:
<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="dp"
android:background="@android:color/black"
/>
你可以根据需要调整PlayerView的一些参数,比如封面、控制器样式等。具体配置可以参考官方文档。
接下来,创建一个ExoPlayer实例,并将其关联到PlayerView上,加载你想要播放的视频资源:
Player player = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(context));
PlayerView playerView = findViewById(R.id.player_view);
playerView.setPlayer(player);
// 设置播放资源,例如通过MediaSource
MediaSource mediaSource = ...;
player.prepare(mediaSource);
player.setPlayWhenReady(true);
运行程序,你将看到视频播放效果。为了更直观的学习,示例代码已在名为ExampleDemo的项目中提供。你可以从GitHub或Gitee上获取源码:
- 示例Demo GitHub: [链接]
- 示例Demo Gitee: [链接]
通过以上步骤,你已经掌握了使用Media3库进行视频播放的基础。后续可以探索更多高级功能,如视频缓存、播放控制等。祝你在视频播放开发中顺利!
坑爹的shadow -- 总结 与 各种坑
Android开发者的阴影之痛
面对新UX总监在设计中大量添加阴影,尤其是多层阴影时,Android开发者们陷入了困境。因为Android平台不直接支持复杂的阴影效果,即使采用折中的方法,自行实现阴影功能也面临诸多挑战,如模糊效果(blur)的实现需要较为复杂的操作,这在Android开发中并不常见。
在实际开发中,Android对阴影的支持有限。对于文字阴影,部分TextView支持,但模糊效果不兼容。Android在5.0版本引入Material Design时,开始支持阴影功能,但其理论体系与设计软件如Figma中的阴影参数存在差异,更接近光照系统模型。理解这种理论体系对于开发者来说是一个挑战。
在Android 5.0之后的版本中,阴影系统引入了三个关键概念:ambient shadow、spot shadow以及elevation。这些概念与现实世界中的阴影形成原理相呼应,但实际应用中,开发者需要处理各种阴影设置的坑点。
例如,在实现阴影时,开发者需要确保View有背景,无论是颜色还是,以生成阴影效果。同时,背景不能是SVG形成的XML文件,否则Android无法生成阴影。此外,阴影的实现还需要额外的空间来确保不会被截断,尤其是在嵌套布局中。
在阴影设置过程中,开发者经常遇到的问题包括:即使设置了elevation值,仍然没有阴影效果;下载的素材作为背景时,阴影效果依然不明显;在特定布局中,阴影可能会被截断等。
解决这些坑点需要深入理解Android中阴影生成的机制,尤其是在outline provider的作用下,View的阴影效果与背景紧密相关。通过调整View的outline provider、背景以及elevation值,可以实现自定义阴影形状和效果。
除了阴影设置的技巧,开发者还需关注Android学习资源的多样性和深入性,包括性能优化、车载开发、逆向安全、底层原理、音视频处理、Jetpack全家桶、Kotlin、Gradle、OkHttp源码解析以及Flutter等领域的知识。这些资源对于提升Android开发技能、解决实际开发中遇到的问题具有重要意义。
Jetpack ComposeBOM是什么?
本篇旨在帮助小伙伴们了解并运用Compose中的BOM(Bill Of Materials)相关知识,以在Compose开发过程中更便捷、统一地管理依赖信息。
BOM基础知识
Compose推出的BOM,全称为物料清单,旨在通过指定BOM版本来管理所有Compose库版本。在未使用BOM的情况下,开发者需手动查找并添加特定版本的依赖。而使用BOM后,开发者只需在dependencies{ }中添加所需库,Gradle便会自动选择对应的版本。BOM于年月日首次发布,至今已推出个版本,最新版本为..。
使用ComposeBOM
在AS创建的Compose项目中,通常会默认添加BOM依赖,但版本可能较旧。通过在app/build.gradle中添加特定版本的BOM,如..,开发者可以确保引入的库版本与BOM保持一致。引入依赖时,无需指定版本号,Gradle会自动匹配BOM中的对应版本,如compose.ui在BOM ..下的版本为1.4.0。
值得注意的是,即使添加了BOM依赖,仍需显式添加所需的库,版本号可通过BOM获取。如果只添加BOM,而未明确指定其他库版本,可能导致资源浪费。
BOM与显式添加版本号是否冲突
在使用BOM的同时,若显式添加其他依赖并指定版本号,Gradle会优先采用显式声明的版本号。例如,添加compose.ui:1.5.3依赖,即使BOM中对应版本为1.4.0,实际引入版本将为1.5.3。这确保了依赖版本的灵活性与统一性。
BOM版本映射关系
列出BOM从首个版本至最新版本的映射关系,以便开发者查阅和参考。如需更新BOM版本,将相应更新映射表。
总结
BOM简化了依赖管理,易于上手,极大便利了Compose相关依赖的统一管理。有兴趣的开发者不妨尝试应用BOM,提升开发效率。
额外资源
整理了一系列Android学习资源,包括性能优化、框架原理、车载开发、逆向安全、音视频处理、Jetpack全家桶、OkHttp源码解析、Kotlin、Gradle、Flutter等,覆盖Android开发多个方面,适合不同阶段的开发者学习参考。
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ç»å使ç¨ï¼ä¼è®©ä½ æèµ·é£çæè§ãåç»ä¼è¿ä¸æ¥å 深使ç¨ãæ¬ç¯ä» 以å¦ä¼ä½¿ç¨ãäºè§£åç为éç¹ã
基于JetPack离线安装torch和编译安装torchvision(arm架构)
在搭建基于arm架构的AI服务过程中,我遇到了一些挑战并记录了相关步骤。首先,针对JetPack 5.1环境,需要从官网下载预先编译的torch离线包,适应Python3.8版本,并确保torch与torchvision版本对应。下载后的文件看起来是这样的:
离线文件下载后:
接着,将文件传至服务器,通过命令行安装,这里使用百度pip源加速依赖包的下载:
安装命令:
安装成功后,继续下载torchvision源码,例如0..0版本,解压并准备安装Pillow,因为torchvision需要它:
下载vision-0..0版本:
安装Pillow:
如果Pillow缺失,需要先安装。接下来,编译安装torchvision:
进入vision-0..0目录并编译安装:
这一步需要一些时间。为避免频繁编译,我们可以将源码转换为whl文件,便于后续快速安装:
源码转whl:
转换后的whl文件:
最后,你可以在dist文件夹中找到转换好的whl文件`torchvision-0..0-cp-cp-linux_aarch.whl`,将其保存备用,以备后续使用。这样,通过这些步骤,你就能在arm架构服务器上离线安装并编译torch和torchvision了。
Android 启动优化: JetPack App Startup 使用及源码浅析
前言 本文将深入探讨 JetPack App Startup 的使用及源码浅析,以解决 Android 应用启动优化问题。让我们一起探讨 JetPack App Startup 如何简化初始化流程,提升应用启动速度。 目录 1. 什么是 JetPack App Startup? 2. JetPack App Startup 解决什么问题? 3. JetPack App Startup 的基本使用 4. JetPack App Startup 的进阶使用 5. JetPack App Startup 源码浅析 6. 小结 什么是 JetPack App Startup? JetPack App Startup 是一个为应用启动提供简洁高效初始化方案的库,适用于库开发者和应用开发者。通过集成 App Startup,开发者可以简化启动序列,明确初始化顺序,减少初始化步骤。相较于单独定义 ContentProvider 供每个组件初始化,App Startup 允许开发者定义共享一个 ContentProvider 的组件初始化器,显著提升应用启动时间。 JetPack App Startup 解决什么问题? 理解 App Startup 的实际应用,有助于我们解决 Android 应用启动时间长的问题。Android 启动流程包括 Application#attachBaseContext、ContentProvider#onCreate、Application#onCreate 及 MainActivity#onCreate 等步骤。App Startup 旨在集中管理 ContentProvider 初始化,减少不必要的初始化操作,优化启动性能。 基本使用 使用 App Startup 分为三步: 在 build.gradle 文件中添加依赖。 自定义实现 Initializer 类。 在 AndroidManifest 中配置自定义的 InitializationProvider。 进阶使用 App Startup 提供了灵活的初始化机制,允许开发者在特定时机执行初始化操作,而非仅在 Application onCreate 之前。这为开发者提供了更多自定义空间。 源码浅析 App Startup 的核心结构包括几个关键类:Initializer 接口和 InitializationProvider 类。Initializer 定义了初始化的基本操作,而 InitializationProvider 借助 ContentProvider 的特性,在应用启动之前执行初始化任务。 小结 本文分享了 JetPack App Startup 的使用方法及源码分析,提供了优化应用启动速度的实用技巧。我们还提供了一份包含 Android 学习资源的资料包,包括架构视频、面试文档及源码笔记,旨在帮助开发者深入理解高级架构知识。如果你对本文内容感兴趣,欢迎点赞、评论或转发支持。