小木箱@Singapore

Results 62 comments of 小木箱@Singapore

java API 提供以下两个接口加载一个 so 库 - `System.loadLibrary(String libName)` : 传进去的参数是so库名称,表示so文件,位于`APK` 压缩文件中的 `lib` 目录,最后复制到`APK`安装目录 - `System.load(String pathName)` 传进去的参数是 so 库 在磁盘中的完整路径,加载一个自定义外部so库文件 上述两种方法方式加载so库实际最后调用`nativeLoad`这个`native` 方法加载 so 库, 这个方法参数 `fileName` so 库: 在磁盘的完整路径名称 `native`...

> 1)AndroidManifest ![image](https://user-images.githubusercontent.com/17723631/98602242-19456700-231b-11eb-8dc6-2bbd6cdfb55d.png) > 2)Layout xml 布局适配 适配原则,在任何横向布局上,不是绝对的left和right,而是使用start和end。 ![image](https://user-images.githubusercontent.com/17723631/98602268-23fffc00-231b-11eb-8b2d-80d63f9eb950.png) 需要注意的是,minSdkVersion 3) 资源适配 由于部分资源是有左右方向的,例如返回按钮的图片资源。通用适配方法: ![image](https://user-images.githubusercontent.com/17723631/98602336-43972480-231b-11eb-81a3-f68868597470.png) > 4)Java 代码布局适配 ![image](https://user-images.githubusercontent.com/17723631/98602400-5c9fd580-231b-11eb-80b3-b4921843df41.png) 总结: 1. 判断当前应该使用RTL或者LTR 2. 获取View方向:ViewCompat.getLayoutDirection(view),需要注意的是在View构造函数中,getLayoutDirection总是返回LTR 3. 获取某个Locale语言方向: TextUtilsCompat.getLayoutDirectionFromLocale(locale) 4. 获取当前Activity使用的方向:context.getResources().getConfiguration().getLayoutDirection() 5. 对相对屏幕左边的X值进行翻转...

我们来看一下非泛型版本的字节码信息 ![image](https://user-images.githubusercontent.com/17723631/98601200-aab3d980-2319-11eb-868c-a9aca45293e8.png) ![image](https://user-images.githubusercontent.com/17723631/98601010-63c5e400-2319-11eb-88fb-3aea682cc2e3.png) 在编译过程中,类型变量的信息是能拿到的。所以,set方法在编译器可以做类型检查,非法类型不能通过编译。对于get方法,由于擦除机制,运行时的实际引用类型为Object类型。为了“还原”返回结果的类型,编译器在get之后添加了类型转换。 我们再看一下泛型版本 ![image](https://user-images.githubusercontent.com/17723631/98601297-cdde8900-2319-11eb-8ce5-d5cf36a4b858.png) ![image](https://user-images.githubusercontent.com/17723631/98600586-c4085600-2318-11eb-9c54-c9116a43e925.png)

吃透 https://blog.csdn.net/hfy8971613/article/details/108401535 https://www.jianshu.com/p/d0f5cf304fa4 这两篇博客即可

让快指针先走K个单位,等快指针遍历到链表结尾,慢指针指向的就是倒数第K个结点。 ![image](https://user-images.githubusercontent.com/17723631/98602920-2ca50200-231c-11eb-8083-5bbad79c21d3.png)

1.Thread.currentThread().interrupt(); 这个用于清除中断状态,这样下次调用Thread.interrupted()方法时就会一直返回为true,因为中断标志已经被恢复了。而调用isInterrupted()只是简单的查询中断状态,不会对状态进行修改。 ---------------------------------------- 2.interrupt()是用来设置中断状态的。返回true说明中断状态被设置了而不是被清除了。我们调用sleep、wait等此类可中断(throw InterruptedException)方法时,一旦方法抛出InterruptedException,当前调用该方法的线程的中断状态就会被jvm自动清除了,就是说我们调用该线程的isInterrupted 方法时是返回false。如果你想保持中断状态,可以再次调用interrupt方法设置中断状态。这样做的原因是,java的中断并不是真正的中断线程,而只设置标志位(中断位)来通知用户。如果你捕获到中断异常,说明当前线程已经被中断,不需要继续保持中断位。 ---------------------------------------- 3.interrupted是静态方法,返回的是当前线程的中断状态。例如,如果当前线程被中断(没有抛出中断异常,否则中断状态就会被清除),你调用interrupted方法,第一次会返回true。然后,当前线程的中断状态被方法内部清除了。第二次调用时就会返回false。如果你刚开始一直调用isInterrupted,则会一直返回true,除非中间线程的中断状态被其他操作清除了。 ---------------------------------------- 当阻塞方法收到中断请求的时候就会抛出InterruptedException异常,这些方法都是出于阻塞状态的方法

### 以往的做法是: 1. 数据库升级 需要我们自行处理,即继承OnUpgrade()。那这样就和以往SQLiteOpenHelper一样,需要判断版本号,然后写SQL进行新增字段或新增表。这样显然不好,我们就是不想写SQL的,而且版本号判断维护麻烦。 ### 现在的做法是: 1. 添加依赖 ```grovvy dependencies { compile 'com.github.yuweiguocn:GreenDaoUpgradeHelper:v0.0.5' } ``` 2、继承DaoMaster.OpenHelper,自定义OnUpgrade()。 ```java public class MySqlLiteOpenHelper extends DaoMaster.OpenHelper { public MySqlLiteOpenHelper(Context context, String name) {...

`Java`类加载过程完整生命周期分为: - load - 加载 `Class` - 通过 `Class` 全限定名获取二进制字节流 - 将 `Class` 文件加载到方法区 - 在内存中生成`java.lang.Class`表示这个`Class` - 获取 `Class` - 从`zip`中获取,如: 从 `jar`,`war`,`ear`等格式的文件中读取`Class`文件内容。 - 从网络获取,如: `Applet` - 动态生成,如: `动态代理`,`ASM`框架等都是这种形式 -...

### D8 ![image](https://user-images.githubusercontent.com/17723631/99867748-1a1da900-2bf7-11eb-966a-6d4cc94e8c13.png) ### R8 ![image](https://user-images.githubusercontent.com/17723631/99867755-31f52d00-2bf7-11eb-8759-888e56eb8650.png) ### 比较 ProGuard 和 R8 优化功能 ![image](https://user-images.githubusercontent.com/17723631/99867766-64068f00-2bf7-11eb-87db-07dd0d3fb58a.png) 构建时的性能 ![image](https://user-images.githubusercontent.com/17723631/99867779-97e1b480-2bf7-11eb-9477-bec1474d3c6e.png) - 保留一个 class r8 仅仅保留 静态初始化 cinit 的方法,而 ProGuard 同步保留他们的无参构造方法。 - 一个虚方法被保留 ProGuard 将保留整条继承数上的该方法。 r8...

### 冷启动类加载的原理 冷启动重启生效,现在一般有两种实现方式 - 一种是类似于QQ空间的插桩,单独放一个帮助类在独立的`dex`中让其他类调用。阻止类被打上CLASS_ISPREVERIFIED 标志从而规避问题的出现.最后加载补丁dex得到dexFile对象作为参数构建一个`Elements`数组前面,这是QQ空间的做法 - `Tinker` 提供`dex`差异包,整体替换`dex`方案,差量方式给出`patch.dex`,然后将`patch.dex`与应用的`classs.dex`合并成一个完整的`dex`,完整`dex`加载得到的`dexFile`对象作为参数构建`Element`对象然后整体替换掉原来旧的`dex-Element`数组,这样有个毛病就算是dex合并内存消耗在 `vm heap` 上,容易 `OOM`,最后导致`dex`合并失败。 `dex merge` 操作是在 `Java` 层面进行的,所有对象分配都是在 `Java heap` 上完成,如果进程申请超过 `vm heap`规定大小,那么进程就会发生`OOM`,系统 `memory killer` 可能会杀死该进程,导致`dex`合成失败。另外一方面,我们知道 `JNI` 层面 `C++ new/malloc`...