android
文章平均质量分 90
龙战于野渭南
天道酬勤
展开
-
重看LeakCanary
LeakCanary是我很久之前看的东西了,我当时侯对它的印象就是它可以用来检测内存泄漏,具体原理就是将弱引用对象延迟个5s然后看是否被回收,如果没有被回收,那么就说明发生了内存泄漏,其他的也没有仔细地看。原创 2024-02-24 01:31:09 · 910 阅读 · 0 评论 -
浅谈instant run
Instant Run 是 Android Studio 提供的一项功能,它允许开发者在修改应用代码后,无需完整重建和重新安装应用就能将改动推送到已运行在设备上的应用程序中。这意味着对于某些类型的代码更改,开发人员可以在不进行全量编译和安装的情况下,直接看到手机上运行的APP反映出代码变更的结果。然而,并非所有类型的修改都能通过Instant Run立即生效,有些复杂的改变仍需要进行完整的构建与部署流程。原创 2024-02-09 01:00:42 · 924 阅读 · 0 评论 -
从SystemServer处理过程到Launcher启动过程
我们回顾一下SystemServer的过程,首先我们是通过Zygote,当它调用方法的时候会遍历找到pid==0的函数然后执行。在里面主要进行了两个操作1.ZygoteInit.nativeZygoteInit()这个函数成功实现了调用native层的代码启动Binder线程池与其他进程进行通信,实现了SystemServer与其他进程通过Binder连接池进行进程间的通信2.RuntimeInit.applicationInit()通过这个函数,我们在它的内部通过反射找到那个名为main。原创 2023-07-13 11:08:52 · 299 阅读 · 0 评论 -
Android中线程池
阻塞队列常用于生产者消费者场景,生产端负责生产,生产的东西发往消费者端。其中生产者端就是往这个阻塞队列添加元素的线程,消费者端就是从队列中拿出元素的线程。原创 2023-06-22 19:21:24 · 1102 阅读 · 0 评论 -
Android常见设计模式
首先一个重点就是**类的初始化得在一开始就弄,并且是由static修饰**使用**static关键字创建类的静态变量时,这个变量会在类加载时被初始化**。**在java中,类加载只会发生1次**。因此,如果使用static关键字创建单例对象,那么在类加载时就会创建单例对象。但是饿汉模式是有一个缺点,就是这个变量会在类加载时被初始化,如果没用过这个实例的话,就容易造成内存的浪费。这就不符合**懒加载**的效果原创 2023-06-21 22:37:12 · 3582 阅读 · 1 评论 -
EventBus
1、三个角色Event:事件,它可以是任意类型,EventBus会根据事件类型进行全局的通知。Subscriber:事件订阅者,在EventBus3.0之前我们必须定义以onEvent开头的那几个方法,分别是onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,而在3.0之后事件处理的方法名可以随意取,不过需要加上注解@subscribe,并且指定线程模型,默认是POSTING。原创 2023-06-21 22:31:00 · 703 阅读 · 1 评论 -
init与zygote的启动流程
init进程主要就是干了以下三点创建和挂载启动所需要的文件目录初始化和启动属性解析init.rc配置文件并启动zygote进程我们以它处于Native还是Java框架层为分界点,分为两个时期第一段是仍然处于Native层,我们先判断service的main函数在不在Zygote进程,如果在的话,给它相关的标志设置为true。如果不在,但是它在这个进程中,那么我们把这个的相关标志设置为true。在Zygote的相关标志为true的情况下,我们启动Zygote进程start的内部我们会。原创 2023-06-16 21:35:19 · 786 阅读 · 0 评论 -
Android协程
在Looper的死循环中,它会不断地从消息队列中取出消息,并将消息分发给对应的Handler处理。当消息队列为空时,Looper会一直循环等待新的消息到达。在等待消息期间,Looper的死循环会阻塞主线程,因为它会一直占用主线程的执行时间片。这意味着主线程无法继续执行其他任务或响应用户的输入事件或系统事件。只有当主线程长时间占用了 CPU 或其他系统资源,并且长时间无法响应用户输入事件或完成关键操作时,才会触发 ANR 错误。耗时操作本身并不会导致主线程卡死,导致主线程卡死的真正原因是。原创 2023-06-13 21:44:28 · 2807 阅读 · 0 评论 -
详解Handler
post()传递的是一个runnable,然后进入方法,它会让你把runnable进行message化与一起传进去然后进入了方法,它会让你把message与一笔给传进去,后面的这个是什么呢?然后传递,把msg与三个参数一起传进去,进行的插入我们再进来看看enqueueMessage()是怎么把msg插入到MessageQueue里面的。原创 2023-06-02 20:31:30 · 573 阅读 · 0 评论 -
Android的消息机制
这是因为每个对象都有一个内部的ThreadMap对象用于存储对象,当一个线程去访问对象,会在自己的对象中寻找对应的值,如果当前线程还没有在存储相应的值,就会为当前线程创建一个新值,这样,每个线程都拥有自己独立的值副本,互不干扰。enqueueMessage中如果消息队列为空(p为null)或给定消息的触发时间为0或给定消息的触发时间小于头消息的触发时间则把该消息设置为头部否则就进行单链表的插入操作,同时它也会判断如果被唤醒且处于异步操作的话,则不再唤醒,退出插入操作next则是无限循环的方法,这一点和。原创 2023-05-31 10:11:46 · 1350 阅读 · 1 评论 -
Window的创建
现在回顾以下我们刚才做的1是创建了Window,(Window是在ActivityThread中调用performLaunchActivity中创建的Activity调用attach中创建的)2.如何创建WindowManager,并且进行了绑定(在Window调用setWindowManager中创建的WindowManager)3.如何将Activity的布局文件设置给PhoneWindow(1.判断DecorView是否创建。原创 2023-05-28 21:19:37 · 680 阅读 · 0 评论 -
理解Window和WindowManager(一)
viewRootImpl的逻辑很多,重要的就是调用了mWindowSession的方法调用了WindowManagerService的方法。mWindowSession是一个IWindowSession类型对象,IWindowSession是一个IBinder接口,他的具体实现类在WindowManagerService,本地的mWindowSession只是一个Binder对象,通过这个mWindowSession就可以直接调用WindowManagerService的方法进行跨进程通信。原创 2023-05-28 14:18:35 · 1610 阅读 · 0 评论 -
Android动画深入分析(View动画)
在MainActivity效果还不错新的动画继承Animation这个抽象类,然后重写initialize和方法initialize方法initialize方法是View的初始化方法,用于在View被添加到窗口或在View大小发生改变时初始化View的状态。在该方法中,您可以初始化一些变量、获取View的宽度和高度等,以便在后续的绘制过程中使用。applyTransformation方法。原创 2023-05-26 16:21:12 · 936 阅读 · 0 评论 -
自定义View
init();init();init();} }比如:我想把这个圆在没有指定其他颜色的情况下是红色,指定后就是你指定的那个颜色现在在values文件夹然后在自定义view那块init();a.recycle()用来释放资源然后在xml文件中设定颜色为黑色我们运行一下:但是我试了一下,这个init();必须得在第二个有参构造里面写,如果不在第二个写的话,在其他的有参构造上写这个没有效果比如我要实现一个类似ViewPager。原创 2023-05-25 01:09:50 · 572 阅读 · 0 评论 -
View的工作原理
直接继承View的自定义控件需要重写onMeasure方法并设置wrap_content时自身的大小,否则在布局中使用wrap_content就相当于使用match_partent。View在布局中使用wrap_content,那么它的specMode时AT_MOST模式,宽高=specSize,这种情况下View的specSize是parentSize,parentSize是父容器中目前可以使用的大小,这种效果和在布局中使用match_parent完全一致。重写的代码其中。原创 2023-05-24 17:25:05 · 992 阅读 · 0 评论 -
View中的滑动冲突
滑动冲突一般有3种,第一种是ViewGroup和子View的滑动方向不一致比如:父布局是可以左右滑动,子view可以上下滑动滑动冲突一般情况下有2种解决方法1.外部拦截法2.内部拦截法这两个的区别是:外部拦截法是先经过父容器的拦截处理,如果父容器拦截的话,则拦截。不拦截则交给view。而内部拦截法**一般情况下**是父容器不进行拦截,直接由子容器进行判断拦不拦截。原创 2023-05-22 00:05:31 · 387 阅读 · 0 评论 -
View的事件分发机制
View的事件分发机制主要分为三点,第一点是Activity将点击事件分发给ViewGroup第二点是ViewGroup将事件自己处理或者分发给子View第三点便是子View自行处理,或者子View处理不了转交给ViewGroup现在依次来看。原创 2023-05-21 15:56:39 · 686 阅读 · 1 评论 -
View的基础与滑动
View是一种界面层的控件的一种抽象,我们知道的大多数控件都是直接或间接继承自View如等等注意:EditText在compose中并没有相关控件,而是通过TextField来进行组合Android中View本身就可以是单个控件也可以是由多个控件组合成的一组控件如下面。原创 2023-05-19 22:47:10 · 572 阅读 · 0 评论 -
CountDownLatch与Binder连接池
如果现在有一个题,有5个数,这时候我想让这5个数同时都乘2,然后算出结果后再算它们的平均数这时候就可以用我们定义了个数组,这个数组存放了{1,2,3,4,5}然后我们让这5个同时开始然后开一个线程让data[i]中的每个元素乘以2.0要是其中有一个完成了任务便会执行进行减一操作,当计数器的值减到 0 时,主线程就会从 await() 方法中返回,可以开始计算平均值。原创 2023-05-16 23:55:54 · 316 阅读 · 0 评论 -
Android中的IPC方式
其中Intent就是用Bundle进行传播四大组件间的进程间通信无并发,适用于交换简单的数据实时性不高的情景使用文件共享容易出:Sharedpreferences对于其他文件共享来说是个特例,因为它只能被应用程序中的其他组件共享,并且访问权限是应用程序私有的,数据格式也非常简单。不仅如此,系统对它有一定的缓存策略,即在内存中年会有一份Sharedpreferences文件的缓存,在多线程模式下,系统对它的读/写不靠谱,面对高并发的读/写访问,Sharedpreferences有很大概率丢失数据。所以不建议在原创 2023-05-16 00:48:48 · 708 阅读 · 0 评论 -
Serializable与Parcelable接口
在讲到Serializable与Parcelable接口前我们需要先了解什么叫序列化与反序列化原创 2023-05-09 20:35:14 · 125 阅读 · 0 评论 -
Activity的生命周期和启动模式
上面这个是chatgpt给的理解我的理解就是onCreate()就是界面的初始化与类的加载,Activity的创建onStart()就是Activity被启动,这时候Activity已经可见了,但并不是在前台可见的意味着我们用户是没办法看见的onResume()就是已经前台可见了,并且已经可以交互了onPause()和onResume()是互相对应的,onPause()只要失去了用户的焦点那么就会被调用。但是书上一般都说onPause的时候activity依然可见。原创 2023-05-09 11:25:55 · 761 阅读 · 0 评论 -
Compose的基本布局
本篇博客参考先看一下实现的效果主要是由3个部分构成的,一个是上面那个搜索框(搜索框是死的,就是一个纯UI,只能看,文字都没办法输入);第二个是中间的,中间的又可以分为2部分,上面的那块是用可以左右滑动,下面的是用实现了两列的左右滑动(使用的时候务必注意:你的版本必须特别高,否则用不了这个);最后是下面的底部导航栏(这个也是写死的东西,点击后不会有任何反应)。原创 2023-05-07 21:22:55 · 362 阅读 · 0 评论 -
Retrofit源码解析
Retrofit的create()方法最终会调用动态代理对象的invoke()方法来处理方法调用。在invoke()方法中,会根据方法的注解和参数等信息创建一个对象,并使用OkHttpCall类创建一个Call对象并返回。以下是invoke()invoke()方法是动态代理对象的一种方法,用于在代理对象上处理方法调用。// ... }在invoke()方法中,会使用类来解析方法的注解和参数等信息,并构建一个对象。类的build()方法会根据方法的注解和参数等信息构建一个对象,并返回该对象。在。原创 2023-04-23 23:24:13 · 178 阅读 · 0 评论 -
Retrofit基本用法
同时,在调用getbody方法时,传入的参数是一个字符串,而该参数实际上是用作查询参数的值,会被自动拼接到URL中。q=动态配置URL地址@Path retrofit&t=&u=&urw=”,因为在Query接口中定义的是@GET(“ip1”),所以最后的URL中的路径部分是"ip1",而不是"ip"。同时,在调用getbody方法时,传入的参数是一个字符串,而该参数实际上是用作查询参数的值,会被自动拼接到URL中。当你需要获取响应体的字节流时,或者无法确定响应体的编码格式时,建议使用。原创 2023-04-22 22:32:34 · 384 阅读 · 0 评论 -
Volley源码流程图
Volley源码流程图原创 2023-04-19 16:36:21 · 102 阅读 · 2 评论 -
Material Design
本博客的知识点源于《Android进阶之光》第二章。原创 2023-01-27 21:37:46 · 129 阅读 · 0 评论 -
LiveData+Room
首先使用的数据库是一个面向关系的数据库,将面向对象的语言和面向关系的数据库结合在一起就是ORM,即对象关系映射而Room就是有这样的一个ORM框架Room 是一个数据库对象映射库,可以轻松访问 Android 应用程序上的数据库。Room 持久性库在 SQLite 上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,能够流畅地访问数据库。具体来说,Room 具有以下优势:针对 SQL 查询的编译时验证。可最大限度减少重复和容易出错的样板代码的方便注解。简化了数据库迁移路径。用。原创 2022-11-25 22:18:44 · 1078 阅读 · 1 评论 -
ViewModel的理解
先说一下一般情况,A/B 均不是透明页面:A 跳转 B 页面会经历的生命周期:A.onPause() -> B.onCreate() -> B.onStart() -> B.onResume() -> A.onStop。从 B 页面返回 A 页面经历的生命周期:B.onPause() -> A.onRestart() -> A.onStart() -> A.onResume() -> B.onStop()。原创 2022-11-21 17:38:24 · 400 阅读 · 2 评论 -
RecyclerView与ViewPager2
适配器里面的东西完全不用改变在MainActivity里面加上} } });fragments . add(BlankFragment . newInstance("好好好" , "1"));fragments . add(BlankFragment . newInstance("棒棒棒" , "2"));fragments . add(BlankFragment . newInstance("好好" , "1"));}至于为什么这么写呢,我只能说这是我为数不多会的了。原创 2022-10-27 16:57:31 · 834 阅读 · 1 评论