- 博客(119)
- 收藏
- 关注
原创 Kotlin中的::操作符详解
摘要:Kotlin的::操作符支持成员引用,简化高阶函数编程。主要用法包括:引用类成员(如String::length)、构造函数(如::Person)、顶层函数、扩展函数,以及获取KClass对象。实际应用场景包括作为高阶函数参数(如users.map(User::name))和绑定实例方法。编译时会被优化为函数接口对象,如String::length转为fun(s:String):Int = s.length。这种机制使函数传递更简洁高效。
2025-05-29 19:56:24
551
原创 Kotlin委托机制使用方式和原理
本文介绍了Kotlin中的类委托和属性委托机制。类委托通过by关键字实现类似Java代理模式的效果,委托类持有真实类对象并转发方法调用。属性委托则是对属性set/get方法的委托,被委托类需要提供setValue/getValue方法。文中通过代码示例展示了两种委托的使用方式,包括接口定义、实现类、委托类以及主函数调用,并提供了反编译后的Java代码展示底层实现原理。最后通过输出结果验证了委托机制的正确性,说明Kotlin通过by关键字简化了代理模式的实现。
2025-05-29 17:14:30
1313
原创 Android方法耗时监控插件开发
摘要:本文介绍了如何通过自定义Gradle插件结合ASM框架来统计方法耗时,并在耗时超过阈值时通过Log日志定位耗时方法。ASM是一个高效的字节码操作框架,支持通过ClassVisitor、ClassReader和ClassWriter等工具读取、修改和生成类字节码。插件通过Transform Action在编译时对指定包名的类进行插桩,过滤不需要插桩的类。具体实现中,ClassVisitor用于访问类结构,MethodVisitor用于插入耗时统计代码,最终通过Log输出耗时方法和线程信息。该插件可以帮助
2025-05-10 20:37:32
994
1
原创 Android Gradle插件开发
自定义插件的时候经常会有这种自定义配置的需求,通过自定义的配置可以让我们的插件提供更丰富的能力。这些配置就是通过扩展插件来的。增加定义了一个SubExtension类,然后在YiRanPluginExtension实例化的时候加到ExtensionContainer中。类嵌套的话,不能写成内部类,不然编译识别不过。
2025-04-26 18:43:53
1090
1
原创 Android Gradle多渠道打包
当渠道配置越来越多的时候,app目录下的build.gradle文件就会显得有些不易阅读和维护,这时候可以将配置模块化,把渠道相关配置抽成一个channel.gradle文件,然后在app/build.gradle文件中apply依赖进来,这样可以更好的管理和维护渠道项目的渠道配置,app/build.gradle文件也会少一些。除了资源文件和代码文件之外,我们的依赖可能会根据渠道有所不同,比如在做推送功能的时候,在打华为渠道包的时候,只依赖华为的推送,而不依赖oppo的推送,也就是根据渠道来配置依赖项。
2025-04-20 14:01:24
987
1
原创 Android性能优化之内存分析
内存抖动就是不停的在新生代创建对象,创建对象很多,会有空间分配担保,新生代空间比较小占1/3,老年代2/3,当新生代空间不够时,老年代会腾挪一部分空间给新生代,导致老年代空间下降,这个时候假设创建了大对象,从新生代经过了from到to,年龄足够到了老年代,这个时候空间不够,如果没有连续的空间,就会导致OOM。GC过程中会暂停用户线程包括UI线程,Stop the World,频繁的创建,释放对象,GC频繁出现,就会导致App整体卡顿。引用计数法:一个对象身上没有引用,不可用,这个对象就会被回收。
2025-04-06 16:47:35
753
原创 Android Compose入门和基本使用
Jetpack Compose是用于构建原生Android界面的新工具包,是一种声明式UI框架。状态是可以变化的任何值。在Compose函数中,如果数据状态没有发生改变,则UI永远不会自行改变。在Compose中,每个组件都是一个被@Composable修饰的函数,其状态就是函数的参数。因为Composeable是个函数,只能通过传参,当参数不变,则函数的输出就不会变,唯一的参数决定唯一输出。反言之,如果要让界面发生变化,则需要改变界面的状态,然后 Composable 响应这种变化。
2025-04-06 16:46:39
2563
原创 UML中类和类之间关系和各种图
百度百科截图:首先了解一下软件开发生命周期:做需求(项目经理,产品跟客户去谈,比如要求这个页面怎么样,点击按钮出现什么效果)–>形成文档(需要什么描述清楚)–>系统设计(设计一下整个功能有那些类,需要准备的数据库表)–>开发人员编写代码–>测试–>运维…这里重点在于系统设计:就好比在实际生活中要盖一栋大楼,一栋大厦,这个时候是不是需要一个设计的图纸,因为只有设计好之后,才知道设计的合不合理。如果设计得不好,就会导致楼塌,豆腐渣工程,如果设计的好,就可以给建筑工人按照图纸进行设计。
2024-09-28 17:29:25
1713
1
原创 Android中的冷启动,热启动和温启动
在App启动方式中分为三种:冷启动(cold start)、热启动(hot start)、温启动(warm start)
2024-09-16 22:04:30
3455
5
原创 Android自定义View实现不同朝向字体变色
实现效果:1.一个文字两种颜色2.实现不同朝向3.结合ViewPager思路:TextView可行?系统提供的只能够显示一种颜色,需要自定义Viewextends TextView:onMeasure()不需要实现 textColor颜色,textSize字体大小会少很多逻辑。1.一个文字两种颜色 画2.能够从左到右,从右到左3.整合到ViewPager,监听滚动事件自定义属性,不变化的颜色 originColor 变化的颜色 changeColorx要在这个位置。
2024-09-01 22:51:15
507
原创 Android invalidate方法源码分析
mLayoutRequested: 默认为 false,意味着只会执行 performDraw(), 不调用performMeasure()和performLayout()Invalidate()方法是Android中View的方法,通过用来调用onDraw方法,进行UI上的刷新。依次执行 performMeasure(),performLayout(),performDraw()最终绘制到 调用了invalidate()的View的 onDraw()方法;不断的绘制子孩子,再绘制子孩子的子孩子,
2024-08-31 17:05:50
508
原创 Android 为什么子线程不能更新UI
开了线程,更新UI 一般会调用setText(),setImageView 回调到这里面来 ViewRootImpl checkThread(),checkThread()用来检测线程。而如果在子线程中更新UI,调用checkThread的时候Thread.currentThread()就是子线程,然后和mThread 不相等,就会抛出异常。其中的mThread在构造函数中赋值mThread = Thread.currentThread();
2024-08-25 18:10:06
479
原创 Android自定义简单仿QQ运动步数进展圆环
useCenter 是否使用中心:true,连接矩形中心及弧;false不显示,(是否显示半径连线,true表示显示圆弧与圆心的半径连线,false表示不显示)(Paint.Style.FILL时)连接弧的起点终点。2.可以变化的小圆弧(红色) color borderWidth。1.固定蓝色的大圆弧 color borderWidth。顺时针,起点从135度开始扫了270度的距离到终点。3.中间的步数文字 color textSize。左边距离=控件宽度的一半减去文字宽度的一半。
2024-08-25 17:25:51
324
原创 Android自定义简单TextView
-name 属性名称format 格式:string 文字 color颜色dimension 宽高 字体大小 integer数字reference 资源引用(drawable)--background是自定义View管理的,可以不用 --> < attr name = " YiRanBackground " format = " reference|color " />
2024-08-23 23:20:47
1235
原创 Android更改包名和签名
2.手动修改app的build.gradle文件中的applicationId(改成和我们之前修改的包名相同)输入 keystore 的密码后,就可以在终端上看到 keystore 签名文件的配置信息了,如下图所示。所有可以检查本地Java的配置环境有没有问题,也可以在AndroidStudio看一下使用的Java环境。这个问题我这边的解决的办法主要是Java jdk的环境配置有问题,找不到对应的tool工具。keytool -list -v -keystore 你的keystore文件的绝对路径。
2024-08-20 18:06:56
3208
原创 Android事件分发机制
但是listview的dispatchTouchEvent我们自定义的listview重写了,返回false,所以handled返回false,所以if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) 条件不成立,所以for循环会询问一下一个子view,但是我们自定义的ViewPager子View就一个listView,所以for循环就退出了。不会告诉子View分发事件,所以ListView处理不到,导致上下滑不动。
2024-08-18 11:06:29
905
1
原创 设计模式之责任链模式
在阅读OkHttp源码的过程中,我发现他在处理拦截器的过程中非常巧妙,结合了责任链模式,将Request以链路的方式传递下去,再将Response以方向链路传递上去。随着业务的发展,首页的弹窗越来越多,隐私政策弹窗,广告弹窗,好评弹窗,应用内更新弹窗等等。具体流程如上图所以,Chain作为链条,驱动着Request请求的开始,同时也是最终拿到Response的对象。能很清楚的看到每个链中对象的执行过程,按照顺序依次进入对象的执行过程,最后再反向将Response传递上去。请出我们的主角:责任链模式。
2024-04-01 10:11:34
1303
原创 Git中的fork,clone和branch
比如说现在有一个很牛逼的项目,我们进入项目地址,想将这个项目复制到自己的github仓库,然后你还想将仓库中的代码拉取到本地进行修改,修改完你还要将本地的修改后的代码推送到自己的github仓库,更甚至你还想将自己复制过来并修改后的代码再还给原作者,请求人家让你合并。接下来就可以对这个项目进行修改了,但是不建议在master分支上直接修改,最好是在master分支基础上切出一个dev分支,然后在dev分支上修改,修改完成后,再将dev分支merge到master分支。
2024-03-13 21:47:02
3760
原创 自定义View中的ListView和ScrollView嵌套的问题
这样在heightSize = mListPadding.top + mListPadding.bottom + childHeight +getVerticalFadingEdgeLength() * 2只是加了一个childHeight 所以展示的只有一个item的大小。因为Integer.MAX_VALUE右移两位等于一个30位的值,这样执行makeMeasureSpec就可以构建成一个32位的值。当我们在使用到ScrollView和ListView的时候可能会出现显示不全的问题。
2024-02-29 22:57:20
860
原创 Android组件化中的Arouter学习
因为生成文件中有很多group,有grouplogin,groupmain,要找到这些group调用loadInto方法,这样我们通过传入path路径,就能找到RouteMeta,就可以拿到class。当我们使用Arouter的注解处理器的时候,就会帮我们生成相应的类,Arouter$$Group $ $login就是login的group,而Arouter $ $Root $ $login就是去查找到group并调用group的方法。而当第二次,缓存到本地后,直接读取拿到信息,就不用再去找。
2024-01-31 22:47:30
932
原创 Kotlin中常见的List使用
find和findLast函数返回与给定条件匹配的第一个或最后一个集合元素。在列表中,都可以使用indexOf() 或者lastIndexOf() 查询到元素在集合中的位置。node:如果集合中没有符合匹配条件的元素,返回true,否则返回false。我们注意到,截取后的集合,也是按照我们传入的下标顺序进行获取的。count函数返回集合中的元素总数或与给定条件匹配的元素数。这些函数检查是否存在与给定条件匹配的集合元素,并返回布尔值。该函数返回具有给定索引的集合元素列表。返回列表中第一个或最后一个元素的值。
2023-11-27 11:15:26
2179
原创 Java中的日期类整理
new SimpleDateFormat(“yyyy年MM月dd日 HH:mm:ss:SSS”).parse(“2022年10月31日 14:58:22:119”)s字符串中的日期格式必须和simpleDateFormat括号里的日期格式相同,才可以使用simpleDateFormat.parse(s)常见的格式:yyyy年MM月dd日 D HH:mm:ss:SSS(hh代表12小时制、SSS代表毫秒、D代表今天是这一年的第几天)包含两个构造器,Date()和Date(long);new Date();
2023-10-18 15:59:02
518
原创 Android中的RxJava入门及常用操作符
RxJava在GitHub的介绍// 翻译:RxJava 是一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库也就是说:RxJava是一个基于事件流,实现异步操作的库。
2023-10-07 19:26:16
1060
1
原创 Android项目中使用Protobuf数据格式
Protobuf全称:Protocol Buffers,是Google推出的一种与平台无关,语言无关,可扩展的轻便高效的序列化数据存储格式,类似于我们常用的xml和json。问题:既然有了xml和json,Google为啥还要推出Protobuf呢?存在是有原因的,Protobuf 用两个字总结:小,快。用 Protobuf 序列化后的大小是 json 的十分之一,是 xml 格式的二十分之一,而且性能是他们的 5~100 倍。
2023-09-28 15:48:14
2746
原创 记录打开别人的Android项目进行构建时报Caused by: org.gradle.api.internal.plugins.PluginApplicationException: Failed
1.在Project视图模式下,选择gradle.properties文件。3.然后点击右上角蓝色部分的‘Sync Now’,稍等几秒进行同步即可完成。2.在最后一行(或者这个文件里的随便哪一行都可以),输入以下代码。个人感觉可能是我保存项目的路径有中文导致这个问题。这行代码的意思是“覆盖路径检查”。
2023-09-27 15:46:11
545
原创 Java中HashMap原理与分析
hash值的每个二进制位用abcde来表示,那么hash和新旧table按位与的结果,最后4位显然是相同的,唯一可能出现的区别就是第5位,也就是hash值的b所在的那一位,如果b所在的那一位是0,那么新table按位与的结果和旧table结果相同,反之如果b所在那一位是1,则新table按位与的结果就比旧table的结果多了10000(二进制),而这个二进制就是旧table的长度。JDK1.7中,由于多线程对HashMap的扩容,HashMap采用头插法,新插入的数据会从链表的头节点进行插入。
2023-08-06 21:58:49
309
原创 Android四大组件之服务
服务是Android中实现程序后台运行的方案,他非常适合去执行那些不需要和用户交互而且还要求长期运行的任务。服务的运行不依赖于任何用户界面,即使程序被切换到后台,或者用户打开了另外一个应用程序,服务仍然能够保持正常运行。每一个服务都需要在配置文件AndroidManifest.xml文件里进行生命,怎么生命呢?使用标签,其实跟前面的activity,广播接收者receiver一样生命。通过Context.startService()来开启服务,通过Context.stop()来停止服务。当然啦,还有一
2023-08-03 10:45:39
1177
原创 算法之快速排序
快速排序广泛应用的主要原因是高效,核心算法是分而治之。Java标准库中Arrays类的sort方法里源码也正是使用了优化后的快速排序。
2023-07-30 17:57:06
291
原创 当你输入URL并按下回车后,发生了什么?
大概发生了八步的事情:URL解析->DNS解析->服务器建立连接->发送HTTP请求->服务器处理请求->服务器响应->接收和渲染页面->关闭连接。
2023-07-16 17:21:25
867
原创 Android架构之MVC,MVP,MVVM解析
Presenter中同时持有View层的interface的引用以及Model层的引用,而View层持有Presenter层引用。当View层某个界面需要展示某些数据的时候,首先会调用Presenter层的引用,通知Presenter层加载数据,然后Presenter层会调用Model层请求数据,当Model层数据加载成功之后会调用Presenter层的回调方法通知Presenter层数据加载情况,最后Presenter层在调用View层的接口将加载后的数据展示给用户。比如说首页,详情页面,播放器页面。
2023-07-11 22:36:14
1108
原创 Android之Glide图片框架分析
确定为GIF动图后,会构建一个GIF的解码器,它可以从GIF动图中读取每一帧的数据并转换为Bitmap,然后使用Canvas将Bitmap绘制到ImageView上,下一帧则利用Handler发送 一个延迟消息实现连续播放,所有Bitmap绘制完成后又会重新循环,所以就实现了加载GIF动图的效果。EngineJob内部维护了线程池,用来管理资源加载,当资源加载完毕的时候通知回调;很明显,这是加载图片之后的事情,通过EngineJob开启线程池去加载图片,取到数据之后,会回调到主线程,把图片存到弱引用。
2023-07-10 23:24:30
1841
原创 Android之Handler分析与理解
Android中的Handler是一个用于处理消息和线程间通信的机制。它可以将Runnable对象或Message对象发送到特定的线程中进行处理。使用Handler的主要目的是在不同的线程之间进行通信,特别是在后台线程中执行一些任务后,将结果发送到UI线程进行更新。
2023-07-03 20:04:26
995
原创 Android之OkHttp框架的分析
Okhttp是Android开发常用的一个网络请求框架,下面将按照自己的理解将okhttp分为三条主线进行分析。
2023-07-02 21:54:56
1050
原创 Android大图加载优化方案,避免程序OOM
我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有不同的形状、不同的大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小。比如微博长图,海报等等。所以我们就要对图片进行局部显示。
2023-06-20 20:52:38
3364
4
原创 码分多址CDMA通信
先收到码片序列:(-1 +1 -3 +1 -1 -3 +1 +1) 问哪个站发送了数据?发送的数据是1还是0?码分复用CDM或码分多址CDMA是一种共享信道的方法,每一个用户可以在同样的时间使用同样的频带进行通信,=(+1-1-3-1-1-3+1-1)/ 8 = -1 B发送了0。=(+1+1+3+1-1-3-1-1)/ 8 = 0 C未发送数据。=(+1-1+3+1-1+3+1+1)/ 8 = 1 A发送了1。=(+1+1+3-1+1+3+3-1 )/ 8 = 1 D发送了1。
2023-06-12 10:21:20
2330
1
原创 子网划分题型总结
划分子网,那么就需要借若干位的网络号,比如借1位的话只能划分为1和0,只能划分两个子网,借2位可以划分00,01,10,11,可以划分4个子网,借3位的话可以划分000,001,010,011,100,101,110,111,可以划分8个子网,满足划分5个子网,那么就需要借3位。我们确定的主机数要大于确定的主机数,才能保证所有的主机数可以得到分配,至于为什么-2,是因为我们要排除主机位全为0和全为1的情况。子网划分主要分为定长和变长两种类型,下面1和2两题是定长,3是变长。
2023-06-11 17:37:40
508
原创 GitHub上README.md文章的上传图片和图片大小尺寸
但是有时候我们上传的图片有可能会太大导致占满界面,此时就需要控制图片大小尺寸。例如这种格式https://github.com//***.jpg。注意图片前与文字要用“回车”隔开,不然文字和图片会在一行展示。
2023-06-11 14:47:26
3909
原创 Android Jetpack组件之Navigation
无论您如何构建应用界面(使用 Fragment、Activity 还是其他组件),都要为应用设计屏幕间导航的功能。那么可以试试Naviagtion。
2023-06-06 16:37:30
700
原创 Android之解决RecyclerView与NestedScrollView的滑动冲突方法
道理是一样的,因为刷新组件消耗了事件,RecyclerView并没有收到事件,所以出现了这种情况。解决的方法就是在刷新组件消耗事件的方法中进行判断,如果RecyclerView还能进行滑动,那就不消耗这个事件,将事件分发给RecyclerView,否则就消耗这个事件,进行数据的加载。这个方法判断刷新组件中的子容器是什么类型,并根据类型调用不同的方法,我们添加一段判断子容器是NestedScrollView的语句,注意要写在判断ViewGroup类型的上面。测试结果:可行,滑动冲突解决,但是仍存在一些瑕疵。
2023-05-31 22:09:28
5467
2
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人