<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[Dream It Possible]]></title><description><![CDATA[目标赋予我们生命的意义和目的。有了目标，我们才会把注意力集中在追求喜悦，而不是在避免痛苦上。]]></description><link>https://blog.csdn.net/jdsjlzx</link><language>zh-cn</language><generator>https://blog.csdn.net/</generator><copyright><![CDATA[Copyright &copy; jdsjlzx]]></copyright><item><title><![CDATA[ImageSpan在行首不显示的问题]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/136438919</link><guid>https://blog.csdn.net/jdsjlzx/article/details/136438919</guid><author>jdsjlzx</author><pubDate>Tue, 12 Aug 2025 19:45:21 +0800</pubDate><description><![CDATA[在换行行首的时候，imagespan会出现不显示的问题，这是因为使用空格的问题。将空格替换成\uFFFC即可。Html源码中的写法使用过后我发现，的确是修复问题了，然后我去stackoverflow搜索更加详细的信息image.png发现估计是android对空格做了处理，只要使用非空格，imagespan都能显示出来，因此，只要不使用空格即可。因为国内的教程普遍都是用空格做占位符，因此，发生这种问题估计都是因为这个原因、。]]></description><category></category></item><item><title><![CDATA[如何在Android中使用Canvas drawText属性实现文字居中]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/140112382</link><guid>https://blog.csdn.net/jdsjlzx/article/details/140112382</guid><author>jdsjlzx</author><pubDate>Thu, 07 Aug 2025 20:18:35 +0800</pubDate><description><![CDATA[baseline是绘制文本的基线，相对于绘制文本区域来说，相当于x轴，向上为负（top、ascent），向下为正（descent、bottom），但是这个x轴并不是控件的x轴，切记切记！有点难理解，举个栗子，上文中的x、y参数传的是（0，0），此时的baseline正好是坐标系中x轴，就相当于从y轴开始向右绘制，以x轴作为文本的baseline进行绘制。使用StaticLayout，每行设置的宽度是相同的，当需求为每行显示不同长度的文本时，这种方式就不能使用了，别担心，接着来看下第二种方式。]]></description><category></category></item><item><title><![CDATA[android: Canvas drawText()文字居中]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/141176271</link><guid>https://blog.csdn.net/jdsjlzx/article/details/141176271</guid><author>jdsjlzx</author><pubDate>Thu, 07 Aug 2025 20:14:39 +0800</pubDate><description><![CDATA[而drawText()方法中x,y坐标所指的点就是上图基线上三个点中的一个,具体是哪一个根据paint的setTextAlign()方法设置,默认为left。计算方式就是用： 文本的总高度的一半减去基线到bottom线的距离，算出基线到中点之间的距离，然后再用中间的Y坐标加上这个距离，就是文本的基线位置。要计算的就是基线中间图上红色点的y坐标了,看图可以发现红色点的y为矩形中点黑色点的y坐标+图中黑色点和红色点之间的距离。正好是在中间的,即证明等式是没有问题的,再来分析这个等式是如何计算的。]]></description><category></category></item><item><title><![CDATA[Android ViewFlipper实现文字上下滚动]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/149562900</link><guid>https://blog.csdn.net/jdsjlzx/article/details/149562900</guid><author>jdsjlzx</author><pubDate>Wed, 23 Jul 2025 10:25:43 +0800</pubDate><description><![CDATA[在很多APP都有如下的（上下自动翻滚）这种效果可以使用很多方式实现，有一个简便的方式可以使用ViewFlipper控件实现，ViewFlipper控件继承结果如下：可以看出ViewFlipper 继承自ViewAnimator，ViewAnimator可以将在添加到其中的两个或多个子View之间进行动画处理的简单。一次只显示子View。可以定期在每个子View之间自动翻转。]]></description><category></category></item><item><title><![CDATA[AnimatorSet组合动画]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/149420385</link><guid>https://blog.csdn.net/jdsjlzx/article/details/149420385</guid><author>jdsjlzx</author><pubDate>Thu, 17 Jul 2025 16:24:20 +0800</pubDate><description><![CDATA[注意：AnimatorSet的监听函数只用来监听AnimatorSet的状态，与其中的动画无关，并且就算里面有重复的动画，他也永远无法执行onAnimationRepeat()函数。在AnimatorSet中提供了两个函数：playSequentially()和playTogether()，前者表示所用动画依次播放，后者表示动画一起播放。看了ValueAnimator和ObjectAnimator，他们只能实现一个动画，如果我们想使用一个组合动画，就需要用到AnimatorSet。]]></description><category></category></item><item><title><![CDATA[30个案例彻底摆脱对正则表达式的恐惧]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/147458281</link><guid>https://blog.csdn.net/jdsjlzx/article/details/147458281</guid><author>jdsjlzx</author><pubDate>Wed, 23 Apr 2025 16:54:32 +0800</pubDate><description><![CDATA[如果你已经掌握了的用法，那可以拿这篇文章再复习巩固下；如果你从来没听过正则表达式是什么，或者对其一知半解，那么看这篇文章就对了。坚持看完并在方便的时候打开你的电脑动手实践，就能明白正则表达式是什么了，相信我，将正则表达式用在你的工作或学习中，一定会提升你的效率。好了，下面让我们一起学习！还是先准备一个测试文件用来说明正则表达式的用法，为了方便大家在阅读文章后面内容的时候不用再捣腾到前面看这个原始文件，因此这个文件在后面可能会贴多次，不过还好，也费不了多少流量，还请各位见谅。注：默认。]]></description><category></category></item><item><title><![CDATA[App处于前台，Activity就不会被回收了？]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/144192422</link><guid>https://blog.csdn.net/jdsjlzx/article/details/144192422</guid><author>jdsjlzx</author><pubDate>Mon, 02 Dec 2024 16:53:40 +0800</pubDate><description><![CDATA[Android系统中，进程的生命周期由系统控制，处于体验和性能考虑，在APP中点击Home键或Back回退操作，并不会真的杀掉APP，进程依旧存在于内存中，这样下次启动此APP时就能更加快速。随着系统运行时间增长，打开APP越来越多，内存中的进程随着增多，系统的可用内存会越来越少。可以看到，adj是动态变化的，当App状态及四大组件生命周期发生改变时，都会改变它的值。下次GC，又会走一遍这里的代码，啧啧啧，相比起轮询高效多了。当然，不会那么蠢，还要开发仔自己在APP里回收内存，虚拟机自带。]]></description><category></category></item><item><title><![CDATA[Android 跨进程+解耦的数据持久化方案]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/143714940</link><guid>https://blog.csdn.net/jdsjlzx/article/details/143714940</guid><author>jdsjlzx</author><pubDate>Tue, 12 Nov 2024 16:18:51 +0800</pubDate><description><![CDATA[如果提到跨进程你肯定会想到 AIDL ， 没错我们确实是频繁使用到 AIDL 去 bind 服来完成跨进程通信。另外如果是一些持久化到本地的数据，bind service 的方式也不是最优解。这种解耦的支持跨进程的持久化存储方案：今天带来 ContentProvider+Room 来给大家出个示例。ContentProvider 是基于 Uri 的，天然就算是解耦的，不需要有任何的 sdk 或者 aidl 文件依赖就能达到耦合和跨进程。]]></description><category></category></item><item><title><![CDATA[Android ScrollView上可拖拽滚动条]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/142631651</link><guid>https://blog.csdn.net/jdsjlzx/article/details/142631651</guid><author>jdsjlzx</author><pubDate>Sun, 29 Sep 2024 11:26:34 +0800</pubDate><description><![CDATA[纯干货，希望您能看完自定义可拖拽滚动条，适用于ScrollView，RecyclerView，ListView纯Canvas实现，同样基于原逻辑，也可以更换成任何View，原理相同实现比原生体验更好的交互，如动画，按压拖拽等调用原生原有API，省去大量计算带来的卡顿及位置错乱的问题。]]></description><category></category></item><item><title><![CDATA[android单元测试怎么读取assets目录下的文件]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/141432682</link><guid>https://blog.csdn.net/jdsjlzx/article/details/141432682</guid><author>jdsjlzx</author><pubDate>Thu, 22 Aug 2024 17:01:55 +0800</pubDate><description><![CDATA[【代码】android单元测试怎么读取assets目录下的文件。]]></description><category></category></item><item><title><![CDATA[AGP8.0 ASM 更简单灵活了]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/140940657</link><guid>https://blog.csdn.net/jdsjlzx/article/details/140940657</guid><author>jdsjlzx</author><pubDate>Tue, 06 Aug 2024 01:16:52 +0800</pubDate><description><![CDATA[在之前《Gradle Transform + ASM 探索》一文中讨论了使用 AGP 提供的 Transform 接口自定义 Gradle 插件，通过 ASM 进行代码插桩。实现一些类似方法耗时统计，批量添加点击事件做埋点的功能。但是随着 AGP8.0 的到来，Transform 接口已经被废弃了，至于废弃的原因官方解释也是很官方了。说白了，就是不好用,传统的 Transform API 增加编译耗时。同时提供了更好用的 API 来规避一些编译时的问题。]]></description><category></category></item><item><title><![CDATA[Android Gradle8.0 Transform 废弃如何适配，手撸Arouter插件教你使用]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/140940578</link><guid>https://blog.csdn.net/jdsjlzx/article/details/140940578</guid><author>jdsjlzx</author><pubDate>Tue, 06 Aug 2024 01:10:53 +0800</pubDate><description><![CDATA[最近公司也在适配项目至Android 14 否则市场不让上架，因此 gradle也必须适配升级了，就先来试试水。目前最新的AGP已经到8.3了，适配AGP8.0也要提上日程了，尤其是一些插件项目，因为8.0删除了transform API，所以需要提前做好适配工作。对于之前未了解过gradle自定义插件的同学可以看下我以前的7.0之前的gradle自定义插件的用法 教你如何一步步实现路由插件。Android 自定义Gradle插件，使用Transform。]]></description><category></category></item><item><title><![CDATA[Android 如何通过AIDL分片传输大量 Parcelable 数据列表]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/140316750</link><guid>https://blog.csdn.net/jdsjlzx/article/details/140316750</guid><author>jdsjlzx</author><pubDate>Wed, 10 Jul 2024 10:37:00 +0800</pubDate><description><![CDATA[下面就来讲述一个分片传输的处理方案，来解决这类数据过大的问题。]]></description><category></category></item><item><title><![CDATA[Gradle自定义task打包AAR和APK]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/140304916</link><guid>https://blog.csdn.net/jdsjlzx/article/details/140304916</guid><author>jdsjlzx</author><pubDate>Tue, 09 Jul 2024 19:41:46 +0800</pubDate><description><![CDATA[上图图示为打包AAR过程中，所经历的一系列task任务，以及执行顺序。如果我们想要修改其中的某一步，只需要定义我们自己的task对build目录下的文件做修改，将task插入到目标动作task中间，即可完成功能。以下列举多个例子来演示一下。]]></description><category></category></item><item><title><![CDATA[从Gradle生命周期到自定义Task挂接到Build构建流程全解]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/140304748</link><guid>https://blog.csdn.net/jdsjlzx/article/details/140304748</guid><author>jdsjlzx</author><pubDate>Tue, 09 Jul 2024 19:37:48 +0800</pubDate><description><![CDATA[如果对一个构建流程的任务依赖关系不熟悉的话，可以使用第三方插件来查看，在根项目的build.gradle中添加如下代码:maven {// 应用插件然后执行./gradlew  taskTree --no-repeat我们知道，Gradle 的构建流程是通过执行一系列的 Task 任务来完成的，每一个Task完成自己独特的工作之后，就根据Task的依赖关系，执行下一个 Task 任务。preBuild(开始构建之前执行的Task任务)->(合并资源文件的Task任务)->]]></description><category></category></item><item><title><![CDATA[Gradle8.0中Transform的替代方案]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/140304622</link><guid>https://blog.csdn.net/jdsjlzx/article/details/140304622</guid><author>jdsjlzx</author><pubDate>Tue, 09 Jul 2024 19:26:35 +0800</pubDate><description><![CDATA[插件中对HuiRouterApi进行插桩，添加插入路由信息的字节码指令，在程序运行时，插桩的字节码指令执行，路由信息被注册到HuiRouterApi内部的路由表中，然后外部就可以通过HuiRouterApi进行跳转操作了。先定义一个注解，用来标记页面的路由信息，在定义一个路由管理类，用来存储路由信息并对外提供跳转功能。5、在taskAction方法中，扫描遍历所有的jar和class文件，收集路由信息，查找到HuiRouterApi类，并将收集到的路由信息通过插桩的方式添加到HuiRouterApi中。]]></description><category></category></item><item><title><![CDATA[Gradle自定义task打包AAR和APK]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/140147644</link><guid>https://blog.csdn.net/jdsjlzx/article/details/140147644</guid><author>jdsjlzx</author><pubDate>Wed, 03 Jul 2024 11:34:08 +0800</pubDate><description><![CDATA[上图图示为打包AAR过程中，所经历的一系列task任务，以及执行顺序。如果我们想要修改其中的某一步，只需要定义我们自己的task对build目录下的文件做修改，将task插入到目标动作task中间，即可完成功能。以下列举多个例子来演示一下。]]></description><category></category></item><item><title><![CDATA[Gradle 进阶学习 之 Task]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/140146043</link><guid>https://blog.csdn.net/jdsjlzx/article/details/140146043</guid><author>jdsjlzx</author><pubDate>Wed, 03 Jul 2024 11:25:01 +0800</pubDate><description><![CDATA[Gradle的任务依赖系统提供了灵活性和效率，允许开发者定义复杂的构建流程。了解任务依赖的执行顺序和重复依赖的处理方式，可以帮助开发者更好地控制构建过程，提高构建的可预测性和性能。在Gradle中，定义任务是构建自动化流程的基础。你可以通过几种不同的方式定义任务，每种方式都适用于不同的场景。通过Project的task()方法基本用法：使用Project对象的task()方法可以定义一个新任务。你可以传递一个字符串作为任务名称，以及一个闭包来定义任务的行为。闭包作为参数：闭包可以作为task()]]></description><category></category></item><item><title><![CDATA[从Gradle生命周期到自定义Task挂接到Build构建流程全解]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/140145288</link><guid>https://blog.csdn.net/jdsjlzx/article/details/140145288</guid><author>jdsjlzx</author><pubDate>Wed, 03 Jul 2024 10:31:05 +0800</pubDate><description><![CDATA[如果对一个构建流程的任务依赖关系不熟悉的话，可以使用第三方插件来查看，在根项目的build.gradle中添加如下代码:maven {// 应用插件然后执行./gradlew  taskTree --no-repeat我们知道，Gradle 的构建流程是通过执行一系列的 Task 任务来完成的，每一个Task完成自己独特的工作之后，就根据Task的依赖关系，执行下一个 Task 任务。preBuild(开始构建之前执行的Task任务)->(合并资源文件的Task任务)->]]></description><category></category></item><item><title><![CDATA[Gradle 动态修改VersionName和VersionCode]]></title><link>https://blog.csdn.net/jdsjlzx/article/details/140135620</link><guid>https://blog.csdn.net/jdsjlzx/article/details/140135620</guid><author>jdsjlzx</author><pubDate>Tue, 02 Jul 2024 20:22:39 +0800</pubDate><description><![CDATA[本文通过BuildType、Property、Variants三种方式介绍了动态修改VersionCode和VersionName的方法，但是他们的时机却有不同。BuildType：有局限性，仅能修改VersionName，无法修改VersionCode；Property：使用比较方便，在云编译场景比较常见，本地的话可以写在打包脚本里面；Variants：比较彻底，能完全覆盖，而且也可以抽成Plugin，但是如果有云编译的话，会导致云编译的更改失效；]]></description><category></category></item></channel></rss>