自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(31)
  • 收藏
  • 关注

原创 AIDL使用及原理介绍

介绍参考官方文档:https://developer.android.com/develop/background-work/services/aidl?hl=zh-cn。

2024-08-16 17:42:48 1085 1

原创 Retrofit之Gson解析原理浅析

文章目录1、TypeAdapter的产生过程1.1 构造器实例化过程1.2 反序列化name列表获取过程2. 数据读取(反序列化)过程本文接着上一片博客Retrofit网络请求过程原理分析的结尾ReponseBodyConverter原理继续分析,场景是:当一个网络请求返回时,Gson是怎么对输入流进行解析的。我们知道当OkHttpCall返回数据时会调用parseResponse()方法来解析返回的数据。这里假设调用GsonResponseBodyConverter类来实现数据解析(即在初始化Retro

2021-03-21 18:53:28 1412 1

原创 系统控件滑动简析

文章目录1、滑动基本原理2、嵌套滑动2.1、外部控件处理嵌套滑动2.2、内部控件处理嵌套滑动在许多场景中我们往往需要自己实现控件的滑动效果,如TextView的跑马灯效果,歌词控件的滑动。其实,许多系统控件也实现了滑动效果,如ScrollerView、RecyclerView等等。同时如果布局中有多个可滑动的控件,且要求各个可滑动控件要相互协同工作,这就要求滑动事件要在各个控件中间分发传递,NestedScrollingChild和NestedScrollingParent两个接口即可完成上述功能定义,系

2021-02-08 18:47:31 370

原创 Material Desion之Shape与shadow原理实现

文章目录1、与shape相关类的功能及关系概述2、边角绘制流程3、兼容shadow绘制流程1、与shape相关类的功能及关系概述在Material Design的shape包下的MaterialShapeDrawable类是用来展示Material Shape的阴影,高程,比例和颜色的。MaterialShapeDrawable是Drawable的子类,其主要的展示逻辑在draw()方法里,先看一下与shape有关的类图:MaterialShapeDrawable类里有一个内部类MaterialSh

2021-02-05 17:30:49 1503

原创 Retrofit之RxJava流处理与线程控制

Retrofit之RxJava流处理与线程控制1. JxJava流处理过程1.1. 订阅过程1.2 流处理过程使用Retrofit发起一次RxJava式的网络请求的式例代码如下:HttpManager.newRetrofit().create(FeedbackApi::class.java) .report() .observeOn(AndroidSchedulers.mainThread())

2021-01-04 18:07:04 499

原创 AppCompactViewInflater替换旧版本Widget及对Material Design的支持

文章目录1. AppCompatViewInflater的作用2. AppCompat Widget功能总结2.1. TextView2.1.1 AppCompatTextView2.1.2 MaterialTextView2.2. AppCompatImageView2.3. Button2.3.1 AppCompatButton2.3.2 MaterialButton2.4. AppCompatEditText2.5. AppCompatSpinner2.6. AppCompatImageButton2

2020-11-11 18:22:00 1146

原创 JetPack之DataBinding布局文件绑定及UI刷新原理

文章目录1. 项目结构说明2. DataBinding绑定解析——节点依赖关系3. DataBinding绑定解析——获取绑定4. DataBinding绑定解析——执行绑定5. DataBinding绑定解析——刷新UI1. 项目结构说明项目有三个moduel:app、business,其中app为空moduel,里面没有具体代码,business主要放业务相关的代码,又有两个目录home和baseui。在app moduel和baseui包和home包的build目录下生成的代码目录如下:可以看

2020-11-07 10:23:35 1013

原创 WMRouter开源库源码阅读笔记(Fragment跳转)

文章目录1.在使用WMRouter实现通过Path来跳转目标Fragment时,由于自己的问题给目标Fragment的构造函数传了一个Context参数,导致跳转不成功问题。在查找这个问题中熟悉了WMRouter的源码,在这里记录一下。1....

2020-10-22 15:30:38 1151

原创 Android中打包发布的方式

文章目录jar格式和aar格式的区别jar格式的打包上传方式aar格式的打包上传方式在开发过程中,往往需要将公共的模块打包发布,场景有:在存在许多模块的项目中,为了减少每次构建因为编译所有模块造成的时间长的问题,可以将每个模块打包成AAR并发布的本地,每次编译只需编译有改动的模块,可以减少编译时间。对于公共模块,可以将其打包并发布到远程仓库,用Gradle管理供所有人使用。这对于SDK开发人员是经常遇到的。对于以上场景中,打包可以节约开发成本。常见的打包格式有两种:jar格式和aar格式。ja

2020-10-20 20:04:52 517

原创 JetPack之DataStore源码笔记

文章目录1. Preferences DataStore1.1. Preferences DataStore的创建1.2. Preferences DataStore的写入1.2.1. 迁移SharedPreference过程上一篇文章分析了SharedPreferences的原理和弊端,这篇文章主要分析DataStore的源码。根据官方文档的介绍,DataStore主要有一下优势:支持键值对和类型化对象的存储;数据存储采用protocol buffers,更节省资源;使用Kotlin协程以及Fl

2020-10-12 15:36:14 1525

原创 SharedPreference存储数据源码简析

文章目录1. SharedPreference几点细节1.1. SharedPreference在初始化时会在子线程中将文件数据加载到内存中1.2. 写入数据时,commit()是同步的,apply()是异步的1.3. 直接从缓存中获取数据1. SharedPreference几点细节1.1. SharedPreference在初始化时会在子线程中将文件数据加载到内存中在使用SharedPreference前应该先初始化一个SharedPreference实例:getActivity().getPr

2020-09-30 15:48:08 551

原创 Coroutine之Flow与LiveData相互转换

文章目录1. Flow与LiveData相互转换1.1. Flow转换成LiveData1.2. LiveData转换成Flow1. Flow与LiveData相互转换1.1. Flow转换成LiveDataFlow提供了asLiveData()扩展函数来将Flow转换成LiveData://CoroutineLiveData.kt@JvmOverloadsfun <T> Flow<T>.asLiveData( context: CoroutineContext

2020-09-29 17:10:07 3207 1

原创 JetPack之WorkManager学习记录

文章目录1. 任务的启动2. OneTimeWorkRequest的链式组合3. 工作调度WorkManager主要是用来处理后台任务的,并且保证这些任务可以在App退出时在适当时机执行,实现这一目标主要是依靠:使用Room将任务以WorkSec为单元存储在本地;使用反射将Work类实例化,并执行其中定义的任务,保证了App退出时任务依然能得到执行。其中后台任务分为两类:立即执行的任务;限制的任务。WorkManager使用及介绍参考Exploring Jetpack: Schedul

2020-09-28 19:22:52 441

原创 JetPack之AppStartUp原理分析

文章目录1. 自动初始化源码分析2. 主动初始化源码分析对于冷启动的App,我们知道其启动过程中,ContentProvidor是先于Applycation初始化的,在Android 10的源码中可以验证: //ActivityThread.java private void handleBindApplication(AppBindData data) { //初始化ContentProvidor if (!data.restrictedBackupMode

2020-09-24 17:18:54 330

原创 Coroutine之Channel的多路复用原理浅析

目录1. select()函数细节2. send()函数细节根据官方文档可知select 表达式可以同时等待多个挂起函数,并选择第一个可用的。select具有一下功能可以细分如下:在多个Channel中选择第一个到达的进行处理;可以对主-从Channel模式进行分流处理,以降低主Channel的压力。下面通过官方的例子来分析Channel的多路复用原理,首先定义两个以不同速率产生字符串的生产者:fun CoroutineScope.fizz() = produce<String>

2020-09-20 23:51:59 783

原创 Coroutine之Channel与Flow的相互转换

目录1. Channel转化成Flow2. Flow转换程Channel2.1. produceIn()转换方式2.2. broadcastIn转换方式源码中对ChannelFlow的定义为:ChannelFlow是一个Flow,但是使用了Channel对它进行扩展,并且二者始终彼此融合在一起。ChannelFlow是一个虚类,其继承关系图为:ChannelFlow主要是用于Channel与Flow相互转换的,下面通过不同的转换方式来看其原理:1. Channel转化成Flow定义了两个Recei

2020-09-17 20:30:10 2039

原创 JetPack之LiveData源码纪要

目录1. 添加观察者的方式1.1. observe(Observer)方式1.2 observeForever(Observer)方法2. 观察者的通知方式LiveData的官方定义:LiveData是一种可以在给定生命周期内被观察的数据承载类。1. 添加观察者的方式有两种方式添加观察者:通过observe(Observer)方法添加的观察者只有在生命周期拥有者活跃(处于STARTED或RESUMED状态)的时候才会接收到LiveData的修改通知,在生命周期拥有者进入DESTORUYED状态时会

2020-09-16 11:10:45 402

原创 JetPack之ViewModel的几点原理分析

目录1. ViewModel的存取设计1.1. ViewModelStore的提供1.2. Factory的提供1.3 ViewModel的存取2. SavedStateHandle保存数据原理2.1. 状态保存过程2.2. 状态恢复过程3. ViewModel的超长生命周期原理ViewModel有两个显著的优点:同一个Activity下的不同Fragment之间可以用ViewModel通信;ViewModel的生命周期极长,即使其LifecycleOwer销毁了ViewModel也依旧存活;第一

2020-09-14 01:05:45 927

原创 JetPack之Lifecycle观察者的实现方式解读

目录1. 生命周期拥有者2. 生命周期观察者2.1. FullLifecycleObserverAdapter实现方式2.2. SingleGeneratedAdapterObserver和CompositeGeneratedAdaptersObserver实现方式2.3 ReflectiveGenericLifecycleObserver实现方式1. 生命周期拥有者android中Activity和Fragment具有生命周期,在Lifecycle组件中用LifecycleOwner接口来定义具有生命

2020-09-11 11:02:37 729

原创 ViewPager与ViewPager2的Adapter对比

目录1. ViewPagerAdapter与其两个子类FragmentPagerAdapter、FragmentStatePagerAdapter1.1. ViewPagerAdapter重要方法剖析a. instantiateItem(ViewGroup container, int position)b. setPrimaryItem(ViewGroup container, int position, Object object)c. startUpdate(@NonNull View contain

2020-09-06 23:52:04 4424 1

原创 CoroutineContext的plus原理

文章目录CoroutineContext的plus operationfold展开操作minusKey减法操作get获取操作CoroutineContext的plus operationCoroutineContext中plus()方法会用到三个方法,这三个方法以虚函数的形式定义在CoroutineContext中: /** * Returns the element with the given [key] from this context or `null`. */

2020-08-18 15:07:40 1141 2

原创 Retrofit网络请求过程原理分析

文章目录Retrofit对Coroutine的适配Retrofit对Coroutine的适配在使用Retrofit时会定义一个接口类,在访问网络时会调用该接口中的方法访问网络。这一过程时通过动态代理实现的,在我们使用Retrofit实例的getApi()方法时,实际会使用Proxy.newProxyInstance()来创建一个接口类的动态代理对象。使用Paging3时接口定义为://interface HomeHttpApiReplaceinterface HomeHttpApiReplace {

2020-08-15 12:47:57 617

原创 Navigation使用指南

概述Navigation跳转1.环境配置在app model下配置://build.gradleimplementation deps.navigation.fragment_ktximplementation deps.navigation.ui_ktx相关配置://versions.gradleversions.navigation = "2.1.0"def navigation = [:]navigation.fragment_ktx = "androidx.navigatio

2020-08-11 18:22:34 2763

原创 Kotlin协程Channel中receive与send原理分析

文章目录0. 引言1. runBlocking()2. receive()3. send()0. 引言在Kotlin官方文档介绍中,Channel是用于协程间的通信的,它的宗旨是:Do not communicate by sharing memory; instead, share memory by communicating. 下面借助官方文档给的一个Channel的使用例子来感受一下这一通信过程的实现:private fun testChannel() { runBlocking {

2020-08-11 00:47:23 3369

原创 Kotlin中flow发射与接收分析

文章目录引言上游构造SafeFlow下游collect()逻辑引言Kotlin Coroutine 1.3.2 新增了flow库,通过官方描述:Flow — cold asynchronous stream with flow builder and comprehensive operator set (filter, map, etc). 可知Flow十分类似RxJava中的Obsaverble。下面通过简单例程来看一下它的使用:fun main() { runBlocking {

2020-08-05 16:21:54 1954

原创 Navigation初始化NavHostFragment过程

Navigation初始化NavHostFragment过程Navigation初始化NavHostFragment过程1. MainActivity的初始化2. NavHostFragment的初始化2.1. 初始化NavHostController实例2.2. 调用NavHostController实例解析mGraphId2.2.1. Navigation初始化NavHostFragment过程在使用Navigation库是,其固定模式是在Activity的布局文件中会先放一个NavHostFragm

2020-08-04 16:54:44 7622

原创 Coroutine挂起与恢复分析

Coroutine挂起从编译代码看挂起从源码看挂起从编译代码看挂起用Kotlin简单写一个Coroutine的小例子,代码如下:@InternalCoroutinesApifun main() { println("main") runBlocking { println("main launch") test1() }}suspend fun test1() { println("test1") delay(100)

2020-07-28 17:53:03 1102

原创 Paging3加载网络数据指南

Paging加载网络数据指南配置依赖网络仓库1.PagingConfig2.PagingSource将数据流注入适配器PagingDataAdapter配置依赖在相应模块的build.gradle文件下配置: implementation deps.paging_runtime implementation deps.retrofit.gson implementation deps.okhttp_logging_interceptor implementation deps.

2020-07-21 20:52:02 3972 1

原创 Paging内部原理

Paging内部原理下拉刷新内部逻辑下拉刷新内部逻辑 当用户触发下拉刷新时,会调用PagingDataAdapter的reresh()方法,我们就从该方法切入,一步步看看内部的调用逻辑。首先,我们看一下函数时序图: ![![Alt]](https://img-blog.csdnimg.cn/20200716195809404.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6L

2020-07-17 17:43:05 2340

原创 ThreadLocal源码笔记

ThreadLocal源码笔记引言类图关系ThreadLocal关键方法1. set()方法,写入值2. get()方法引言总所周知,对Java多线程的共享资源的访问会产生竞争条件,为了保护临界区,往往需要加锁,使所有线程以串行的方式访问临界区,这是以牺牲时间性能为代价的。ThredLocal的实现机制是:为每一个线程分配一个副本,所有副本之前相互独立,互不影响,因此不会产生线程竞争,所有线程可以并行运行。这是以牺牲空间性能为代价的。类图关系如图所示:每一个线程类Thread中包含一个类型为Thr

2020-07-10 17:45:07 223

原创 Android动态代理原理以及在Retrofit上的应用

Java动态代理调用时序调用时序看一下动态代理的使用例子: public static void main(String[] args) { FacialMask facialMask = new FacialMask(); IProduct proxyInstance = (IProduct) Proxy.newProxyInstance(FacialMask.class.getClassLoader(), new Class[]{IProduct.class}, ne

2020-05-13 16:06:07 710

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除