自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(56)
  • 收藏
  • 关注

原创 Java中的23种设计模式

一、创建型模式1.单例模式单例模式是 Java 中最简单的设计模式之一。通过单例模式,可以保证系统中,应用了单例模式的类,只有一个对象实例。包括五种:饿汉式、懒汉式、双重校验、静态内部类、枚举类。1.1 饿汉式特点:类加载时就初始化,线程安全1.1静态常量(可用) 优点:类加载的时候完成初始化,避免了线程同步的问题,是线程安全的。 缺点:不能延迟加载,如果从始至终未使用该类的话,就造成了资源浪费。 public class ImageLoader{

2023-11-01 17:02:44 627

原创 数据结构 -- ArrayList与LinkedList的区别

而 LinkedList 是链表的形式,在内存中的表现形式不是一段连续的空间,而是每个元素中都存储着上一个和下一个元素指针地址,当get(index)时,只能从首个元素开始,依次获取下一个元素的地址。原因是 ArrayList 在内存中的表现形式是一段连续的空间,当我 get(index) 的时候,我可以根据数组的。LinkedList 比 ArrayList 的效率更高,因为ArrayList是数组,在进行增、删操作时,会改变操作节点之后所有数据的下标,需要进行数据的移动。

2023-10-30 11:52:43 687

原创 安装apk文件时的常见的错误及解决方法

安装apk文件时的常见的错误及解决方法

2022-12-06 18:03:53 7658 1

原创 Handler 原理

Handler是一套Android消息传递机制。

2022-11-25 11:16:39 1766

原创 ARouter详解

ARouter跳转到其他moudle时,需要注意的是,moudle中的目标Activity或者service服务类上使用@Route(path = “xx/xxx”) 与 app moudle中使用的@Route里的path路径不能相同,否则会报错,找不到索引。即会拦截跳转时的Path 和 Url (app内部跳转,以及页面跳转到app页面) ,拦截之后可以重新定义跳转路径,改变跳转的目标页面。通俗的讲,降级就是,在使用ARouter实现跳转的时候,如果发生错误,而进行相应的逻辑处理,

2022-11-11 13:12:03 6148

原创 EventBus详解 (详解 + 原理)

EventBus简介EventBus是一个开源库,由GreenRobot开发而来,是用于Android开发的 “事件发布—订阅总线”,用来进行模块间通信、解藕。它可以使用很少的代码,来实现多组件之间的通信。Android系统中的事件通信则是 handler (消息机制) 和 BroadCastReceiver (广播机制),通过它们可以实现组件之间的事件通讯。缺点在于,代码量多、组件之易产生藕合引用。EventBus产生的背景。

2022-11-10 12:01:05 38562

原创 leakCanary原理

LeakCanary的原理是什么?(针对Activity来说)LeakCanary通过监听Activity生命周期,在Activity onDestroy的时候,创建一个弱引用,key跟当前Activity绑定,将key保存到set里面,并且关联一个引用队列,然后在主线程空闲5秒后,开始检测是否内存泄漏,具体检测步骤:1:判断引用队列中是否有该Activity的引用,有则说明Activity被回收了,移除Set里面对应的key。

2022-11-09 23:16:53 414

原创 String中的compareTo()

可以认为是是一个外比较器,一个对象不支持自己和自己比较(没有实现。接口强制了实现类对象列表的排序。其排序称为自然顺序,其。是一种内比较,即支持跟当前对象比较。接口),但是又想对两个对象进行比较。在String内部还有个静态内部类。所以从上面的源码中可以看到,对象的大小写不敏感比较方法。方法,称为自然比较法。

2022-11-08 13:39:48 824

原创 数据结构之 LinkedHashMap 与 TreeMap

LinkedHashMap和HashMap区别?LinkedHashMap底层实现?利用LinkedHashMap实现LRU缓存?大多数情况下,只要不涉及线程安全问题,Map基本都可以使用HashMap,不过HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序。HashMap的这一缺点往往会带来困扰,因为有些场景,我们期待一个有序的Map.这就是我们的LinkedHashMap,看个小Demo:可以看到,在使用上,LinkedHashMap和HashMap的

2022-11-08 13:30:57 2017

原创 重识HashMap

尽管我们在进行get和put操作的时候,使用的key从逻辑上讲是等值的(通过equals比较是相等的),但由于没有重写hashCode方法,所以put操作时,key(hashcode1)–>hash–>indexFor–>最终索引位置 ,而通过key取出value的时候 key(hashcode2)–>hash–>indexFor–>最终索引位置,由于hashcode1不等于hashcode2,导致没有定位到一个数组位置而返回逻辑上错误的值null。如果使用默认的规则,是比较两个对象的地址。

2022-11-08 11:35:34 411

原创 HandlerThread 简介

可以使用HandlerThread来处理本地的IO读写的工作,因为本地IO操作大多数耗时都是毫秒级的,所以对于HandlerThread这种单线程 + 队列的形式,不会产生阻塞。优先级越高的线程,获的的CPU资源越多,反之越少。所以如果其中某一个线程 任务执行时间过长,就会导致后续的任务都会被延迟处理。由于HandlerThread是单线程同步队列的,所以不适合处理网络IO的操作。是没有必要设置这么高的优先级的,因而需要我们根据需求,来设置合理的优先级别。线程的优先级,一定程度的优化线程。

2022-10-11 20:47:08 523

原创 IntentService简介&源码分析

是一个继承自Service的抽象类,本质上还是一个Service,我们需要创建它的子类去使用。同时实现了,在内部维护了一个线程,专门用来处理耗时操作。实际上中所有的操作都是在这个中执行的。多次启动同一个IntentService,则每一次启动的耗时任务,都会以消息队列的形式在WorkerThread中被依次执行,任务的执行是在onHandleIntent()方法中完成的。都执行完成后,就会调用 stopSelf() 自动结束,不需要我们去手动结束。

2022-10-11 00:54:48 516

原创 Jetpack 之 LiveData (一)使用篇

LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,能够响应组件( activity、fragment 或 service)的生命周期。以便确保 LiveData 仅更新处于活跃生命周期状态下的组件观察者。如果观察者组件的生命周期处于Started或Resumed状态,则 LiveData 会认为该观察者处于活跃状态。LiveData 只会将更新通知给活跃的观察者。非活跃观察者则不会收到更新通知。被观察者需要实现。

2022-10-08 00:48:29 262

原创 Jetpack 之 ViewModel (一)使用篇

ViewModel类旨在响应组件(Activity、Fragment、Service)生命周期的方式,来存储和管理界面相关数据。ViewModel可以在组件界面发生屏幕旋转等配置变化后,继续留存数据。第一个问题:如果组件(Activity、Fragment、Service)被系统销毁或者重建,则存储在其中的界面数据都会丢失。例如:Activity中可能包含一个列表,如果该Activity重新被创建之后,则列表数据必须重新获取。对于简单的数据来说,Activity可以在。

2022-10-07 21:55:00 1185

转载 Jetpack 之 LifeCycle (一)使用篇

有了 LifeCycle ,你可以做什么?写更少的代码,犯更少的错。生命周期的处理趋于标准化,这也正是 Jetpack 想带给我们的,让开发趋于标准化的同时可以犯更少的错误,减少崩溃和内存泄漏。浏览一下你的项目,如果还有未使用 LifeCycle 解决生命周期问题的地方,赶紧替换吧!

2022-09-27 23:41:03 336

转载 解耦的方式

上面这段代码就是适配器模式进行解耦的代码例子,可能有人会很疑惑这样解耦有什么意义,以上代码只做演示确实看不出这种解耦的好处,但是在实际的项目开发过程中,如果有关A类的一些需求发生改变,我们可能只需要修改Base中的相关代码就可以进行整体需求的改变,否则的话,我们不仅要 修改A,还很有可能会导致B的修改。解耦的本质就是将类之间的直接关系转换成间接关系,不管是类向上转型,接口回调还是适配器模式都是在类之间加了一层,将原来的直接关系变成间接关系,使得两类对中间层是强耦合,两类之间变成弱耦合关系。

2022-09-27 00:13:17 545

原创 Retrofit教程

创建一个自定义的Interceptor拦截器,然后在创建Retrofit实例的地方通过addInterceptor()进行添加,通过它我们可以实现一些拦截的操作,比如下面:我们想要拦截每一次请求,添加一个公共的请求参数。但是如果提交的是一个Map集合,那么@Body的作用就相当于@Field,不过此时的map需要被FormBody.Builder处理成符合Okhttp的表单。@Url 用于在网络请求的时候,直接传入一个请求的Url变量,用于Url设置。来注解每个键值对的键名称,随后的对象需要提供键值对的。

2022-09-26 23:27:41 339

原创 Http中的Content-Type详解

首先生成了一个 boundary 用于分割不同的字段,在请求实体里每个参数以------boundary开始,然后是附加信息和参数名,然后是空行,最后是参数内容。它用来告诉服务端如何处理请求的数据,以及告诉客户端如何解析响应的数据,比如显示图片,解析并展示html等等。与application/json类似,这里用的是xml格式的数据,text/xml的话,将忽略xml数据里的编码格式,参考。上面的Content-Type,我们只认得就好,但是下面有4种是需要我们清楚他们的区别及牢记在心的。

2022-09-26 16:53:31 11951

转载 RxJava2.0 (八) Flowable

给叶问, 然后就在边上看热闹, 看叶问能不能打死十个鬼子, 等叶问打死十个鬼子后再继续要鬼子接着打。先来回顾一下上上节,我们讲Flowable的时候,说它采用了。给叶问, 让他打, 等叶问打死这个鬼子之后, 再次调用。先暂停,工作来了,抱歉。的例子,再来回顾一下吧,我们说把。的方式,我们还举了个。

2022-09-22 17:36:11 125

转载 RxJava2.0 (七) Flowable之 BackpressureStrategy

在上一节中, 我们学习了FLowable的一些基本知识, 同时也挖了许多坑, 这一节就让我们来填坑吧.

2022-09-22 17:29:45 398

转载 RxJava2.0 (六) 背压策略Flowable

异常, 这是因为下游没有调用request, 上游就认为下游没有处理事件的能力, 而这又是一个同步的订阅, 既然下游处理不了, 那上游不可能一直等待吧, 如果是这样, 万一这两根水管工作在主线程里, 界面不就卡死了吗, 因此只能抛个异常来提醒我们. 那如何解决这种情况呢, 很简单啦, 下游直接调用request(Long.MAX_VALUE)就行了, 或者根据上游发送事件的数量来request就行了, 比如这里request(3)就可以了.这种想法, 这是万万不可的, 它们都有各自的优势和不足.

2022-09-22 17:02:20 213

转载 RxJava2.0 (五) 背压策略

在上一节中, 我们找到了上下游流速不均衡的源头 , 在这一节里我们将学习如何去治理它 . 可能很多看过其他人写的文章的朋友都会觉得只有Flowable才能解决 , 所以大家对这个Flowable都抱有很大的期许。今天我们先抛开Flowable, 仅仅依靠我们自己的双手和智慧, 来看看我们如何去治理 , 通过本节的学习之后我们再来看Flowable, 你会发现它其实并没有想象中那么牛叉, 它只是被其他人过度神化了.

2022-09-22 16:34:39 165

转载 RxJava2.0 (四) Backpressure背压

大家期待已久的来啦.这一节中我们将来学习. 我看好多吃瓜群众早已坐不住了, 别急, 我们先来回顾一下上一节讲的Zip.上一节中我们说到Zip可以将多个上游发送的事件组合起来发送给下游, 那大家有没有想过一个问题, 如果其中一个水管A发送事件特别快, 而另一个水管B发送事件特别慢, 那就可能出现这种情况, 发得快的水管A已经发送了1000个事件了, 而发的慢的水管B才发一个出来, 组合了一个之后水管A还剩999个事件, 这些事件需要继续等待水管B发送事件出来组合, 那么这么多的事件是放在哪里的呢?

2022-09-22 16:10:38 126

原创 RxJava2.0(三)强大的操作符

上一节讲解了线程调度, 并且举了两个实际中的例子, 其中有一个登录的例子, 不知大家有没有想过这么一个问题, 如果是一个新用户, 必须先注册, 等注册成功之后再自动登录该怎么做呢.很明显, 这是一个嵌套的网络请求, 首先需要去请求注册, 待注册成功回调了再去请求登录的接口..subscribeOn(Schedulers.io()) //在IO线程进行网络请求.observeOn(AndroidSchedulers.mainThread()) //回到主线程去处理请求结果@Override。

2022-09-22 15:16:20 821

转载 RxJava2.0(二)Schedulers线程调度器

上一节教程讲解了最基本的RxJava2的使用, 在本节中, 我们将学习RxJava强大的线程控制Schedulers.

2022-09-22 12:31:39 850

转载 RxJava2.0(一)

首先需要说明的是,RxJava2.0和RxJava1.0是不冲突的,如果学过RxJava1.0,那么只需要在关注下更新内容即可。不过如果没学过RxJava1.0也没关系,直接学习RxJava2.0也是一样的,本文中所有的名词都属于RxJava2.0,并不涉及RxJava1。

2022-09-22 11:46:49 192

原创 RXJava1.0

对象会被存储在返回的Observable对象中,OnSubscribe的作用相当于一个计划表,当Observable被订阅的时候,OnSubscribe中的call()方法会自动被调用,事件序列也会依照设定的次序依次触发,先是调用观察者Subscriber中的onNext()方法三次,再调用观察者Subscriber中的onCompleted()方法一次。在复杂的逻辑下,会涉及到线程间的多次切换,多次切换遵循的规则是observeOn()指定的是它后面的操作所在的线程。Scheduler。...

2022-07-20 18:30:48 850

原创 Android网络框架 Retrofit

但是如果提交的是一个Map集合,那么@Body的作用就相当于@Field,不过此时的map需要被FormBody.Builder处理成符合Okhttp的表单。创建一个自定义的Interceptor拦截器,然后在创建Retrofit实例的地方通过addInterceptor()进行添加,通过它我们可以实现一些拦截的操作,比如下面我们想要拦截每一次请求,添加一个公共的请求参数。@Url用于在网络请求的时候,直接传入一个请求的Url变量,用于Url设置。,作为发送Post请求时提交请求参数的表单字段。...

2022-07-20 15:42:14 848

原创 Java基础知识(四)

一、值传递 & 引用传递值传递:方法接收的是实参值的拷贝,会创建副本,对形参的修改不会影响到实参。 引用传递:方法接收的直接是实参所引用的对象在堆中的地址,不会创建副本,对形参的修改将影响到实参。二、为什么Java只有值传递?...

2022-05-23 14:17:57 85

原创 Java基础知识(三)

一、I/O 什么是序列化?什么是反序列化?如果我们需要持久化一个 Java 对象:比如将Java对象存储到文件中,或者将Java对象实现在网络中传输等,这些场景都需要用到序列化。序列化: 将Java对象,转换成二进制字节流的过程。 反序列化:将在序列化过程中所生成的二进制字节流,转换成Java对象的过程。二、Java序列化时如何禁止某些字段参与序列化?对于不想进行序列化的变量,可以使用transient关键字修饰。transient关键字的作用是:阻止实例中那些用此关键字修饰的的变...

2022-05-18 17:21:44 62

原创 Java基础知识(二)

一、面向对象和面向过程的区别两者的主要区别在于解决问题的方式不同:面向过程把解决问题的过程,拆成一个个方法,通过这些方法的执行来解决问题。 面向对象会先抽象出对象,然后用对象执行方法的方式解决问题。另外,面向对象开发的程序一般更易维护、易复用、易扩展。二、成员变量和局部变量的区别语法形式:从语法形式上看,成员变量是属于类的,而局部变量是在代码块或方法中定义的变量或是方法的参数;成员变量可以被public、private、static等修饰符所修饰,而局部变量不能被访问控制修饰符及...

2022-05-17 17:34:20 331

原创 Java基础知识(一)

一、 JVM 虚拟机JVM是运行Java字节码的虚拟机。而基于不同平台,相同的Java字节码,执行之后会产生相同的结果,这也是实现跨平台的关键。JVM 并不是特有的,只要满足JVM规范,每个公司或组织或者个人,都可以开发自己专属的JVM。二、JDK 和 JREJDK是 Java Development Kit 的缩写,是功能齐全的 SDK。它包含 JRE 所拥有一切,还包括: javac、javadoc、jdb。它能够创建程序、编译程序。JRE是Java运行时环境。用来运行已编译好的Ja

2022-05-07 15:51:40 252

原创 网络协议 (六) TCP与UDP的区别

一、TCP与UDP对比:UDP 在传送数据之前不需要先建立连接,远地主机在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 却是一种最有效的工作方式(一般用于即时通信),比如: QQ 语音、 QQ 视频 、直播等等。TCP 提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。由于 TCP 要提供可靠的,面向连接的传输服务,这难免增加了许多开销。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP 一般用于文件传输

2022-04-29 19:25:23 285

原创 网络协议 (五) TCP握手建立连接

一、握手策略为了可以准确的将数据准确无误地送达目标主机,所有基于 TCP 实现的协议,都需要先完成 TCP 协议的三次握手策略。

2022-04-27 17:54:30 2805

原创 网络协议 (四) 计算机网络常识

一、应用层有哪些协议?HTTP 超文本传输协议; SMTP 简单邮件传输(发送)协议; POP3/IMAP 邮件接收协议; FTP 文件传输协议; Telnet 远程登陆协议; SSH 安全网络传输协议;1.1 Http协议Http 协议是基于TCP协议的,发送Http请求之前,首先需要建立一个 TCP 连接,也就是所谓的 3 次握手。目前使用的 HTTP 协议版本大部分都是 1.1。而在 Http1.1里,默认是开启 Keep-Alive 的,这样的情况下建立的链接就可以在多次的请求中

2022-04-24 18:04:51 2546

原创 网络协议 (三) Http1.0 vs Http1.1 vs Http2.0 (应用层)

这篇文章会从下面几个维度来对比 HTTP 1.0 和 HTTP 1.1:响应状态码 缓存处理 连接方式 Host头处理 带宽优化1. 响应状态码Http1.1 与 Http1.0 相比,新加入了大量的状态码。2. 缓存处理Http1.0 中的缓存机制非常简单,服务端使用 Expires 标签来标识一个相应体,在 Expires 标志的时间内的所有请求,获得的都会是缓存。服务端 初次返回给 客户端 的响应体中,会有一个 Last-Modified 标签,该标签标记了被请求资源在

2022-04-21 22:01:43 2200

原创 网络协议 (二) Http vs Https (应用层)

一、Http 协议1. Http 协议介绍HTTP 协议,全称超文本传输协议。顾名思义,HTTP 协议就是用来规范超文本的传输的。超文本:也就是网络上的包括文本在内的各式各样的消息。HTTP 是一个无状态协议(stateless),也就是说服务器不维护任何有关客户端过去所发请求的消息。这其实是一种懒政,有状态协议会更加复杂,需要维护历史信息,而且如果客户或服务器失效,会产生状态的不一致,解决这种不一致的代价更高。2. HTTP 协议通信过程HTTP 是应用层协议,它以 TCP(传输层)作

2022-04-18 17:40:35 1869

原创 网络协议 (一) TCP/IP 四层模型

TCP/IP 四层模型 是目前被广泛采用的一种模型,我们可以将 TCP / IP 模型看作是 OSI 七层模型的精简版本,由以下 4 层组成:应用层 传输层 网络层 网络接口层需要注意的是,我们并不能将 TCP/IP 四层模型 和 OSI 七层模型完全精确地匹配起来,不过可以简单将两者对应起来,如下图所示:一、应用程 (Application Layer)应用层位于传输层之上,主要提供两个终端设备上的应用程序之间信息交换的服务,它定义了信息交换的格式,消息会交给下一层传输层来传输。

2022-04-18 12:27:02 6726

原创 数据结构(五)红黑树

讲红黑树之前,我们先来回顾一下 二叉查找树 (BST) ,先来看一下二叉查找树的特性:左子树上所有结点的值均小于或等于它的根结点的值。 右子树上所有结点的值均大于或等于它的根结点的值。 左、右子树也分别为二叉排序树。我们来看一个典型的二叉查找树:这样的数据结构有什么好处呢?首先我们来测试一下,试着查找一下值为 10 的节点。1. 查看根节点 9 。2.由于10 > 9,因此查看右孩子13。3.由于10 < 13,因此查看左孩子11。4.由于10 < 11.

2022-03-11 17:14:31 629

原创 数据结构(四)堆

堆也是一种树,但是它需要满足以下条件:堆中的每一个节点值 都大于等于 或者 都小于等于 该节点下子树中所有节点的值。或者说,任意一个节点的值都大于等于 (或小于等于) 所有子节点的值。注意⚠️很多博客说堆是完全二叉树,其实并非如此,堆不一定是完全二叉树,只是为了方便存储和索引,我们通常用完全二叉树的形式来表示堆。事实上,广为人知的斐波那契堆和二项堆就不是完全二叉树,它们甚至都不是二叉树。 (二叉)堆是一个数组,它可以被看成是一个近似的完全二叉树。1 堆的用途当我们只关心所有数据中的 最.

2022-03-11 17:12:46 349

空空如也

空空如也

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

TA关注的人

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