- 博客(32)
- 收藏
- 关注
原创 C++ > Cmake
根目录可以使用 CMake 的 add_subdirectory 添加子目录, 子目录也包含一个 CMakeLists.txt,其中定义的库在 add_subdirectory 之后就可以使用。调用编译器程序g++, 读取main.cpp中源码, 根据C++标准生成相应的机器指令码, 输出到a.out可执行文件。跨平台的 CMake 的产生, 只需编写CMakeLists.txt,就能够在调用时生成当前系统所支持的构建系统。在 C++ 中常常用到很多的类, 和函数一样, 类的声明也会被放到头文件中。
2023-05-30 19:14:50 628
原创 Android Binder原理
管道是Linux由Unix那里继承过来的进程间的通信机制,它是Unix早期的一个重要通信机制。管道的主要思想是,在内存中创建一个共享文件,从而使通信双方利用这个共享文件来传递信息。这个共享文件比较特殊,它不属于文件系统并且只存在于内存中。另外还有一点,管道采用的是半双工通信方式的,数据只能在一个方向上流动。信号是软件层次上对中断机制的一种模拟,是一种异步通信方式,进程不必通过任何操作来等待信号的到达。信号可以在用户空间进程和内核之间直接交互,内核可以利用信号来通知用户空间的进程发生了哪些系统事件。
2020-11-26 17:31:30 1494
原创 Android Activity Fragment
Activity的启动过程:由ActivityManagerService(AMS)对栈内的Activity状态进行同步管理 & 规定:新Activity启动前,栈顶的Activity必须先onPause(),才能启动新的Activity(执行onResume())ActivityStack类记录需启动的Activity的信息 & 调整Activity栈 将其置于栈顶、通过 Binder 驱动 将 Activity 的启动信息传递到ApplicationThread线程中(即Binder线程)
2020-11-26 15:38:11 398
原创 Java 数据结构
二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低为 O ( log n )。二叉查找树是基础性数据结构,用于构建更为抽象的数据结构,如集合、多重集、关联数组等。树是一种数据结构,它是n(n>=0)个节点的有限集。循环链表 能通过任何一个节点找到其他所有的节点,将两种(双向/单向)链表的最后一个结点指向第一个结点从而实现循环。区别于线性表一对一的元素关系,树中的节点是一对多的关系。树有许多相关的术语与概念,在学习树的结构之前,我们要熟悉这些概念。单向链表 一个节点指向下一个节点。
2020-11-24 10:38:10 206
原创 Android Handler机制
Handler 即处理器,常用于跨线程通讯:线程A 和线程 B 拥有同一个 handler 对象在线程 A 中使用 handler 的 sendMessage() 方法发送消息在线程 B 中使用 handler 的 handleMessage() 方法处理消息。
2020-11-17 11:52:04 542
原创 Android 如何使用AIDL
界面上有三个按钮,分别是功能分别是bindService(绑定Service), unbindService(解除绑定Service), killProcess(杀死Service进程)。本例是为了演示进程间的通信机制,故需要将Service与Activity处于不同的进程,需要在AndroidManifest.xml中,把service配置成。android.os.IBinder obj 如何得到 IRemoteService (android.os.IInterface)?,进程也可以命名成其他的。
2020-11-12 20:11:10 828
原创 C++ binder 实现自定义Android Native Service
代码很简单, 定义一个类继承自IInterface, 里面接口就是我们自己要用到的, 其中DECLARE_META_INTERFACE(DeviceMac);要实现跨进程, 自然是使用Binder了, 因此我们首先要定义一个用于跨进程的接口, 我们通过一个读取和设置蓝牙地址的例子为例, 来讲解具体实现方法, 接口名为。可以看到我们定义IDeviceMac后, 还定义了一个类BnDeviceMac,这个是Binder调用的一个规范, 即定义Ixxx接口后,Bpxxx和Bnxxx都需要我们去实现具体内容,
2020-11-12 19:25:15 867
原创 Launcher 启动过程
我们再回到ActivityManagerService的startHomeActivityLocked函数,假设系统的运行模式不是低级工厂模式,在注释3处判断符合Action为Intent.ACTION_MAIN,Category为Intent.CATEGORY_HOME的应用程序是否已经启动,如果没启动则调用注释4的方法启动该应用程序。被SystemServer进程启动的ActivityManagerService会启动Launcher,Launcher启动后会将已安装应用的快捷图标显示到界面上。
2020-11-12 11:11:39 724
原创 Android Jetpack
因为在Android Support Library 26.1.0 及其之后的版本,Activity和Fragment已经默认实现了LifecycleOwner接口,所以在注释1处可以直接使用getLifecycle方法获取Lifecycle对象,这样MyObserver就可以观察MainActivity的生命周期变化了,LifecycleOwner可以理解为被观察者,MainActivity默认实现了LifecycleOwner接口,也就是说MainActivity是被观察者。
2020-10-03 20:33:09 49
原创 Java 设计模式 结构型设计模式
鸭子(Duck)和火鸡(Turkey)拥有不同的叫声,Duck 的叫声调用 quack() 方法,而 Turkey 调用 gobble() 方法。要求将 Turkey 的 gobble() 方法适配成 Duck 的 quack() 方法,从而让火鸡冒充鸭子。RemoteControl 表示遥控器,指代 Abstraction。桥接模式将遥控器和电视分离开来,从而可以独立改变遥控器或者电视的实现。观看电影需要操作很多电器,使用外观模式实现一键看电影功能。TV 表示电视,指代 Implementor。
2020-08-20 16:26:37 35
原创 Android 手写实现简化版AMS
接口,它声明了跨进程通信需要实现的一系列抽象方法,实现了这个接口就说明可 以进行跨进程通信,所有的Binder。代理对象它同样实现 了IBinder。和 Server都要实现此接口。中拿到的实际上是这个代理对象。,在Binder.java。,IBinder的子类,对象从而完成跨进程间通信。,跨进程通信的Base。这个文件中还定义了一个。
2020-07-15 14:46:10 130
原创 Android系统启动 init zygote
init 启动 Zygote 时主要是调用 app_main.cpp 的 main 函数中的AppRuntime的 start 方法来启动 Zygote 进程的,我们就先从app_main.cpp 的 main函数开始分析,Zygote进程启动过程的时序图如图。init启动zygote时主要是调用app_main.cpp的main函数中的AppRuntime的start来启动zygote进程的,我们就从app_main.cpp的main函数开始分析,如下所示,
2020-07-13 18:00:03 303
原创 C++程序设计(II)兼谈对象模型(侯捷)—— 2.转换函数 conversion function & 3.non-explicit-one-argument ctor
基本只会在构造函数前面加这个关键字(模板中有一个也可以加这个关键字,但是很少人用)告诉编译器不要自动帮我做事情,等我真的调用构造函数的时候你再调用。这样上面的 4 不会自动变成Fraction。
2020-06-22 20:05:24 39
原创 网络专题 http 和 https
请求头中的If-Modified-Since:当需要再次请求服务器该资源的时候,客户端会将该资源的修改时间作为If-Midified-Since的值放到请求头,一起发送给服务器,服务器收到后返现有If-Modified-Since,则将该资源的最后修改时间与之对比,若最后修改时间较新,则说明资源又被修改过,则返回新资源,HTTP 200 OK;总体而言,HTTP 1.0和HTTP 1.1在性能和功能上有些局限性,而HTTP 2.0通过引入新的技术和改进,提高了性能和效率,并增加了新的功能。
2020-06-14 16:15:03 436
原创 Java 集合框架 ArrayList LinkedList
ArrayList实现了List接口,是顺序容器,即元素存放的数据与放进去的顺序相同,允许放入。
2020-06-12 09:49:54 42
原创 Android Handler native
从 Android 2.3 开始,Google 把 Handler 的阻塞/唤醒方案从 Object#wait() / notify(),改成了用 Linux epoll 来实现。
2020-06-07 14:18:31 980
原创 Android类加载器ClassLoader 和 热修复原理
PathClassLoader: 主要用于系统和app的类加载器,其中optimizedDirectory为null, 采用默认目录/data/dalvik-cache/DexClassLoader: 可以从包含classes.dex的jar或者apk中,加载类的类加载器, 可用于执行动态加载,但必须是app私有可写目录来缓存odex文件. 能够加载系统没有安装的apk或者jar文件, 因此很多插件化方案都是采用DexClassLoader;
2020-05-12 10:21:27 417
原创 Android 网络编程 > HTTP协议原理 > OkHttp > Retrofit
网络分层网络分层(此处5层)从上到下分别是应用层、传输层、网络层、数据链路层和物理层。越靠下的层 越接近硬件。接下来我们从下而上来分别了解这些分层。物理层该层负责比特流在节点间的传输,即负责物理传输。该层的协议既与链路有关,也与传输介质有关。其通俗来讲就是把计算机连接起来的物理手段。数据链路层该层控制网络层与物理层之间的通信,其主要功能是如何在不可靠的物理线路上进行数据的可靠传递。为了保证传输,从网络层接收到的数据被分割成特定的可被物理层传输的帧。
2020-04-13 14:36:30 1128 2
原创 Java>多线程编程
这两步操作在左边的线程执行完第一步,但还没执行第二步时右边的线程抢过CPU控制权开始完成+1的操作后写入到主内存,于是左边的线程工作内存中的count副本失效了,相当于左边这一次+1的操作就被覆盖掉了。,线程1会立即将自己工作内存的initFlag = false失效,当线程1的执行引擎需要用到initFlag变量时,线程1要重新执行read 和 load操作,那么线程1就能拿到最新值了。线程池对线程进行管理。如果两个线程存取相同的对象,并且每一个线程都调用了修改该对象的方法,这种情况通常被称为竞争条件。
2020-03-16 09:26:12 184 1
原创 Java 集合框架 Stack, Queue, Deque
操作,由于Deque是双向的,所以可以对队列的头和尾都进行操作,它同时也支持两组格式,一组是抛出异常的实现;是"double ended queue", 表示双向的队列,英文读作"deck". Deque 继承自 Queue接口,除了支持Queue的方法之外,还支持。的含义是“double ended queue”,即双端队列,它既可以当作栈使用,也可以当作队列使用。添加,删除,取值都有两套接口,它们功能相同,区别是对失败情况的处理不同。除非某种实现对容量有限制,大多数情况下,添加操作是不会失败的。
2020-03-14 11:07:26 281
原创 使用 Memory Analyzer ( MAT ) 工具分析内存 (二)
yml语言的配置debug: falseserver: port: 80spring: http: encoding: charset: utf-8 thymeleaf: cache: false mvc: date-format: yyyy-MM-dd
2020-01-19 10:32:22 1540
原创 使用 Memory Analyzer ( MAT ) 工具分析内存 (一)
使用 SDK 中的 hprof-conv.exe 工具 , 可以将上述 hprof 文件转为 MAT 工具可以识别的文件 , 工具所在目录的路径为 platform-tools , 将该目录配置到环境变量中 , 即可在命令窗口使用该工具。执行如下命令 : 将 memory-XXX.hprof 内存快照文件转换为 MAT 格式的内存文件 , 最终存储在 mat.hprof 文件中 , 其中加入 -z 选项 , 表示排除非 APP 内存信息;
2020-01-15 15:13:35 2921
原创 Java 设计模式 创建型设计模式
抽象工厂模式创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。而工厂方法模式只是用于创建一个对象,这和抽象工厂模式有很大不同。抽象工厂模式用到了工厂方法模式来创建单一对象,AbstractFactory 中的 createProductA() 和 createProductB() 方法都是让子类来实现,这两个方法单独来看就是在创建一个对象,这符合工厂方法模式的定义。
2019-12-12 18:01:54 42
原创 JUC线程池: ThreadPoolExecutor详解
程序中我们创建了固定大小为五个工作线程的线程池。然后分配给线程池十个工作,因为线程池大小为五,它将启动五个工作线程先处理五个工作,其他的工作则处于等待状态,一旦有工作完成,空闲下来工作线程就会捡取等待队列里的其他工作进行执行。输出表明线程池中至始至终只有五个名为 "pool-1-thread-1" 到 "pool-1-thread-5" 的五个线程,这五个线程不随着工作的完成而消亡,会一直存在,并负责执行分配给线程池的任务,直到线程池消亡。Java是如何实现和管理线程池的?这里是以上程序的输出。
2019-11-07 20:04:12 175
原创 Java JUC
是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值,经过调查发现,其实现方式是基于硬件平台的汇编指令,就是说CAS是靠硬件实现的,JVM只是封装了汇编调用,那些AtomicInteger类便是使用了这些封装后的接口。简单解释:CAS操作需要输入两个数值,一个旧值(期望操作前的值)和一个新值,在操作期间先比较下在旧值有没有发生变化,如果没有发生变化,才交换成新值,发生了变化则不交换。CAS操作是原子性的,所以多线程并发使用CAS更新数据时,可以不使用锁。
2019-11-03 11:18:15 592
原创 Java 面向对象 UML 类图
表示不同类对象之间有关联,这是一种静态关系,与运行过程的状态无关,在最开始就可以确定。比如学生和学校就是一种关联关系,一个学校可以有很多学生,但是一个学生只属于一个学校,因此这是一种多对一的关系,在运行开始之前就可以确定。和聚合不同,组合中整体和部分是强依赖的,整体不存在了部分也不存在了。但是公司和员工就属于聚合关系了,因为公司没了员工还在。和关联关系不同的是,依赖关系是在运行过程中起作用的。表示整体由部分组成,但是整体和部分不是强依赖的,整体不存在了部分还是会存在。
2019-10-31 15:37:15 133
原创 Java 垃圾回收
给对象添加一个引用计数器,当对象增加一个引用时计数器加 1,引用失效时计数器减 1。引用计数为 0 的对象可被回收。两个对象出现循环引用的情况下,此时引用计数器永远不为 0,导致无法对它们进行回收。正因为循环引用的存在,因此 Java 虚拟机不使用引用计数算法。通过 GC Roots 作为起始点进行搜索,能够到达到的对象都是存活的,不可达的对象可被回收。无论是通过引用计算算法判断对象的引用数量,还是通过可达性分析算法判断对象是否可达,判定对象是否可被回收都与引用有关。
2019-07-22 16:56:04 67
原创 Java 集合框架 HashSet & HashMap
默认的负载因子大小为 0.75,也就是说,当一个 map 填满了 75% 的 bucket 时候,和其它集合类(如 ArrayList 等)一样,将会创建原来 HashMap 大小的两倍的 bucket 数组,来重新调整 map 的大小,并将原来的对象放入新的 bucket 数组中。这个过程叫作 rehashing因为它调用 hash 方法找到新的 bucket 位置。
2019-07-08 20:14:53 252
原创 Android View体系
View的工作流程,指的就是measure、layout和draw其中,measure用来测量View的宽和高,layout用来确定View的位置,draw则用来绘制View。
2019-06-29 17:53:57 279
原创 Java synchronized
JVM 堆中所有对象分配的内存字节总数必须是 8N,如果对象头和实例数据占用的总大小不满足要求,则需要通过对齐数据来填满。有争用 - 锁升级为轻量级锁 - 每个线程有自己的LockRecord在自己的线程栈上,用CAS去争用markword的LR(Lock Record)的指针,指针指向哪个线程的LR,哪个线程就拥有锁。偏向锁 - markword 上记录当前线程指针(JavaThread*),下次同一个线程加锁的时候,不需要争用,只需要判断线程指针是否同一个,所以,偏向锁,偏向加锁的第一个线程。
2019-06-28 15:56:20 93
原创 解决android studio Could not GET 'https://dl.google.com/dl/android/maven2
解决android studio Could not GET 'https://dl.google.com/dl/android/maven21. http proxy 选择 No proxy 模式2. 修改gradle配置文件找到C:\Users\Administrator\.gradle\gradle.properties 配置文件, 去掉多余的代理配置...
2019-06-11 15:24:52 5521 9
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人