- 博客(1753)
- 资源 (224)
- 问答 (1)
- 收藏
- 关注
原创 面试知识点:notify是随机唤醒线程吗(唤醒线程顺序)?
notify 唤醒线程的规则是随机唤醒还是顺序唤醒取决于 JVM 的具体实现,作为主流的 HotSpot 虚拟机中的 notify 的唤醒规则是顺序的,也就是 notify 会按照线程的休眠顺序,依次唤醒线程。
2024-01-24 11:24:27 619
转载 java注解的详细使用(APT、插桩、反射)
什么是apt:APT,就是Annotation Processing Tool的简称,就是可以在代码编译期间对注解进行处理,并且生成Java文件,减少手动的代码输入。注解我们平时用到的比较多的可能会是运行时注解,比如大名鼎鼎的retrofit就是用运行时注解,通过动态代理来生成网络请求。编译时注解平时开发中可能会涉及的比较少,但并不是说不常用,比如我们经常用的轮子Dagger2, ButterKnife, EventBus3 都在用,所以要紧跟潮流来看看APT技术的来龙去脉。
2024-01-17 22:24:08 143
转载 24张图带你彻底理解Java中的21种锁
为了提高性能, Java 提供了读写锁,在读的地方使用读锁,在写的地方使用写锁,灵活控制,如果没有写锁的情况下,读是无阻塞的,在一定程度上提高了程序的执行效率。现在绝大多数的个人电脑和服务器都是多路(核)处理器系统,如果物理机器有一个以上的处理器或者处理器核心,能让两个或以上的线程同时并行执行,就可以让后面请求锁的那个线程“稍等一会”,但不放弃处理器的执行时间,看看持有锁的线程是否很快就会释放锁。多个线程获取锁的顺序,不是按照先到先得的顺序,有可能后申请锁的线程比先申请的线程优先获取锁。
2024-01-15 12:05:16 277
转载 理解AQS的原理及应用总结
AQS全称为AbstractQueuedSynchronizer,是Java中用于构建锁和同步器的框架性组件,它是Java并发包中ReentrantLock、Semaphore、ReentrantReadWriteLock等同步器的基础。在开发中,我们可以利用AQS提供的同步机制来实现线程的协作和同步,从而达到线程安全的目的。使用ReentrantLock实现同步:ReentrantLock是一个可重入独占锁,可以使用它来实现线程的同步。
2024-01-11 13:12:03 661
原创 可重入锁和不可重入锁
如果把证件/卡看作是同步锁,把关卡看作是同步域(即同步代码块/方法或显式锁锁定的代码),那么可重入锁指的是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁,这样的锁就叫做可重入锁。Reentrant = Re + entrant,Re是重复、又、再的意思,entrant是enter的名词或者形容词形式,翻译为进入者或者可进入的,所以Reentrant翻译为可重复进入的、可再次进入的,因此ReentrantLock翻译为重入锁或者再入锁。
2024-01-10 19:06:50 1191
原创 java并发之阻塞队列ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue和非阻塞队列ConcurrentLinkedQueue
基于单向链表实现,使用volatile保证可见性,使得在读场景下不需要使用其他同步机制;使用乐观锁CAS+失败重试保证写场景下操作的原子性使用延迟更新首尾节点的思想,大大减少CAS次数,提升并发性能;使用哨兵节点,降低代码复杂度,避免一个节点时的竞争在入队操作时,会在循环中找到真正的尾节点,使用CAS添加新节点,再判断是否CAS更新尾节点tail在入队操作的循环期间一般情况下是向后遍历节点,由于出队操作会构建哨兵节点,当判断为哨兵节点(next指向自己)时,根据情况定位到尾节点或头节点(“跳出”)
2024-01-10 14:37:36 1004
原创 Queue接口分析
区分阻塞队列和非阻塞队列的关键因素是什么?按照大多数文章的介绍,阻塞队列支持阻塞特性,在队列满或为空时会阻塞,但是我想到队列必须是线程安全的,阻塞队列(前文表格中的那5个阻塞队列)都是利用悲观加锁,互斥做到线程安全的,貌似加锁在某种程度上也等价于阻塞,巧合的是非阻塞队列(比如ConcurrentLinkedQueue)又是利用乐观锁实现线程安全的,乐观锁可以理解成未加锁。在《JAVA中的阻塞队列和非阻塞队列》一文中,介绍非阻塞队列时有如下:基于锁的算法会带来一些活跃度失败的风险。
2024-01-10 13:05:30 901
转载 深入了解java虚拟机
1、程序计数器是线程私有,描述的是当前线程下一条需要执行的字节码指令行号;2、虚拟机栈描述的是 Java 方法执行的内存模型;3、本地方法栈与虚拟机栈类似,区别在于虚拟机栈执行 Java 方法,而本地方法栈执行 native 方法;4、堆是虚拟机上最大的一块内存,绝大多数对象都是存储在堆上的,垃圾回收机制操作的主要区域也是堆;5、方法区主要存放虚拟机加载的类相关数据。垃圾回收机制(Garbage Collection,GC)
2024-01-10 00:16:17 71
转载 Android Realm数据库使用
也就是说,Realm实例在线程中,如果没有Looper,是不能收到更新通知的,list.add(new TestUser(2,"adidass", "110119", 28, "云南德克萨斯州", "海员", "男"));list.add(new TestUser(0,"android", "123123", 20, "河南常德", "传菜员", "女"));list.add(new TestUser(4,"hibrid", "120250", 26, "赣州", "贼", "男"));
2023-12-22 21:03:36 540
转载 Android Jetpack框架-LiveData和Room使用
LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。如果观察者(由 Observer 类表示)的生命周期处于 STARTED 或 RESUMED 状态,则 LiveData 会认为该观察者处于活跃状态。LiveData 只会将更新通知给活跃的观察者。
2023-12-22 20:43:58 223
转载 Java内存模型
误解:volatile修饰的变量保证了对所有线程的可见性,所以基于volatile修饰的变量的运算在并发下是线程安全的。这个观点的论据是正确的,但是根据论据得出的结论是错误的,并不能得出这样的结论。volatile的规则保证了read、load、use的顺序和连续性,同理assign、store、write也是顺序和连续的。也就是这几个动作是原子性的,但是对变量的修改或者对变量的运算,却不能保证是原子性的。
2023-12-18 19:39:57 180 1
转载 ASM 插桩采集方法入参,出参及耗时信息
ASM字节码插桩技术在Android开发中有着广泛的应用,但相信很多人会不知道怎么上手,不知道该拿ASM来做点什么。学习一门技术最好的方法就是动手实践,本文主要通过ASM插桩采集方法的入参,出参及耗时信息并打印,通过一个不大不小的例子快速上手ASM插桩开发。通过上述步骤,我们就把ASM插桩实现记录方法入参,返回值以及方法耗时的功能完成了,通过插桩可以在方法执行的时候输出我们需要的信息。而这些信息的价值就是可以很好的让我们做一些程序的全链路监控以及工程质量验证。
2023-12-16 21:29:38 151
转载 Android 启动优化-有向无环图
说到 Android 启动优化,大家第一时间可能会想到异步加载。将耗时任务放到子线程加载,等到所有加载任务加载完成之后,再进入首页。多线程异步加载方案确实是 ok 的。但如果遇到前后依赖的关系呢。比如任务2 依赖于任务 1,这时候要怎么解决呢。最简单的方案是将任务1 丢到主线程加载,然后再启动多线程异步加载。如果遇到更复杂的依赖呢。任务3 依赖于任务 2, 任务 2 依赖于任务 1 呢,这时候你要怎么解决。更复杂的依赖关系呢。
2023-12-16 13:17:08 159 2
转载 Flutter插件的制作和发布
注意圈着的部分,工程类型一定要选择Plugin,然后填写包名,选择开发语言,对于开发语言的选择有几点建议:如果你将要制作的插件没有引入第三方sdk,或者只引入了一些工具类的库,那么根据你熟悉或喜欢的语言随意选择;我们在用xcode打开ios工程前,要确保你的mac中已经安装了flutter和cocoapods环境,因为flutter plugin是以pods方式集成的,确认没问题后,可以先使用mac端AS打开项目,并运行,这时AS会自动执行pod install,并自动配置项目的xcode环境。
2023-12-12 23:07:49 252
转载 Flutter Native 插件开发 (Android)
这三种方式,无论是传递方法还是事件,本质上都是传递的数据。具体使用哪种通信方式,要看使用场景,同一种功能可以通过不同的方式来实现。比如获取手机电量,网络变化等可以通过。
2023-12-12 18:25:22 221
转载 Flutter 自定义插件基础
BasicMessageChannel:用于传递字符串和半结构化的信息MethodChannel:用于传递方法调用(method invocation)EventChannel: 用于数据流(event streams)的通信MethodChannel总共有3个成员变量在Flutter中会存在多个Channel,一个Channel对象通过name来进行唯一的标识,所以在Channel的命名上一定要独一无二,推荐采用组件名_Channel名 组合来进行命名。
2023-12-12 18:00:20 189
转载 Android APT从入门到实战
APT可以在编译器扫描注解帮我们提前生成类JavaPoet可以帮我们优雅的生成类,再也不用拼接了APT最主要的功能就是可以替代反射的一些功能,避免降低性能APT只会在编译时影响一点点速度,在运行期不会,而反射刚好相反。
2023-11-30 14:13:39 377
转载 浅谈 ViewModel 的生命周期控制
以上就是 ViewModel 的生命周期的总结。我们只是通过对主流程的分析研究了它的生命周期的流程,实际上内部还有许多小细节,逻辑也比较简单,我们就不一一说明了。其实,从 Google 的官方文档中,我们也能够得到上面的总结,这里使用了,也就是 Activity 处于前台的时候配置发生变化的情况,而不是处于后台,不知道你之前有没有注意这一点呢?
2023-11-28 15:12:58 363
原创 Android使用AIDL+MemoryFile传递大数据
Android进程间通信经常会使用AIDL,简单方便,但是数据量有限制,超过一定值会报错:E!!!!!可以通过使用AIDL+MemoryFile传递大数据。
2023-11-23 22:53:59 907
原创 Android MemoryFile 共享内存
网上很多时间比较久的贴子,通过各种反射在A进程获取MemoryFIle来读取共享数据,这种方式并不可取;MemoryFile新版本的封装方式就体现了它的使用方式,Google是希望随时使用随时创建MemoryFile并把文件描述附共享出去这种方式来实现功能的。Android内存映射文件实现1. 什么是内存映射文件内存映射文件是一种将磁盘上的文件映射到内存中的方法。通过内存映射文件,可以将文件的内容直接映射到内存中的一个地址空间,从而可以直接对内存进行读写操作,而无需通过传统的文件IO操作。
2023-11-23 22:41:00 1806
原创 Android 匿名内存深入分析
共享简单的实现方式就是通过mmap同一个文件来实现。但是真实文件的读写速度实在是太慢了,所以利用tmpfs这个虚拟文件系统,创建了一个虚拟文件来读写。同时这块虚拟内存在上面也写到重写了vm_ops。当有进程操作这个虚拟内存的时候会触发缺页错误,接着会去查找Page缓存,由于是第一次所以没有缓存,读取物理内存,同时加入Page缓存,当第二个进程进来的时也触发缺页错误时就能找到Page缓存了,那么他们操作的就是同一块物理内存了。看完之后发现AshMemory是基于Linux的共享内存实现的。做了几点改造。
2023-11-23 22:32:54 1428
转载 Android多进程
经过模块解耦,开辟新的进程,独立的JVM,来达到数据解耦目的。解析:绑定服务端的Service,绑定成功后,将服务端返回的Binder对象转成AIDL接口所属的类型,然后就可以调用AIDL中的方法了,客户端调用远程服务的方法,被调用的方法运行在服务端的Binder线程池中,同时客户端的线程会被挂起,如果服务端方法执行比较耗时,就会导致客户端线程长时间阻塞,导致ANR,客户端的onServiceConnected和onServiceDisconnected方法都在UI线程中。
2023-11-23 22:09:57 325
原创 怎样用AIDL Service 传递复杂数据
1.在客户端新建一个包,命名需要和服务端放置aidl文件的包名相同(我这里是com.example.remoteservice),然后把服务端的Person.java,Pet.java,Person.aidl,Pet.aidl,IPet.aidl复制到这个包下面。大家都知道在Android中通过AIDL可以跨进程调用Service中的数据,网上也有很多实例,但是大部分实例都是关于基本数据类型的远程调用,很少讲到复杂数据的调用,今天我用一个例子来演示一下怎样用AIDL Service 传递复杂数据。
2023-11-23 21:43:55 561
转载 Android跨进程传大图思考及实现——附上原理分析
在文章开头,我们举的例子中:通过Intent去传递一个Bitmap,在执行到Instrumentation#execStartActivity的时候,我们发现Intent有个prepareToLeaveProcess方法,在此方法里面调用了Bundle#setAllowFds(false)上面测试的时候,超出200k数据传递的时候,LogCat已经给我们打印提示“Transaction too large”了,但是只要没有超出异步事务空闲的缓冲区大小,就不会崩溃;先别着急着下结论,继续往下看👇👇。
2023-11-23 16:23:34 150
原创 Android跨进程传图片或者大数据(解决TransactionTooLargeException)
优势效率相对最高传递图片没有大小限制劣势使用相对麻烦,需要自定义aidl相关代码可能有侵入性,必须在四大组件中接收。/***/
2023-11-22 15:29:55 1000
原创 Flutter StreamBuilder 实现局部刷新 Widget
当widget需要进行刷新时,我们可以通过调用widget的setState方法来实现,setState随后会调用State的build方法来进行重建。那么,如果 我们能将 build方法中的 return new Text(_text) 暴漏出去,我们就可以实现通用的 局部刷新 Widget。Stream 就是事件流或者管道,是基于事件流驱动设计代码,然后监听订阅事件,并针对事件变换处理响应。Flutter StatefulBuilder 用来实现局部数据刷新。本页面实现 Demo 效果如下。
2023-11-09 15:54:26 777
转载 Flutter:WebSocket封装-实现心跳、重连机制
Http协议是无状态的,只能由客户端主动发起,服务端再被动响应,服务端无法向客户端主动推送内容,并且一旦服务器响应结束,链接就会断开(见注解部分),所以无法进行实时通信。WebSocket协议正是为解决客户端与服务端实时通信而产生的技术,现在已经被主流浏览器支持,所以对于Web开发者来说应该比较熟悉了,Flutter也提供了专门的包来支持WebSocket协议。
2023-11-08 21:43:40 1678
转载 从 Java 字节码到 ASM 实践
AOP(面向切面编程)的概念现在已经应用的非常广泛了,下面是从百度百科上摘抄的一段解释,比较浅显易懂面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
2023-11-02 18:39:32 132
转载 ASM 库的介绍和使用
如下所示,在 ClassVisitor 中提供了和类结构同名的一些方法,这些方法会对类中相应的部分进行操作,而且是有顺序的:visit [ visitSource ] [ visitOuterClass ] ( visitAnnotation | visitAttribute )* (visitInnerClass | visitField | visitMethod )* visitEnd......该方法是当扫描类时第一个调用的方法,主要用于类声明使用。
2023-11-02 18:32:31 634
转载 认识 .class 文件的字节码结构
写一个简单的 Demo.java 程序如下所示使用 javac 命令编译 Demo.java 文件生成 Demo.class 文件接着用文本编辑器打开生成的 Demo.class 文件,如下所示可以看到,该文件中是由十六进制符号组成的,这一段十六进制符号组成的长串是遵守 Java 虚拟机规范的魔数(Magic Number):.class 文件的第 1 - 4 个字节,它唯一的作用就是确定这个文件是否是一个能被虚拟机接受的 class 文件,其固定值是:0xCAFEBABE(咖啡宝贝)。
2023-11-02 16:03:15 77
转载 Android 性能优化系列 - 04 Matrix 中 TraceCanary 源码解析
在做 UI 性能优化的时候,很重要的一点就是需要做好优化前和优化后的对比,否则怎么判断自己的优化是否有效果,效果有多大呢?对比的话,个人认为可以分为两类,一类是通过观察直观的对比,另一类是通过数据客观的对比直观对比,我们可以通过开发者选项中的过渡绘制和GPU 分析查看页面中是否存在过渡绘制和 UI 渲染时的 GPU 渲染图客观对比,我们可以通过各种测试工具分析、对比,比如网易的Emmagee、腾讯的matrix。
2023-11-02 13:42:29 189
转载 Android 性能优化系列 - 03 使用对象池优化内存
避免在循环里面或者频繁被调用的方法里面创建对象,在循环或者被频繁调用的方法之外创建对象使用对象池缓存对象,在使用对象的时候,直接从对象池中取对象即可,避免频繁的创建对象一般来讲,实现对象池有三种方法,对应的具体的数据结构即是数组、链表和 Map,下面我将通过示例分别介绍通过这三种数据结构实现的对象池首先是Pool<T>接口定义,代码不难,如下所示,只有两个方法acquire()和方法acquire():从对象池中取一个对象,注意:有可能会返回 null:将一个对象释放到对象池中,
2023-11-02 13:36:11 337
转载 Android 性能优化系列 - 02 理解 systrace
在上篇文章中已经介绍过了,systrace 本质上是对其他工具的封装,包括 PC 端的 atrace 和设备端的 ftrace,ftrace 是 Linux 内核中的主要跟踪机制。systrace 使用 atrace 开启追踪,然后读取 ftrace 的缓存,并且把它重新转换成HTML格式。
2023-11-02 13:27:18 194
转载 Android 性能优化系列 - 01 手把手教你使用 systrace
性能优化是 Android 中的一个重要知识,也是衡量一个 Android 工程师水平的重要依据,简单的性能优化,可能很多人都会。比如以下几个优化 UI 渲染的方法,想必很多人都知道使用“设置 --> 开发者选项 --> 调试 GPU 过度绘制”,根据屏幕显示的不同颜色来区分是存在过度绘制,从而排查该界面的 xml 文件,去除不必要的 background,消除过度绘制通过。
2023-11-02 12:20:25 1008
原创 ContentProvider的执行时机
这里先给出源码分析的结论:ContentProvider 的 onCreate() 方法先于 Application 的 onCreate() 方法执行,晚于Application的onAttachContext()方法执行。
2023-10-23 11:12:01 179
转载 Android中SPI思想应用与改进
在自定义的gradle任务中,遍历所有的二进制文本文件无论是class格式还是jar格式,查找注解标注的类,以../app/build/intermediates/javac/{variant}作为注册表类的存放目录,并仿照JDK中META-INF/services格式,在../app/build/intermediates/spi/debug/services目录下生成遍历生成的KV文件。目前掌握的需求场景有两种:1). 插件场景,调用方定义接口,实现方提供接口实现,将装配的控制权移到调用方模块之外。
2023-10-23 11:00:55 259
原创 Flutter 单线程模型保证UI运行流畅
好了,今天关于 Dart 的异步与并发机制、实现原理的分享就到这里了,我们来简单回顾一下主要内容。Dart 是单线程的,但通过事件循环可以实现异步。而 Future 是异步任务的封装,借助于 await 与 async,我们可以通过事件循环实现非阻塞的同步等待;Isolate 是 Dart 中的多线程,可以实现并发,有自己的事件循环与 Queue,独占资源。Isolate 之间可以通过消息机制进行单向通信,这些传递的消息通过对方的事件循环驱动对方进行异步处理。
2023-07-19 19:56:29 2420 2
转载 一次Binder通信最大可以传输多大的数据?
在第六章中,我通过匿名共享内存的方式解决Binder通信是无法传递大数据的问题,一次Binder通信最大可以传输是1MB-8KB(PS:8k是两个pagesize,一个pagesize是申请物理内存的最小单元)但是这个答案对不对呢,我只能说不准确,接下来我们来仔细研究一下。
2023-04-20 21:38:17 1463
转载 Flutter渲染之Widget、Element 和 RenderObject
上面通过源码讲解了一下 Widget、Element、RenderObject 的联系。下面简单来个总结。我们写好 Widget 树后,Flutter 会在遍历 Widget 树时调用 Widget 里面的 createElement 方法去生成对应节点的 Element 对象,同时 Element 里面也有了对 Widget 的引用。
2023-04-04 12:10:48 1487 1
Android将list数据通过LitePal保存到本地(集合保存到本地)
2016-06-17
AndroidDownLoad-多线程断点续传下载
2016-06-14
DownloadEngine-Android多线程下载断点续传
2016-06-14
android-rsa-http
2016-06-12
RxJava在Android中内存泄漏解决以及RxJava的封装
2016-05-23
Android H5做的商城客户端
2016-04-29
Android通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比
2016-03-31
Android Bluetooth蓝牙通信文件传输
2016-03-27
Android蓝牙聊天程序的扩展开发(基于Google Sample,类QQ设计)
2016-03-26
Android蓝牙聊天程序优化版
2016-03-26
Android 通过Socket 和服务器通讯
2016-02-16
android RangeSeekBarView 选定范围值的控件
2016-02-01
Android仿天天动态上拉播放界面控件
2016-01-31
Flutter编程指南-多线程
2022-02-21
java数据结构与算法之美(物超所值)
2022-02-09
flutter_macos_2.8.1-stable.zip
2022-01-05
mac_apktool.zip
2021-03-25
Postman-osx-5.3.2 for Mac
2017-10-31
CoordinatorLayout+AppBarLayout实现上滑隐藏ToolBar
2016-08-19
android自定义进度条渐变色View的实例代码
2016-07-26
Android多行文本折叠展开效果
2016-07-25
Android封装popwindow类(下拉菜单弹出和收缩效果)
2016-07-22
Android自定义spinner下拉框
2016-07-16
Android DigitalClock实现倒计时
2016-07-12
Android 带箭头有光晕效果的ProgressBar
2016-07-04
android webview与 js交互通信
2016-06-20
Android项目webview中做与js交互
2016-06-20
Android客户端提供Socket服务与pc通过USB通信
2016-06-17
Android 使用Socket,ServerSocket编程网络通信
2016-06-17
Android socket即时通信Demo
2016-06-17
自定义view和自定义动画怎么学习比较好呢?
2016-11-16
TA创建的收藏夹 TA关注的收藏夹
TA关注的人