- 博客(66)
- 收藏
- 关注
翻译 【译】Jetpack Compose 稳定性说明
在讨论稳定性之前,让我们快速回顾一下重组“重组是当输入发生变化时再次调用可组合函数的过程。当函数的输入发生变化时,就会发生这种情况。当 Compose 根据新输入进行重组时,它仅调用可能已更改的函数或 lambda,并跳过其余部分。通过跳过所有未更改参数的函数或 lambda,Compose 可以高效地进行重组。注意那里的关键词——“可能”。当快照状态发生变化时,Compose 将触发重组,并跳过任何未更改的可组合项。重要的是,只有当 Compose 可以确保可组合项的任何参数均未更新时,才会跳过可组合项。
2024-01-02 18:11:21
121
翻译 【译】Jetpack Compose State 指南
什么是 State?“所有的值都可能随着时间的推移而改变”。我介绍了 Jetpack Compose 中管理状态的 9 条准则。如何使用 Jetpack Compose 来管理状态。您需要了解 Jetpack Compose 才能正确运行它。基本思想是单一事实来源和关注点分离。即使在 Compose 之外了解它们也可能很有用。如果您有任何反馈,请告诉我。我想修改一下这篇文章。
2023-12-28 15:07:09
267
翻译 [译] App Startup 使用介绍
官方文档:https://developer.android.com/topic/libraries/app-startup文章目录配置在应用启动时初始化组件实现组件初始化器设置清单条目运行 lint 检查手动初始化组件禁用单个组件的自动初始化禁用所有组件的自动初始化手动调用组件初始化器App Startup 库提供了一种在应用程序启动时初始化组件的简单、高效的方法。库开发人员和应用程序开发人员都可以使用 App Startup 来简化启动顺序并明确设置初始化顺序。App Startup 允许您定义共
2022-05-09 15:07:11
571
转载 [转] 感受异或的神奇
原文:感受异或的神奇 - 金马的Blog什么是异或?Wikipedia的解释:在逻辑学中,逻辑算符异或(exclusive or)是对两个运算元的一种逻辑析取类型,符号为 XOR 或 EOR 或 ⊕(编程语言中常用^)。但与一般的逻辑或不同,异或算符的值为真仅当两个运算元中恰有一个的值为真,而另外一个的值为非真。转化为命题,就是:“两者的值不同。”或“有且仅有一个为真。”定义:1 ⊕ 1 = 00 ⊕ 0 = 01 ⊕ 0 = 10 ⊕ 1 = 1真值表:
2022-04-24 16:54:49
245
转载 [转] Android Miracast投屏入门
原文:https://www.codetd.com/article/12138544哇,打开新世界了。SOS……遇到问题查看资料,中英文该看的都不落下。官配1. AOSP源码:Miracast Sink端源码最早出现在Android 4.2.2上,通过googlesource可以很方便的查看:https://android.googlesource.com/platform/frameworks/av/+/android-4.2.2_r1.2/media/libstagefright/wifi-d
2022-04-11 11:15:52
1870
1
原创 Android 基于 DroidAssist 插件实现无埋点
DroidAssistDroidAssist (源码) 是一个轻量级的 Android 字节码编辑插件,基于 Javassist 对字节码操作,根据 xml 配置处理 class 文件,以达到对 class 文件进行动态修改的效果。和其他 AOP 方案不同,DroidAssist 提供了一种更加轻量,简单易用,无侵入,可配置化的字节码操作方式,你不需要 Java 字节码的相关知识,只需要在 Xml 插件配置中添加简单的 Java 代码即可实现类似 AOP 的功能,同时不需要引入其他额外的依赖。使用方式
2022-02-11 22:33:16
1701
原创 Android Gradle Transform 学习
build.gradle:plugins { id 'java' //id 'groovy' id 'org.jetbrains.kotlin.jvm' version '1.5.31' id 'java-gradle-plugin'}repositories { google() mavenCentral()}java { sourceCompatibility = JavaVersion.VERSION_1_8 targetC
2022-01-06 13:38:46
1500
1
原创 Android 12 SplashScreen 应用启动画面
从 Android 12 开始,在所有应用的冷启动和温启动期间,系统一律会应用 Android 系统的默认启动画面。默认情况下,此系统默认启动画面由应用的启动器图标元素和主题的 windowBackground(如果是单色)构成。注:实际测试发现如果 windowBackground 为一张图片,则会从这种图里提取出单色。假如有一个 SplashActivity 使用了这样的主题(img_splash_new 为一张有图片文字的图): <style name="Theme.SplashTe
2021-12-17 17:30:05
3764
翻译 [译]从 LiveData 迁移到 Kotlin Flow
原文:https://medium.com/androiddevelopers/migrating-from-livedata-to-kotlins-flow-379292f419fbLiveData 是我们在 2017 年需要的东西。观察者模式让我们的生活更轻松,但 RxJava 等选项在当时对于初学者来说太复杂了。 架构组件团队创建了 LiveData:一个非常固执的可观察数据持有者类,专为 Android 设计。 它保持简单以使其易于上手,并且建议将 RxJava 用于更复杂的反应式流案例,利用两者
2021-11-17 16:20:13
228
翻译 [译]关于 Flow 的 shareIn 和 stateIn 操作符的注意事项
原文:https://medium.com/androiddevelopers/things-to-know-about-flows-sharein-and-statein-operators-20e6ccb2bc74Flow.shareIn 和 Flow.stateIn 运算符将冷流转换为热流:它们可以将来自冷上游流的信息多播到多个收集器。 它们通常用于提高性能,在不存在收集器时添加缓冲区,甚至作为缓存机制。注意:冷流是按需创建的,并在被观察时发出数据。 热流始终处于活动状态,无论是否被观察到,都可
2021-11-15 18:39:47
363
翻译 [译]从 Android UI 收集流的更安全方法
原文:https://medium.com/androiddevelopers/a-safer-way-to-collect-flows-from-android-uis-23080b1f8bda在 Android 应用程序中,Kotlin 流通常从 UI 层收集以在屏幕上显示数据更新。但是,您希望收集这些流,以确保在视图转到后台时不会做多余的工作、浪费资源(CPU 和内存)或泄漏数据。在本文中,您将了解 Lifecycle.repeatOnLifecycle, 和 Flow.flowWithLifec
2021-11-15 16:54:03
241
原创 Android 图片处理工具类 ImageUtils
import android.annotation.SuppressLintimport android.graphics.Bitmapimport android.graphics.Bitmap.CompressFormatimport android.graphics.Bitmap.CompressFormat.JPEGimport android.graphics.BitmapFactoryimport android.graphics.Matriximport android.net.U
2021-09-30 16:11:01
460
原创 支持可选择编码可读取大型文本的 TextFileReader
最开始只用 RandomAccessFile 读取每一行,但发现读取太慢了,因为每次都是从磁盘里读取。然后想到了用 MappedByteBuffer 再进行一次内存映射,可以显著提升读取速度。但如果原文件太大了的话,还得进行分块映射处理,要不然会 OOM。最后又发现读取某些文本文件时会出现乱码,原因是 RandomAccessFile 是用 ISO-8859-1 编码,而 ByteBuffer.getChar() 又是用 UTF-16 编码。无奈只能用 Charset.decode(inByteBuf
2021-08-29 12:10:39
461
原创 如何在 Android 进程内通过 Bundle 传递 functional interface 实例
假如我们要在 Bundle 中传递一个实现了 functional interface 的实例,我们可以这样扩展或者定义一个接口:interface Parser<E> : Parcelable where E : Enum<E>, E : LogParser<E> { fun parseLine(line: String): CharSequence}这个接口的泛型参数 E 定义的很巧妙:首先,E : Parser<E>,这是一个自限定类型
2021-08-29 11:37:59
383
翻译 [译] Realm 修改对象模式 - Android SDK
原文:https://docs.mongodb.com/realm/sdk/android/examples/modify-an-object-schema文章目录添加属性删除属性修改属性类型或重命名属性迁移函数以下示例演示了如何在模式中添加、删除和修改属性。首先,进行所需的模式更改。然后,创建相应的迁移函数,将数据从原始模式移动到更新后的模式。使用模式版本的领域0具有Person对象类型:class Person: RealmObject { // Realm schema version 0
2021-07-05 22:22:46
267
翻译 [译] Realm 对象模型和模式 - Android SDK
原文:https://docs.mongodb.com/realm/sdk/android/fundamentals/object-models-and-schemas文章目录Realm 应用程序主键Optionality 可选择性Relationships 关系Indexes 索引Modules 模块Realm 对象RealmProxyRealm 对象限制增量构建总结一个对象模式是一个配置对象,它定义了一个 Realm 对象类型的的字段和关系。Android Realm 应用程序通过使用 Java 或
2021-07-05 22:04:48
371
翻译 [译] 定义 Realm 对象模式 - Android SDK
小费有关模式的概念信息以及有关类型和约束的详细信息,请参阅基础:对象模型和模式。定义一个领域对象要在您的应用程序中定义 Realm 对象,请创建RealmObject的子类 或实现RealmModel。重要的所有 Realm 对象都必须提供一个空的构造函数。扩展RealmObject例子以下代码块显示了一个描述青蛙的 Realm 对象。这个 Frog 类可以存储在 Realm 数据库中,因为它extends是RealmObject类。科特林爪哇import io.realm.Realm
2021-07-05 18:07:19
156
翻译 [译] Kotlin 协程异常处理
原文:https://github.com/Kotlin/kotlinx.coroutines/blob/master/docs/topics/exception-handling.md文章目录异常传播协程异常处理器 CoroutineExceptionHandler本节介绍异常处理和在异常时取消。我们已经知道取消的协程会在挂起点抛出 CancellationException 并且它会被协程的机制忽略。这里我们看看如果在取消过程中抛出异常或者同一个协程的多个子协程抛出异常会发生什么。异常传播协程构
2021-06-24 16:02:47
1131
1
翻译 [译] 协程中的取消和异常(第 3 部分)- 协程中的异常
原文:https://medium.com/androiddevelopers/exceptions-in-coroutines-ce8da1ec060c文章目录一个协程突然失败了!现在怎么办?????SupervisorJob 来拯救*???? 无论你使用哪种 Job,未捕获的异常都会被抛出*Job 还是 SupervisorJob?????当心测验!谁是我的父母?????了解幕后处理异常????????Launch*使用 launch,异常将在发生时立即抛出*Async*当 async 用作根协程时
2021-06-17 18:21:16
239
翻译 [译] 协程中的取消和异常(第 2 部分)- 协程中的取消
在开发中,就像在生活中一样,我们知道避免做多余的工作很重要,因为这会浪费内存和精力。这个原则也适用于协程。您需要确保控制协程的生命周期,并在不再需要时将其取消——这就是结构化并发所代表的含义。继续阅读以了解协程取消的来龙去脉。调用取消启动多个协程时,跟踪它们或单独取消每个协程可能会很痛苦。相反,我们可以依靠取消启动协程的整个 scope,因为这将取消它所有创建的子协程:// assume we have a scope defined for this layer of the appval job
2021-06-17 16:19:35
615
翻译 [译] 协程中的取消和异常(第 1 部分)- 协程:第一件事
原文:https://medium.com/androiddevelopers/coroutines-first-things-first-e6187bf3bb21本系列博客文章深入探讨了协程中的取消和异常。取消对于避免做多余的工作很重要,这会浪费内存和电量;正确的异常处理是良好用户体验的关键。作为本系列其他 3 部分(第 2 部分:取消,第 3 部分:异常,第 4 部分:不应取消的工作的协程和模式)的基础,定义一些核心协程概念非常重要,例如 CoroutineScope, Job 和 Coroutine
2021-06-17 15:08:33
154
翻译 [译] Realm 的使用入门
一、初始化Realm必须先初始化 Realm 库,然后才能在应用程序中使用 Realm。您的应用程序每次运行时都应该仅初始化一次 Realm。要初始化 Realm 库,请将 Android context 提供给 Realm.init() static 函数。您可以提供一个 Activity,Fragment 或 Application context 进行初始化,而在行为上没有差异。您可以在 Application子类 的 onCreate() 方法中初始化 Realm 库,以确保每次应用程序运行时仅
2021-06-16 16:57:45
878
原创 Kotlin 协程三类 Continuation
协程有三层 Continuation 包装,通过代理模式将协程的各层包装组合在一起,每层负责不同的功能。第一层 Continuation 包装是 CoroutineScope.launch() 和 CoroutineScope.async() 方法分别返回的 Job、Deferred,里面封装了协程状态,提供了取消协程的接口,它们所属的类(StandaloneCoroutine、DeferredCoroutine)都是继承自 AbstractCoroutine,而 AbstractCoroutine 实现
2021-06-15 17:41:05
773
1
原创 Kotlin 协程四类 Dispatcher
Default: 默认情况下,此调度器使用的最大并行数等于 CPU 内核数,但至少为 2。 并行度 X 保证在这个调度器中并行执行的任务不超过 X 个。Main: 不管是否已经在 main 线程中,都将会 Handler.post(block) 执行Main.immediate:如果已经在 main 线程中,将立即执行,否则将会 Handler.post(block) 执行override fun isDispatchNeeded(context: CoroutineContext): Boolean
2021-06-14 22:44:28
746
原创 Kotlin 异步回调转为协程
suspendCoroutine() 方法 和 suspendCancellableCoroutine() 方法都可以将异步转为协程。通过 continuation.resume() 传递结果,continuation.resumeWithException() 传递异常。public suspend inline fun <T> suspendCoroutine(crossinline block: (Continuation<T>) -> Unit): T {
2021-06-14 22:15:52
1016
原创 以 Retrofit suspend 方法举例解析 Kotlin 协程原理
前置条件:一个 Retrofit API 接口 VideoApi,其方法是 suspend 方法。interface VideoApi { @GET("https://live.{env}.shopee.{cid}/api/v1/homepage/replay") suspend fun getVideoList( @Path("env") env: String = EnvConstants.NETWORK_ENV, @Path("cid") cid:
2021-06-14 13:33:35
1535
1
翻译 [译] Kotlin Flow 官方 Guide 指南(2021-06-13)翻译
原文链接:https://github.com/Kotlin/kotlinx.coroutines/blob/master/docs/topics/flow.mdFlows are coldflow 构建器中的代码在收集流之前不会运行fun simple(): Flow<Int> = flow { println("Flow started") for (i in 1..3) { delay(100) emit(i) }}fun
2021-06-13 17:16:24
463
原创 Kotlin suspend fun 会编译成什么样的代码?
对于这样的 suspend funfun foo(p1 : P1, ..., pn : Pn) : R其编译期生成的代码类似这样: @Nullable public Object foo(P1 p1, ..., Pn pn, @NotNull Continuation continuation) { class LocalContinuationImpl extends kotlin.coroutines.jvm.internal.ContinuationImpl {
2021-06-11 02:17:41
769
1
原创 Kotlin suspend lambda 会编译成什么样的代码?
对于这样的 suspend lambdasuspend (p1 : P1, ..., pn : Pn) -> R其编译期生成的代码如下:public class SuspendLambdaBlock<P1, ..., Pn, R> extends kotlin.coroutines.jvm.internal.SuspendLambda implements FunctionN<P1, ..., Pn, Continuation<? super R>
2021-06-11 01:18:51
561
原创 Kotlin 协程的一些内部实现函数
public suspend inline fun <T> suspendCoroutineUninterceptedOrReturn(crossinline block: (Continuation<T>) -> Any?): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } throw NotImplementedError("Implementation of suspend
2021-06-10 19:23:55
226
原创 Kotlin Flow buffer 的使用
public fun <T> Flow<T>.buffer(capacity: Int = BUFFERED, onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND): Flow<T> { ...}缓冲区通过指定容量的通道发射,并在单独的协程中运行收集器。通常,流是顺序的。这意味着所有运算符的代码都在同一个协程中执行。例如,考虑以下使用 onEach 和 collect 运算符的代码:flow
2021-06-07 18:25:59
1496
3
翻译 [译] Kotlin 协程 Flow 官方文档(2021-2-4)翻译
原文:https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/Flow (流)interfaceFlow<outT>(source)异步数据流,它顺序地发出值并正常或异常地完成。流的中间运算符(例如 map, filter, take, zip 等)是应用于一个或多个上游流并返回下游流(可以在其中应用其他运算符)的函数。中间运算符...
2021-02-04 19:58:16
772
原创 OkHttp CookieJar 简单序列化存取
先将将 List<Cookie> 保存到实现了Serializable接口的CookieSerialize类的实例中,然后通过 Java 序列化机制保存到磁盘里,通过 Java 反序列化机制从磁盘里读取出来。一个 host 的 cookie 对应一个序列化文件。需要自己实现 hostStringToFileName 方法,即 host 字符串转化为文件名的规则。import android.app.Application;import android.content.Context;i
2021-01-27 11:38:37
789
原创 RecyclerView支持单选复选的容器实现ButtonGroupRecyclerView
先上图和视频看效果: 屏幕录制2021-01-25 08.51.42 谷歌已经提供了 MaterialButtonToggleGroup, 但是 MaterialButtonToggleGroup 是继承 LinearLayout 的,并且没有增加子View排列的的属性定义,说明只支持线性排列,不能满足需要多行排列的需求。无奈自己仿写了 MaterialButtonToggleGro
2021-01-25 09:40:24
192
转载 [转] 算法数据结构可视化网站
https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
2021-01-10 19:02:36
79
原创 Android byte 数组转 String
不知道什么原因,Android 的 String.java 的好多方法不能使用,抛出这样的异常:throw new UnsupportedOperationException("Use StringFactory instead.");但是呢,StringFactory.java 这个类却又是 @hide,无法直接调用,无奈拷贝出其中的方法,拎出来使用:import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.ch
2020-07-04 01:03:15
4472
原创 Java byte 数组与 int long 互转
public static void intToByteArray(int intValue, byte[] bytes) { bytes[0] = (byte) ((intValue >> 24) & 0xFF); bytes[1] = (byte) ((intValue >> 16) & 0xFF); bytes[2] = (byte) ((intValue >> 8) & 0xFF);...
2020-07-04 00:59:09
388
翻译 [译] Android MediaCodec 官方文档(2020-6-12)翻译
原文:https://developer.android.google.cn/reference/android/media/MediaCodecMediaCodec类可用于访问低级媒体编解码器,即编码器/解码器组件。 它是Android低级多媒体支持基础结构的一部分(通常与 MediaExtractor, MediaSync, MediaMuxer, MediaCrypto, MediaDrm, Image, Surface, 和 AudioTrack 一起使用)。广义而言,编解码..
2020-06-11 16:14:54
1011
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人