Android 开发
文章平均质量分 89
okclouderx
这个作者很懒,什么都没留下…
展开
-
Kotlin的协程:flow
之前介绍的启动协程方法,比如 launch、async 都是协程的单次启动。如果有复杂场景,比如发送多个数据,就需要使用 flow 数据流。在 flow 中,数据如水流一样经过上游发送,中间站处理,下游接收。flow 是 kotlin 提供的解决复杂异步场景的方案。flow 由创建、中间操作符、终止操作符三个部分组成。flow 的生命周期可以分为 onStart 和 onComplete,与它们在 flow 的位置无关。flow 的异常处理使用 catch。catch 与位置相关。原创 2022-10-19 17:34:35 · 1238 阅读 · 0 评论 -
Android Jetpack Compose介绍
Jetpack Compose 是用于构建原生 Android 界面的新工具包。它使用更少的代码、强大的工具和直观的 Kotlin API,可以帮助您简化并加快 Android 界面开发。2019年5月,Google在I/O大会上公布Compose2020年9月,发布第一个Alpha版本2021年7月,发布第一个稳定版本参数指定默认值。函数参数很多时,可以分为必选参数和可选参数。命名参数可以不按照顺序传参。举例:文本控件只需要传入文字是什么。Text API定义2.2 高阶函数参数是函数的函数原创 2022-07-08 00:16:16 · 877 阅读 · 0 评论 -
Kotlin的协程:上下文
Kotlin 的协程上下文叫做 CoroutineContext,通常用来切换线程池。launch 的第一个参数 context 是 CoroutineContext,默认值是 EmptyCoroutineContext。如果需要指定 launch 工作的线程池,就需要指定 CoroutineContext 参数。withContextwithContext 用来切换线程执行代码。它的第一个参数是 CoroutineContext,指定线程池。在 getUserInfoIo 中指定 withConte原创 2022-06-30 19:09:13 · 1062 阅读 · 0 评论 -
Kotlin的泛型:协变与逆变
Kotlin 的协变与逆变统称为 Kotlin 的变型。变型是指泛型的基础类型与它的参数类型是如何关联的。对于普通类型来说,我们可以使用子类代替父类,因为子类包含了父类的全部内容。但是对于泛型来说,如果泛型的基础类型相同,其中一个参数类型是另外一个参数类型的子类,泛型类也不存在这种继承关系,无法直接替换使用。要解除这些限制,就需要用到协变与逆变。变型变型的存在是为了解决函数的泛型参数传递问题。下面的代码中,printContents 接收 List 的参数,然后把 list 中的每个元素拼接成 St原创 2022-03-13 01:25:06 · 945 阅读 · 0 评论 -
Android ActivityResult 介绍
Android ActivityResult 介绍ActivityResult API 是 androidx.activity:activity 包引入的新 API,用来替代原有的 onActivityResult 获取上一个 Activity 返回的结果。被废弃的 startActivityForResult 和 onActivityResultstartActivityForResult从 ComponentActivity 的 startActivityForResult 方法 @Deprec原创 2021-11-17 12:40:15 · 4533 阅读 · 0 评论 -
Android AOP 框架 Lancet 应用与解析
Android AOP 框架 Lancet 应用与解析Lancet 是一个轻量级 Android AOP 框架。它可以用来替换某个方法的代码实现,或者在方法执行前后插入代码。Lancet 应用举例待修改的 MainActivity 如下:public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override prote原创 2020-12-08 21:14:22 · 2043 阅读 · 9 评论 -
Gradle Android Transform API 编译修改 class
Gradle Android Transform API 编译修改 classGradle 插件Android 的 Gradle 插件一般用作 Android 工程的编译构建流程。以 Android app 模块的 build.gradle 为例:apply plugin: 'com.android.application'‘com.android.application’ 插件是 Android Gradle Plugin(AGP) 提供的用作 app 编译的插件。Android librar原创 2020-11-03 10:07:21 · 1398 阅读 · 0 评论 -
Android Gradle 版本参数优化
Android Gradle 版本参数优化在 Gradle 项目结构中,每一个 Module 都对应一个 build.gradle。有时每个 Module 都会需要配置相同的版本号或者相同的版本依赖。为了解决相同参数重复配置的问题,可以在项目的根目录下增加一个公用的配置文件 common_config.gradle,在公用配置文件提供 Android app 模块、Android library 模块、java library 模块的公用配置。common_config.gradle每一个模块的 bu原创 2020-10-28 13:02:33 · 413 阅读 · 0 评论 -
Android Proguard 混淆
Android Proguard 混淆Android 项目可以在 build.gradle 开启 proguard 代码混淆。开启混淆的好处降低代码的可读性,缩短类和成员的名称,使反编译后的代码不容易被其他人阅读或破解。比如 APP \ SDK 对外发布正式版本时,通常需要做代码混淆。代码压缩。开启混淆后,项目中没有被任何地方执行到的代码会被 Proguard 优化,减少 APP\SDK 包体积。资源压缩。开启混淆后,项目中没有被使用的图片、字符串、布局等资源会从项目中移出,减少 APP\SDK原创 2020-09-07 19:46:23 · 376 阅读 · 0 评论 -
Android View 生成唯一 Id
Android View 生成唯一 Id可以使用 Hook LayoutInflater 的方法替换 SystemService 原有的 LayoutInflater,在自定义的 LayoutInflater 遍历每一个 view,为它们生成 md5 作为 view 的唯一 id。Hook LayoutInflaterHook LayoutInflater 的核心在于使用反射调用 registerService 方法,注册自定义的 LayoutInflater。public class Layout原创 2020-08-31 23:06:48 · 1271 阅读 · 0 评论 -
Android 崩溃优化
Android 崩溃优化Android 的两种崩溃Java 崩溃Native 崩溃Java 崩溃就是在 Java 代码中,出现了未捕获异常,导致程序异常退出。Native 崩溃一般都是因为在 Native 代码中访问非法地址,也可能是地址对齐出现了问题,或者发生了程序主动 abort,这些都会产生相应的 signal 信号,导致程序异常退出。...原创 2020-01-06 21:05:38 · 218 阅读 · 0 评论 -
自定义 ActivityNotifier 观察所有 Activity 切换
自定义 ActivityNotifier 观察所有 Activity 切换我们知道,使用 Application 注册 ActivityLifecycleCallbacks 可以观察到本应用的所有 Activity 的生命周期切换。那么有没有一种方法可以观察到手机上所有应用的 Activity 的生命周期切换?因为所有 Activity 的生命周期回调都会经过 ActivityManagerS...原创 2019-12-03 01:01:30 · 726 阅读 · 0 评论 -
Application 的 onCreate 和 attachBaseContext
Application 的 onCreate 和 attachBaseContextApplication 的 onCreate 和 attachBaseContext 是 Application 的两个回调方法,通常我们会在其中做一些初始化操作。onCreate 和 attachBaseContext 顺序Application 的 attachBaseContext 在 onCreate...原创 2019-12-01 23:57:54 · 11292 阅读 · 0 评论 -
Groovy 语法简介
Groovy 语法简介Groovy 是一个 JVM 语言,它可以和 Java 兼容,编译成 class 文件在 JVM 上运行。相比较 Java ,Groovy 语法更为简洁。Gradle 构建工具使用 Groovy 语言编写配置。Groovy 的 StringGroovy 的 String 类型和 Java 的 String 类似,但是它可以使用 $ 字符串模板来拼接字符串。b = "h...原创 2019-10-09 01:01:48 · 668 阅读 · 0 评论 -
Gradle 插件基础
Gradle 插件基础Gradle 中的插件可以分为 2 类:脚本插件对象插件脚本插件脚本插件直接在 gradle 文件中编写,其他 gradle 文件通过 apply from 引用这个脚本插件。它本质上是一个 gradle 配置文件。在项目根目录下新建一个 config.gradleproject.task('showconfig').doLast { println...原创 2019-10-13 00:39:33 · 309 阅读 · 0 评论 -
Gradle 自定义 task
Gradle 自定义 tasktask 是 gradle 的执行单元,gradle 通过一个个 task 完成具体任务的执行。build.gradle 中自带的 clean task 如下:task clean(type: Delete) { delete rootProject.buildDir}执行 gradlew clean 命令时会删除 build 目录。doFirs...原创 2019-10-12 00:23:25 · 1262 阅读 · 0 评论 -
Gradle 脚本的执行时序
Gradle 脚本的执行时序Gradle 脚本的执行分为三个过程:初始化。分析有哪一些 module 需要被构建,为每个 module 创建 project 实例。这时候 settings.gradle 文件会被解析。配置。处理所有 module 的 build.gradle,处理依赖、属性等。这个时候每个模块的 build.gradle 文件会被解析并且配置,会构建整个 task ...原创 2019-10-10 23:48:52 · 487 阅读 · 0 评论 -
Android SharedPreferences 实现原理
Android SharedPreferences 实现原理Android 的 SharedPreferences 一般用来保存一些标记位或者是一些设置项,比较适合轻量级的存储。通常获取 SharedPreferences 时有两种方法:通过 PreferenceManager 的 getDefaultSharedPreferences 得到默认的 SharedPreferences,也...原创 2019-10-07 21:31:33 · 513 阅读 · 0 评论 -
Binder、IBinder 和 IInterface 的关系
Binder、IBinder 和 IInterface 的关系IBinder 接口Binder 实现了 IBinder 接口。public class Binder implements IBinder { ...}IBinder 接口定义了一些常量和方法。比如第一个交易码(transaction code)和最后一个交易码。最小的交易码是 1,最大的交易码是 16 ^ 6 ...原创 2019-08-20 00:40:01 · 8962 阅读 · 2 评论 -
Binder 笔记
Binder 笔记Binder 是 Android RPC 机制的核心基础类,它实现了 IBinder 接口。Android 中跨进程通信一般都涉及到了 Binder 调用。Binder 简介Binder 类位于 /frameworks/base/core/java/android/os/Binder.java 文件中。大多数使用Binder的时候,不是直接实现Binder类,而是通过 A...原创 2019-08-18 22:11:01 · 141 阅读 · 0 评论 -
Android 问题记录
Android 问题记录自定义 View如何设计一个抽奖动画?View 事件分发时间是怎么确定到某个 view 上的?如:内外层 view,点击内层 view,内层 view 会触发事件,这是怎么个流程?开源框架rxjava 操作符有哪些?okhttp 源码glide 源码eventbus 源码热修复插件化Java 垃圾回收Activity...原创 2019-08-18 22:12:16 · 100 阅读 · 0 评论 -
ContentProvider 的 query 流程分析
ContentProvider 的 query 流程分析ContentProvider 将底层的数据结构(比如数据库、文件)封装并且提供增删改查的接口,提供给本应用或者外部的应用调用。ContentResolver 的 query 方法ContentProvider 的 query 操作是通过 ContentResolver 的 query 调用的,而不是直接调用 ContentProvid...原创 2019-09-11 00:34:13 · 1274 阅读 · 0 评论 -
Activity 应用生命周期回调 ActivityLifecycleCallbacks
Activity 应用生命周期回调 ActivityLifecycleCallbacksActivityLifecycleCallbacks 介绍Application 类里面有一个接口 ActivityLifecycleCallbacks,它可以监听应用的 Activity 声明周期变化。 public interface ActivityLifecycleCallbacks { ...原创 2019-09-09 23:17:26 · 553 阅读 · 0 评论 -
AsyncTask 异步任务
AsyncTask 异步任务AsyncTask 是 Android 的异步任务类,它本质上是对 Thread 和 Handler 的封装,达到工作线程执行异步任务,执行完毕后切换到主线程的功能。AsyncTask 的执行顺序以 SDK 28 为例,默认情况下,调用 execute 方法,AsyncTask 的任务都是串行的。比如有 10 个 AsyncTask 同时开始执行,实际上当前一个 ...原创 2019-08-20 00:38:57 · 183 阅读 · 0 评论 -
Android 消息机制
Android 消息机制Android 的消息机制是通过 Handler 来完成的。Handler 内部有 Looper 和 MessageQueue 分别用来处理消息循环和保存消息队列。线程默认是没有 Looper 的,因此没有办法处理消息。线程要使用 Handler 处理消息,必须先准备消息循环,即先创建 Looper,再根据 Looper 创建线程的 Handler。应用主线程(UI ...原创 2019-08-19 23:10:41 · 118 阅读 · 0 评论 -
Android 布局 ViewGroup 置灰
Android 布局 ViewGroup 置灰如果对 button 控件 setEnabled(false),会把 button 控件置灰,同时使得 button 无法点击。如果需要置灰(enable false)的控件是一个 ViewGroup,不仅需要对 ViewGroup setEnabled(false),而且要对它的每个子 view 都 setEnabled(false)。View...原创 2019-09-13 17:55:08 · 1936 阅读 · 0 评论 -
Android 主线程与Looper.loop() 循环
Android 主线程与Looper.loop() 循环Android中为什么主线程不会因为Looper.loop()里的死循环卡死?这是一个知乎上的问题,链接如下:https://www.zhihu.com/question/34652589要回答这个问题,需要涉及一些知识,比如 Looper、Handler、AcitivityThread、Binder 等。主线程消息循环众所周知,在...原创 2019-08-20 00:39:27 · 1727 阅读 · 0 评论 -
Android 子线程更新 UI
Android 子线程更新 UI一般来说,不能在子线程更新 UI 控件,否则子线程和主线程同时更新 UI,可能导致 UI 被多个线程控制,显示异常。onCreate 更新 UI下面这个例子,在 Activity 的 onCreate 可以更新 UI。 @Override protected void onCreate(@Nullable Bundle savedInstanc...原创 2019-08-20 00:37:33 · 325 阅读 · 0 评论 -
Android Window
Android WindowWindow 是一个抽象类,它的实现是 PhoneWindow。Activity 的 setContentView 方法实际上就是通过 PhoneWindow 完成的。一般使用 WindowManager 来添加 View。WindowManager 是客户端用来添加 View 的接口,WindowManager 在 framework 层对应的是 WindowMan...原创 2019-08-19 23:14:34 · 214 阅读 · 0 评论 -
Android RemoteViews
Android RemoveViewsRemoteViews 不是用在应用自身的进程中,它用在其他进程(SystemServer 进程)中显示视图界面,但它不是真正的 View,也没有继承自 View 类。RemoteViews 的使用场景有两种,通知栏和桌面小部件(Widget)。RemoteViews 在通知栏的应用发送通知时可以使用 RemoteViews 完成自定义通知栏 View ...原创 2019-08-19 23:14:05 · 404 阅读 · 0 评论 -
ContentProvider 难点
ContentProvider 难点ContentProvider 的生命周期ContentProvider 只有 onCreate 这个生命周期方法。ContentProvider 的 onCreate 和 CRUDContentProvider 运行在哪个线程?他们是线程安全的吗?onCreate 方法运行在主线程。如果是 ContentProvider 同进程通信,CRUD 运行在...原创 2019-08-19 23:13:31 · 218 阅读 · 0 评论 -
Service 难点
Service 难点如何停止 Service如果先 startService,然后 bindService,如何停止这个 Service?如果只是调用了 stopService,但是还有其他的地方 bindService,service 是停止不了的。必须保证所有 bindService 的地方都调用了 unBindService,然后再调用 stopService,才能停止 service...原创 2019-08-19 23:11:49 · 130 阅读 · 0 评论 -
Activity 难点
Activity 难点记录 Activity 相关的问题。setResult 和 finish 的关系假设 Activity A 跳转到 Activity B,B 如果想回传一个 intent 给 A,setResult 和 finish 的执行顺序应该是怎样的?应该先 setResult,然后再 finish。 public final void setResult(int re...原创 2019-08-19 23:11:19 · 206 阅读 · 0 评论 -
View 的绘制流程
View 的绘制流程View 的绘制流程其实就是 View 的 measure\layout\draw 过程,分别对应测量、布局和绘制。ViewRootViewRoot 对于 ViewRootImpl 类,他是连接 WindowManager 和 DecorView 的桥梁。View 的三大流程都是通过 ViewRoot 完成的。在 ActivityThread 类中,activity 创建...原创 2019-08-19 23:10:08 · 121 阅读 · 0 评论 -
view 的事件分发机制
view 的事件分发机制当点击手机屏幕时,会产生点击事件,这个事件就是MotionEvent。view系统有一套事件分发机制,决定由哪一个 view 处理点击事件。事件分发由三个重要的方法:dispatchTouchEvent 事件分发onInterceptTouchEvent 事件拦截onTouchEvent 事件处理事件的传递过程是由上至下传递。点击事件会依次传递给 Activ...原创 2019-08-19 23:09:01 · 141 阅读 · 0 评论 -
Android 知识路线
Android 知识点核心知识点BinderAIDL多进程View 的绘制事件分发消息队列Activity 难点Service 难点ContentProvider 难点AsyncTask 原理RemoteViewsWindow 和 ViewRootImpl刁钻问题汇总其他补充开源库原理RetrofitRxjavaGlideGradleGroovyGrad...原创 2019-08-18 22:15:30 · 288 阅读 · 0 评论 -
AIDL
AIDLAIDL(Android Interface Definition Language)Android 接口描述语言,故名思意,使用来定义接口的。创建 AIDL 文件后,编译会自动产生对应的 Java 接口以及实现接口通信的样板代码。// IMyAidlInterfaceB.aidlpackage com.example.b.myapplicationb;// Declare an...原创 2019-08-18 22:13:31 · 147 阅读 · 0 评论 -
Android 中的 IPC 方式
Android 中的 IPC 方式Android 中跨进程通信的方式有 intent 传入 bundle,共享文件,Messenger,AIDL,ContentProvider,Socket。Bundle四大组件中的三大组件(Activity\Service\BroadcastReceiver)都是支持在 intent 中传递 Bundle 数据的。由于 Bundle 实现了 Parcela...原创 2019-08-18 22:12:55 · 133 阅读 · 0 评论 -
Android setPackagesSuspended 暂停应用
Android setPackagesSuspended 暂停应用setPackagesSuspended 是 PackageManager 的一个 public 方法,它可以用来暂停应用。应用被暂停之后会进入 Suspended 状态,无法点击打开,会弹出一个系统对话框,提示应用已被暂停。应用的后台活动比如播放音乐也会被暂停。Android 数字健康(com.google.android....原创 2019-09-12 00:12:09 · 2487 阅读 · 1 评论