自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

qq_34888036的博客

好好学习

  • 博客(194)
  • 收藏
  • 关注

原创 pthread_key_t和pthread_key_create()详解

现在有一全局变量,所有线程都可以使用它,改变它的值。表面上看起来这是一个全局变量,所有线程都可以使用它,而它的值在每一个线程中又是单独存储的。这就是线程存储的意义。该函数有两个参数,第一个参数就是上面声明的pthread_key_t变量,第二个参数是一个清理函数,用来在线程释放该线程存储的时候被调用。该函数有两个参数,第一个为前面声明的pthread_key_t变量,第二个为void*变量,这样你可以存储任何类型的值。该函数的参数为前面提到的pthread_key_t变量,该函数返回void *类型的值。

2023-10-24 13:18:07 373

原创 binder通信之Messenger介绍

Messenger是什么?Messenger是基于AIDL实现的轻量级IPC方案。这里立马就会有疑问为什么要它呢?明明有了aidl上节课大家学完了aidl进行binder通信是否感觉到使用起来其实还是有点复杂,毕竟通信什么的要写aidl,而且客户端和服务端都需要aidl文件,两个过程里面都需要,相对来说还是比较麻烦,对于项目过程中可能就是一些简单的跨进程数据传递,就是调用几个非常非常简单的方法,很多觉得都要写aidl成本比较大,那么有没有更加简单的方案来解决这个问题呢?

2023-10-11 23:23:47 230

原创 Android之getSystemService方法实现详解

什么是系统服务?为什么要使用系统服务我们在Android开发过程中经常会用到各种各样的系统管理服务,比如对Wifi进行操作时需要使用到WifiManager,对电源进行操作就需要使用到PowerMaager,对于电池得操作就需要使用到BatterManager…可以说,系统服务时Android对于我们开发者所提供的能够对于系统底层进行配置操作的一种方式。了解这些系统服务,对于我们安卓的开发使用起着至关重要的作用。//获取电源相关的服务。

2023-10-08 13:52:02 2355 1

原创 classloader的讲解

从这段源码可以看出,dexElements是用来保存dex的数组,而每个dex文件其实就是DexFile对象。我们通过上面代码发现最终是通过classloader.loadClass(className).newInstance()来进行Activity类的实例化的。classloader通过java.lang.ClassLoader cl = appContext.getClassLoader()构造。

2023-08-20 15:19:55 126

原创 Android模板设计模式之 - 构建整个应用的BaseActivity

模式的定义定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。模式的使用场景1.多个子类有公有的方法,并且逻辑基本相同时。2.重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。3.重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约束其行为。

2023-08-09 23:34:35 983 1

原创 自己动手打造一套IOC注解框架

那么什么是IOC,控制反转(Inversion of Control,英文缩写为IOC),其实就是反射加注解如果你学过Java后台这个在三大框架中会经常使用。过多的去解释其实也没什么意思,我们主要来看有什么用处。今天主要讲的就是Android中IOC框架就是注入控件和布局或者说是设置点击监听,如果你用过xUtils,afinal,butterknife类的框架,你肯定不陌生~

2023-08-09 00:03:08 174

原创 AppCompatActivity.setContentView(与activity.setContentView区别)方法解读

/设置要显示视图的布局ID或者View @Override public void setContentView(@LayoutRes int layoutResID) {实现了三个重载的setContentView方法,getDelegate()方法负责创建Activity的代理类实例,然后调用setContentView方法添加显示的视图,Activity通过代理模式添加要显示的视图;然后看看这个里面是从哪里来的?这是这个的一个函数,可以看看这个类是做什么用的。

2023-08-01 01:03:28 166

原创 onTouchEvent浅析

我们接着上次的自定义星星来作讲解当 onTouchEvent 返回 super.onTouchEvent ( false ) 时第一次会执行 DOWN 事件,DOWN 事件返回 false 之后,之后的 MOVE 事件和 UP 事件并没有触发。因为触摸时候存在子 View 所以会调用 child.dispatchTouchEvent(event)。

2023-07-29 13:50:29 278

原创 自定义 View(六) 自定义评分星星

创建 View Class创建 attr 属性文件,确定属性View Class 绑定 attr 属性onMeasure 测量onDraw 绘制onTouchEvent ( 用户交互需要处理 )

2023-07-28 20:30:32 197

原创 自定义view - 炫酷进度条

1>:自定义属性:内圆颜色、外圆颜色、圆弧宽度、中间文字颜色、文字大小;4>:onDraw:所有绘制代码都写在onDraw方法中;1>:values__attrs.xml,自定义属性;3>:onMeasure:不是非必须的,测量控件大小;2>:自定义ProgressBar,继承View;2>:在第三个构造方法中,获取自定义属性;

2023-07-27 08:17:51 96

原创 自定义view - 玩转字体变色

自定义View步骤:1>:values__attrs.xml,定义自定义属性;2>:在第三个构造方法中获取自定义属性;3>:onMeasure【不是必须的】;4>:onDraw:绘制代码全都在onDraw中写的;这篇文章主要是结合属性动画自定义一个文字变色的view。先来看效果图。技术分析:不能用TextView,因为系统的TextView只能有一种颜色,需要ColorTraceTextView,继承TextView,而不是继承View,原因是:1>:继承TextView不用自己手动实现on

2023-07-25 22:14:05 688

原创 Android自定义View03-实现弧形进度条效果

1.创建一个自定义View : QQStepView,让所有的构造方法都执行到同一个,并且在这个构造方法中去获取xml里设置的属性。想让内圈弧形动起来,就要修改不断的内圈圆弧的绘制角度,提供两个设置方法,去设置最大值和当前值。使用了属性动画来生成当前值(2s内从0增长到3000),生成设置给QQStepView。2.重写onMeasure()方法,确定view的宽高,保证是个正方形。外圈颜色、内圈颜色、弧宽度、数字文本大小、数字文本颜色。写到这里,就能绘制出初始图形了。在外部调用这两个方法。

2023-07-21 01:01:47 513 2

原创 Android ViewGroup onDraw为什么没调用

若要ViewGroup onDraw() 执行,只需要 setWillNotDraw(false) 、设置背景、设置前景、设置焦点高亮, 4 个选项其中一项满足即可。当然也可以重写dispatchDraw()方法,在该方法里绘制自定义view的内容。

2023-07-18 23:54:36 1082

原创 自定义view(一)----自定义TextView

android : layout_width = "wrap_content" android : layout_height = "wrap_content" android : background = "#FF0000" app : wqqinputType = "number" app : wqqtext = "我是安徽人" android : padding = "50dp" app : wqqtextSize = "20sp" / >

2023-07-18 23:11:49 1101

原创 自定义View简介 - onMeasure,onDraw,自定义属性

(后面会分析View的绘制流程源码,会有些许差别)。对于自定义View其实有一些套路,比如onMeasure(),onDarw(),onTouch(),自定义属性,我们需要知道是用来干什么的,剩下就是一些逻辑代码了,其实也很简单。主要用来绘制效果,里面会有一个参数那就是canvas画布,利用canvas就可以画各式各样的效果,如:canvas.drawCircle()画圆形,canvas.drawBitmap()画bitmap,我们这里肯定是需要画文字,那就是drawText()画文本。

2023-07-18 13:00:59 100

原创 UI的绘制流程

所以ActivityThread是一个handler,不停的接收AMS或者PMS发来的信息,进行操作处理。每个App都是一个独立的进程,当一个app启动的时候,当前进程也被启动,在Android中有一个类ActivityThread,就是进程的初始类,其中main方法就是整个app的入口。在onCreate方法中,主要做的工作就是将我们自己的写的XML布局,加载到了DecorView当中,其实这只是一个开始,还需要对布局进行测试绘制,才能展示到手机上,这个过程,是在onResume生命周期中完成。

2023-07-03 00:17:25 343

原创 eventfd 和 epoll 的结合使用

这是因为,假如没有设置EPOLL_CLOEXEC标志的fork将把描述符复制到子进程中的epoll实例,当这些进程中的某一个或者多个进程关闭了其中一个文件描述符,那么可能会导致程序的不可用,或者不在我们的预期之内。size参数向内核指定内核进程需要监控的文件描述符的个数,这有助于内核决定epoll实例的大小。进程通过调用epoll_create来创建epoll实例,后续通过epoll返回的指向epoll实例的文件描述符来进行各种操作,比如添加、删除或者修改它想要件事epoll实例的I/O的其他文件描述符。

2023-05-31 00:04:46 1251

原创 安卓的智能指针:sp和wp

PS:在Android native代码中,一般的对象指针都已经被sp、wp等代替了,用了它们,我们无需手动去回收指针对象,这样极大地提升了程序的稳定性。而在大多数的native程序中,sp、wp都只是一个代替普通指针的工具,我们能了解它的原理更好,不了解的话,就把它们当中普通指针来看待就行了。定义一个RefBase的子类类型,作为sp、wp的模板类型,并创建它的一个指针对象。这样,所有的对象都已经删除掉。代码中给该对象的强弱引用计数值都自加了1,此时就对象的强引用计数值为1,弱引用计数值为2了。

2023-05-21 17:20:50 1041

原创 安卓12源码编译错误-java.lang.OutOfMemoryError: Java heap space

swap是啥大家自己百度哈,大概就是用电脑硬盘当内存用。系统重启,则需要重新挂载swap文件。2.2、将文件格式化为swap文件。步骤一:设置swap内存。2.3、挂载swap文件。

2023-04-23 22:55:38 2694 1

原创 I2C通信原理

在起始信号后必须传送一个从机的地址(7位),第8位是数据的传送方向位(R/T),用“0”表示主机发送数据(T),“1”表示主机接收数据(R)。每个接到I2C总线上的器件都有唯一的地址。连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA及SCL都是线“与”关系。I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。I2C总线上传送的数据信号是广义的,既包括地址信号,又包括真正的数据信号。

2023-03-07 23:23:26 1918

原创 Binder系统-C程序示例_框架分析

首先先打开驱动,并且告诉驱动他是servicemanager,这样他就有了驱动的操作权限,并且他是是一个while(1)循环,不停的读取数据,解释数据,如果有需要注册服务,则保存注册的服务到链表中,如果有需要获取服务,则从链表查询服务返回,在没有事情做的时候会处于休眠状态。分析了注册服务和获取服务的大致过程,我们现在来分析其细致原理,即分析binder_call与之前提到svcmgr_handler函数参数txn中的txn->code,binder_call函数时在binder.c中提供的。

2023-02-26 23:05:56 349

原创 离散化介绍

数的值域跨度范围很大,但数的个数很少,通常会差几个数量级。四、示例(Example)二、离散化算法的介绍。三、离散化算法的运用。

2023-02-22 00:24:52 309

原创 双指针算法

双指针指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的。最常见的双指针算法有两种:一种是,在一个序列里边,用两个指针维护一段区间;另一种是,在两个序列里边,一个指针指向其中一个序列,另外一个指针指向另外一个序列,来维护某种次序。在利用双指针算法解题时,考虑原问题如何用暴力算法解出,观察是否可构成单调性,若可以,就可采用双指针算法对暴力算法进行优化.严格的来说,双指针只能说是是算法中的一种技巧。

2023-02-10 00:10:31 124

原创 位运算介绍

1.也就是求解lowbit(n)1.把第k位移动到最后一位。3.得出公式n>>k&1。求解过程:n&(-n)

2023-02-09 00:13:10 93

原创 高精度除法

此外,要注意我们的A是逆着计算的,因此C.begin()存放的是最高位,C.end()存放的是最低位;i–)匹配的话,需要将C逆置reverse(C.begin(),C.end());数据预处理:输入string a和int b两个数,并将a各个位的数倒置,并存放在vector[HTML_REMOVED] A中;此外,如果相除后C为100,输出时为001,与习惯不符,则需要pop出多余的0。模拟人工除法,r = A[i] + r*10,作为被除数;①从被除数的第一位开始,用此数除以除数,得出商和余数。

2023-02-08 00:11:30 495

原创 二分法讲解

是向下取整,当l与r只相差1的时候,即 l = r - 1,最终的结果mid = l(即结果不变还是l),补上1之后 mid = r,再次循环之后l = r 即[r , r],最终结束循环。如果不补1将会出现死循环。单调性与二分的关系:有单调性一定可以二分,用二分不一定是单调性。二分的本质不是单调性而是边界点(找符合条件的最小的数或者最大的数)二分法比较蛋疼的是由很多边界要考虑。

2023-02-06 00:52:42 516

原创 差分算法介绍

对于第一个数a[1]的插入,就是在[1,1]的区间段加上a[1],而对b数组而言,就是b[1]+a[1],b[1+1]-a[1],即insert(1,1,a[1])b[l] + c,效果使得a数组中 a[l]及以后的数都加上了c(红色部分),但我们只要求l到r区间加上c, 因此还需要执行 b[r+1] - c,让a数组中a[r+1]及往后的区间再减去c(绿色部分),这样对于a[r] 以后区间的数相当于没有发生改变。a[n],且令 b[i] = a[i]-a[i-1],b[1]=a[1],那么就有。

2023-01-08 23:35:09 8442 5

原创 前缀和讲解

原数组: a[1], a[2], a[3], a[4], a[5], …前缀和: S[i] = a[1] + a[2] + a[3] + …for循环求出 每个S[i] (将 S[0] 定义为 0, 避免下标的转换)注意: 前缀和的下标一定要从 1开始, 避免进行下标的转换。求 [l, r]中的和, 即为 S[r] - S[l-1]前缀和 Si为数组的前 i项和。一、一维数组求解前缀和(Si)快速求出元素组中某段区间的和。

2023-01-08 21:52:56 93

原创 write和fwrite

这就是我们常见的文件IO调用read/write函数。内核的这个page cache有很多好处,比如你的程序对io还没到需要自己做用户态的读写缓存,那内核的这个机制就帮你省去了很多工作,毕竟page cache是在内存里的,而且可以拿来做read hit,相比于每次read/write都要访问磁盘,带来的性能优势还是很不错的,算是惠及大部分普通程序。所以fwrite的好处是对于小量的写,减少syscall的次数,毕竟如果你每写一个字节都要发起一个syscall,然后特权级切换到内核,这是比较耗性能的。

2023-01-08 14:17:05 3146 1

原创 c语言中printf 函数不定长参数的实现

, 可变参数的函数必须有一个参数表示参数的个数, 才能让编译器知道压栈多少参数, 以及函数返回时弹出多少个参数, 我们在fmt字符串中提取’%‘的个数, 以及针对’%'后面不同的字符来处理。第一个参数ap, 就是刚刚提到的va_list类型, 第二个参数A, 就是一个确定的类型, 也就是"…va_start(ap, A)宏将ap初始化,以便随后被va_arg()和va_end()使用,必须先调用。va_arg()宏在va_start()宏之后的第一次使用会返回最后的参数. 连续的调用会返回其余参数的值.

2023-01-08 11:30:59 747

原创 归并排序分析

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;2.申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;3.设定两个指针,最初位置分别为两个已经排序序列的起始位置;将另一序列剩下的所有元素直接复制到合并序列尾。重复步骤 3 直到某一指针达到序列尾;数组中的第K个最大元素。1.通过递归拆分数组。

2022-12-26 23:22:38 87

原创 高精度乘法

如果计算机结果已经超过long long所能表示的范围,将会得到溢出后的答案(结果不正确,也不能计算)。这时候就需要用到高精度乘法算法,所谓高精度乘法算法,无非也就是通过录入字符数组的形式保存数字为字符串,然后逐一取出录入的数字字符,转换成对应的int数字,然后利用计算机善于重复循环处理数据的特点,模拟乘法竖式的计算过程,通过进位和错位相加的形式,得到高精度计算结果。如下:给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

2022-12-26 20:52:40 142

原创 【Linux 内核 内存管理】物理内存组织结构

所有节点中的处理器都可以访问全部的系统物理存储器,但是访问本节点内的存储器所需要的时间,比访问某些远程节点内的存储器所花的时间要少得多。在 NUMA 非一致内存访问架构 中, 将 CPU 划分为多个节点 , 每个节点都有自己的 " 内存控制器 " 和 " 内存插槽 " , CPU 访问自己的节点上的 内存 很快 , 但是访问其它 CPU 的内存 很慢;内存节点的pglist_data实例的成员node_mem_map指向该内存节点包含的所有物理页的页描述符组成的数组。体系结构不同,支持的页大小也相同。

2022-12-21 23:31:19 650

原创 高精度减法

2.对于 t = A[i] - B[i] - t;可以拆为 t = A[i] - t如果B[i]合法,再t -= B[i] 这么两步来做。3.将相减后t的处理 ,把 t >=0 和 t < 0 用一个式子来表示 t = (t + 10) % 10。给定两个正整数(不含前导 0),计算它们的差,计算结果可能为负数。1.先比较两个数的大小,打的数放参数前面。

2022-12-18 00:03:00 71

原创 高精度加法

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。再十位相加: 6 + 2 + 1(进位)= 9, 所以十位是 9,向百位进 0。先个位相加: 7 + 8 = 15,所以结果的个位是5,向十位进 1。在百位相加: 5 + 0 = 5, 所以结果的百位是 5。例如计算:567 + 28。综上,计算结果为 595。模拟手动加法计算即可。415. 字符串相加。

2022-12-16 22:25:50 102

原创 快速排序(双指针法)

由于while(i < j)循环结束时,i>=j,i=j时没问题,当i>j时,且只剩下两个元素,由于x = nums[l],会一直死循环。当两指针即将相遇时,停止,此时q[i]的左边全部小于x,q[j]的右边全部大于x,j从指向去q[r]开始向前移动,如果q[j]>x,就继续向前移动,否则,停止。右侧q[r],令它为x。i从指向q[l]开始向后移动,如果q[i]

2022-12-15 01:06:40 868 1

原创 linux的内存映射(二)

我们先来看幅图:Linux内存管理的最底层是buddy内存管理方案,即伙伴算法,管理伙伴算法我们不做详诉,有兴趣的可以自行学习,我们这里只要知道buddy内存池中只能分配2^n个page的内存,比如1,2,4,8……个pages,然而正常使用的时候不会碰巧就需要1,2,4,8……个pages。所以基于buddy内存池,还需要有上一级的内存管理系统,内核里面采用的是slab,slub,slob;而用户空间也有自己的内存管理方案,比如基于glibc的malloc/free内存管理方案。关于glibc的ma

2022-12-08 00:24:34 533

原创 Linux内核--链表结构

与list_for_each不同,list_for_each遍历的是链表节点,而list_for_each_entry遍历的是由链表节点串起来的结构体链表。list_del:删除链表中的entry节点,entry节点的前驱后继指针指向LIST_POSITION1和LIST_POSITION2两个特殊值,这样设置是为了保证不在链表中的节点项不可访问,对LIST_POSITION1和LIST_POSITION2的访问都将引起页故障。list_for_each的加强版,支持遍历过程的节点删除操作,提高安全性。

2022-12-02 20:47:32 1046

原创 内存映射原理及系统调用

因此,内核可以向树和线性链表添加新的区域,而无需扫描链表。(1)I/O映射方式(I/O-mapped):英特尔的x86处理器为外围设备专门实现了一个单独的地址空间,称为“I/O地址空间”或“I/O端口空间”,处理器通过专门的I/O指令(如x86的in和out指令)来访问这一空间中的地址单元。(2)内存映射方式(memory-mapped):使用精简指令集的处理器通常只实现一个物理地址空间,外围设备和物理内存使用统一的物理地址空间,处理器可以像访问一个内存单元那样访问外围设备,不需要提供专门的I/O指令。

2022-11-30 00:29:07 461

原创 内存管理架构

之所以这样分隔是因为每个虚拟区间可能来源不同,有的可能来自可执行映像,有的可能来自共享库,而有的可能是动态内存分配的内存区,所以对于每个由vm_area_struct结构所描述的区间的处理操作和它前后范围的处理操作不同,因此linux把虚拟内存分割管理,并利用了虚拟内存处理例程vm_ops来抽象对不同来源虚拟内存的处理方法。mm_struct是对进程的地址空间(虚拟内存)的描述。程序间断点就是程序数据段的结尾。如果间断点值增加,那么这个指针(指的是返回的之前的间断点地址)是指向分配的新的内存的首地址。

2022-11-29 00:20:32 302

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除