Android 如何根据区域高度动态计算最匹配的字体大小 Android 提供了一个 autoSizeTextType 属性来自动调整字体大小,但是它仅适用于 API Level 26 及以上的版本。对于 API Level 25 及以下的版本,可以通过代码计算最佳字体大小来实现动态调整。以下是使用 Kotlin 代码实现的示例:fun getBestFontSize(text: String, maxWidth: Int, maxHeight: Int): Float { val paint = Paint() var textSiz
Android屏幕刷新机制解析 之所以要讲这点,是因为,当我们的 app 界面没有必要再刷新时(比如用户不操作了,当前界面也没动画),这个时候,我们 app 是接收不到屏幕刷新信号的,所以也就不会让 CPU 去计算下一帧画面数据,但是底层仍然会以固定的频率来切换每一帧的画面,只是它后面切换的每一帧画面都一样,所以给我们的感觉就是屏幕没刷新。其实,想想就能明白了。这也是我们从代码上看到的,每一个屏幕刷新信号来的时候,只会去执行一次 performTraversals(),因为只需遍历一遍,就能够刷新所有的 View 了。
module解耦(二)基于路由的解耦 模块化开发可以将一个大型项目拆分成多个相对独立的模块,每个模块负责一个功能或业务场景,从而提高代码的可读性、可维护性和可复用性。路由表可以是静态的或动态的,也可以是本地的或远程的。本地路由表是存储在客户端内存或文件中的,远程路由表是存储在服务器端数据库或配置文件中的。路由是一种将URL映射到具体页面或服务的机制,可以用于将Intent页面跳转的强依赖关系解耦,同时减少跨团队开发的互相依赖问题。这个路由表包含两条记录,分别表示moduleA模块中的pageA页面和moduleB模块中的pageB页面。
安卓开发module解耦总篇 在安卓开发中,随着项目的功能不断扩展,一个app主模块往往会变得庞大而复杂,各种业务逻辑高度耦合,导致代码难以维护和测试。为了提高代码的可读性、可复用性和可扩展性,我们需要将一个app主模块拆分成多个子模块(module),每个子模块负责一个独立的功能或业务场景,例如登录、支付、社交等。但是,拆分后的子模块之间可能还需要相互调用或通信,例如登录模块需要调用支付模块的接口进行支付验证,或者社交模块需要调用登录模块的接口获取用户信息。
module解耦(一)基于接口的module解耦 在安卓开发中,随着项目的功能不断扩展,一个app主模块往往会变得庞大而复杂,各种业务逻辑高度耦合,导致代码难以维护和测试。为了提高代码的可读性、可复用性和可扩展性,我们需要将一个app主模块拆分成多个子模块(module),每个子模块负责一个独立的功能或业务场景,例如登录、支付、社交等。但是,拆分后的子模块之间可能还需要相互调用或通信,例如登录模块需要调用支付模块的接口进行支付验证,或者社交模块需要调用登录模块的接口获取用户信息。
常见代码重构技巧(非常实用) Java 8 之前我们知道,一个接口的所有方法其子类必须实现(当然,这个子类不是一个抽象类),但是 java 8 之后接口的默认方法可以选择不实现,如上的操作是可以通过编译期编译的。另外,if else(或switch)本身就是一个“变化点”,当需要扩展新的类型时,我们不得不追加if else(或switch)语句块,以及相应的逻辑,这无疑降低了程序的可扩展性,也违反了面向对象的开闭原则。同时,类职责单一,类依赖的和被依赖的其他类也会变少,减少了代码的耦合性,以此来实现代码的高内聚、松耦合。
常见 Java 代码重构技巧 Java 8 之前我们知道,一个接口的所有方法其子类必须实现(当然,这个子类不是一个抽象类),但是 java 8 之后接口的默认方法可以选择不实现,如上的操作是可以通过编译期编译的。另外,if else(或switch)本身就是一个“变化点”,当需要扩展新的类型时,我们不得不追加if else(或switch)语句块,以及相应的逻辑,这无疑降低了程序的可扩展性,也违反了面向对象的开闭原则。同时,类职责单一,类依赖的和被依赖的其他类也会变少,减少了代码的耦合性,以此来实现代码的高内聚、松耦合。
面向对象设计的SOLID原则 这个原则比较简单,举个例子来说,我们对外提供API接口服务,调用方可能有很多个,很多时候我们会提供一个大而全的接口给不同的调用方,但有些时候调用方A只使用1、2、3 这三个方法,调用方B只使用4、5两个方法,其他都不用。面向对象设计的原则有很多,在实际的设计过程中完全遵循所有的原则是不太切实际的,也不现实,始终是一个取舍平衡的过程。说到面向对象设计的 SOLID 原则,相信大部分的程序员都有个大概的印象,但具体是做什么的,要怎么做可能不太清楚,今天就带大家一起来聊聊SOLID原则以及它们之间的联系。
聚合/组合 Father类里有两个方法A和方法B,并且A调用了B。子类Son重写了方法B,这时候如果子类调用继承来的方法A,那么方法A调用的就不再是Father.B(),而是子类中的方法Son.B()。如果程序的正确性依赖于Father.B()中的一些操作,而Son.B()重写了这些操作,那么就很可能导致错误产生。
依赖倒置原则 如此一来,系统发布以后,实际上是非常不稳定的,在修改代码的同时也会带来意想不到的风险。通过依赖倒置,可以减少类与类之间的耦合性,提高系统的稳定性,提高代码的可读性和可维护性,并且能够降低修改程序所造成的风险。这时候再看来代码,Tom的兴趣无论怎么暴涨,对于新的课程,只需要新建一个类,通过传参的方式告诉Tom,而不需要修改底层代码。根据构造器方式注入,在调用时,每次都要创建实例。大家要切记:以抽象为基准比以细节为基准搭建起来的架构要稳定得多,因此在拿到需求之后,要面向接口编程,先顶层再细节地设计代码结构。
面向对象设计原则-开闭原则 这下是不是比开始好了很多,并且他还很好的满足了单一职责原则(SRP),每个类只负责一种动物发出的声音,职责单一了, 但是我们发现如果我们想听到猫的叫声还是要修改Main方法中的调用代码, 还要编译部署,风险还是有点大,工作量还是有点大,那么我们能不能不修改代码只需要改个配置来达到修改Main方法调用的结果呢?那么势必会对软件的开发带来额外的风险和成本, 这是OCP原则要规范设计的一个主要原因,所有的设计原则都是对软件的开发,设计以及维护带来好处的,OCP也不例外。很简单达到了我们的设计目的。
面向对象原则——单一职责原则 上图中,通过接口将耦合的职责分开,但实际上ModemImplementation也应该被分离,但有时这些分离是困难甚至是难以实现的,这个时候应当保证所有的依赖关系与它无关。不仅仅是类,方法,函数,甚至是变量也需要做到职责的分离,例如:你不应当使用一个变量即代表正确返回值,又代表错误时的错误原因。单一职责听起来很简单,做起来却很难,因为我们总是自然而然地倾向与把职责结合在一起(习惯于面向过程的思维)。因为之前对于这些概念了解很少,在实际工作中遇到了很多的坑,借着内部交流的机会也重新学习了一下。
谈谈编程思想 今天就讲讲编程思想。编程思想是个宏大的主题,我不敢保证我能在短短的一两个小时里讲得全面而深入。推荐给大家一本好书『冒号课堂』,是国内为数不多的讲编程思想的经典之作。无奈这本书已经不再出版,只能在图书馆里一睹芳容(我几年前在国图和它偶遇)。各种软件思想虽然层出不穷,但其本质是降低系统复杂度,减少重复,减少代码的变更。掌握了这个大方向,理解各种编程思想就容易多了。下文建议在手机上横过来看。所涉及的代码大多是剪短清晰的python代码。我们一点点展开,说到哪算哪。
设计原则之里氏替换原则里氏替换原则的定义 里氏替换原则(Liskov Substitution Principle,LSP)由麻省理工学院计算机科学实验室的里斯科夫(Liskov)女士在 1987 年的“面向对象技术的高峰会议”(OOPSLA)上发表的一篇文章《数据抽象和层次》(Data Abstraction and Hierarchy)里提出来的,她提出:继承必须确保超类所拥有的性质在子类中仍然成立(Inheritance should ensure that any property proved about supertype object
软件开发:面向对象设计的七大原则! 软件系统的构建是一个需要不断重构的过程,在这个过程中,模块的功能抽象,模块与模块间的关系,都不会从一开始就非常清晰明了,所以构建100%满足开闭原则的软件系统是相当困难的,这就是开闭原则的相对性。但在设计过程中,通过对模块功能的抽象(接口定义),模块之间的关系的抽象(通过接口调用),抽象与实现的分离(面向接口的程序设计)等,可以尽量接近满足开闭原则。根据开闭原则,在设计一个软件系统模块(类,方法)的时候,应该可以在不修改原有的模块(修改关闭)的基础上,能扩展其功能(扩展开放)。
Android 插桩之美,全面掌握 但是对于一些复杂情况,我们可能需要使用另外一种 Tree API 来完成对 Class 文件更直接的修改,因此这时候你要掌握一些必不可少的 Java 字节码知识,ASM 的特点是功能强大操作灵活,但是上手的难度也会比 AspectJ 更难,但是它能获得更好的性能,更适合大面积的插桩场景。可以操作“.class”的 Java 字节码,也可以操作“.dex”的 Dalvik 字节码,这取决于我们使用的插桩方法,相对于 Java 文件方式,字节码操作方式功能更加强大,应用场景也更广,但是它的使用复杂度更高。
kotlin之object,companion object,内部class和inner class之间的区别 最近开始使用kotlin写项目了,这几天一直对object,companion object,内部类和inner class搞得有点迷糊现在抽空,理清一下他们之间区别我定义了一个class A然后再class A内部分别定义了class B,object C,companion object D,inner class E四中不同的类每个类中包含一个字段和一个函数/** * Copyright:AndroidInterview * Author: liyang <br>
Kotlin基础--静态方法、静态变量和常量 在Java中我们通常会使用静态变量和静态方法作为工具类。public class StaticUtils { public static String staticProperty; public static String getStaticProperty(){ return staticProperty; }}那如何在Kotlin中类名直接调用类的方法和变量呢?先来看看 object 关键字的作用。objectobject 和 c
Kotlin之const val、val以及@JvmField修饰字段 我们先看看kotlin官方文档的解释 val 声明一个只读属性(也称作只读变量)或局部变量 如果被声明的变量是方法内部的局部变量,可以称为常量 如果被声明变量是顶级变量,称为只读变量 const 将属性标记为编译期常量(编译期常量是在程序编译期会替换成字面量) 位于顶层或者是 object 声明 或 companion object 的一个成员 以 String 或原生类型值初始化 没有自定义 getter 我们通过代码一一理解一下局部变量