00:00
好,接下来呢,我们就来详细的讲解这个源码啊,源码这一块啊,讲这个源码之前呢,啊,带着大家看一下我这个资料。啊,在这个位置这个文件夹,这个文件夹呢,这里有一个测试代码,这测试代码里面有一个带注释的源码和这个不带式注释的源码,啊这是什么什么意思呢。待注册的源码啊,就是说是这个。我这里面呢,在这个源码上啊,有一些这个中文注释啊,看起来呢比较方便,那么这个不带注释的源码是什么意思呢?哎,这不带不带这个注册源码啊,啊可以直接运行啊,可以在运行到这个程序中啊。直接可以运行起来,这个代注式的,它不能运行啊,不能运行的原因呢,就是这个编码方式啊啊,它这个代码本身是这个GBK的啊,我这个工程呢,是这个U8的啊,我这个改起来呢,比较比较麻烦啊,我就没有没有去改它啊,但是不影响我们这个看代码啊,代码是一样的。
01:02
好啊,给大家说一下这个事情啊,接下来呢,我们就开始讲这个源码,这个源码呢,一共这个分这个三大块啊,包括它的注册啊,发布和这个取消注册啊,这么三大块啊,非常简单,首先第一个就是这个注册,注册呢就一行代码啊,In bus.get default。点resist啊,注册将当前这个it的对象啊传进来就OK了,就这么一步啊,那首先呢,我们看一下这个源码。我拿来带注释的。找到我们的activity。啊,有他吧。啊,就是它啊这里面呢,首先来到这个in need date啊in date方法这里面找到啊注册就这么一行,点get default,那我们就看一下这个default。这里面呢,一进来一看,这里面是一个什么类什么呀啊,大家仔细看一看。
02:03
他是不是就是一个单啊,就是这么一个单对象。啊,如果为空的时候,那我就创建啊,否则呢,我直接就要返回这个默认的这个对象啊,这是典型的一个单例,但是单立呢,这下面还有一个特点,它什么意思呢?你看if这个default等于等于空。啊,然后呢,下面加了一个锁啊,加了锁之后呢,下面又if default instance等于等于空啊这是什么意思呢?这是采用这个双重校验所的设计的一种弹力啊,为了这个啊,防止这个同步啊,防止这个异步啊,防止这个异步。那大家看一下,可以看出来,Bus是一个单立模式存在的,一个项目中只能有一个bus。这样有利于管理订阅者。啊和这个订阅方法。这会在下面啊,具体的介绍体现出来啊,就是说啊,这里面呢,它是采用这个单例,那么它只有这一个啊in bus,但是。
03:07
啊,但是但是大家往下看。看到这个地方。哎,他同时是不是还给我们提供了一个构造啊,空程构造啊,而且是public,那public是不是就可以new对象啊,哎,那么它也可以啊,拗出多条这个因霸筒线来。啊,给你提供了赠与方式,他这个既给你提供了一个这个。大力又给你提供了一个new照啊,创建对象的这么一个方法啊,是不是很奇怪啊,很奇怪,这个设计的还是比较独特的啊。好,接下来那说一下,它采用的是双重教练所设计的单列模式啊。但是构造中啊,确实是public in bus呢,默认支持一条时间总线,通常是通过get defpot方法获取in巴实例啊,但也能通过直接扭运八神这种最简单的方式获取多条时间总线,彼此之间完全分开。
04:05
这就是这个gett default啊,记住它有个单立,同时呢它有一个构造啊,而且呢,这个单立呢,设计呢,还是这个双重键位锁啊就OK了,这是这个地方,接下来我们回退回来回到这个may,然后呢进入到这个的注册的方法。进来。进来呀,是不是就将这个你这个类传进来了啊,大家注意看一下啊,看是不传进来是个this啊,This表示谁呀?是不是表示的是main activity啊,哎,Main activity,那么它传进来了。他传进来之后干了什么事情?Get class啊,传啊,获取到当前activity,也就是main activity的class对象,那么拿到这个class对象它又干嘛的呢?它又传到了这个方法中,那么这一步是干什么的呢?这一步表示从订阅类中获取所有的订阅方法。
05:07
那么,订阅类是谁?啊,订阅类,那还记得这个图吗?啊,这个图谁是订阅者呀,是不是这边啊接收方都是这个订阅者呀,啊订阅者这边呢,是发送方。啊,发送包。啊,记住这里面接收方是订阅者,那么当前这个订阅者指的也就是这个main activity啊,这个地方要注意。好,那么它要从这个订阅类中,也就是max中获取你所有的订阅方法,啊,其实是谁呢?其实也就是。这个方法和这个方法啊,你注册的这个订阅的方法,订阅的事件吗?根据这个的事件,你订阅的方法吗?啊,也就是他俩那么再往下看啊,详细的看这个代码。进来进来之后,首先它干嘛了呢?从缓存中读取这个获取的订阅类的方法啊,那看一下。
06:08
啊,这个case啊,也是缓存get,通过这个class啊,去获取当前这个订阅者的所有的订阅的方法啊。啊,通过你传进来这个maxtc这个类,然后以它为K获取所有的值。啊,如果这个方法不为空,也就是说这个缓存中有订阅的方法,那么直接返回就结束了啊,就拿到了所有的订阅这个方法了,啊,那就不会往下走了。那么如果这个缓存中要没有呢?哎,那他继续往下走啊,这个呢,Generated index它默认的是false啊,它不会找这分支,它会找这分支啊,那么上面这分值表示什么意思呢?利用反射来获取订阅类中的订阅的方法。
07:01
啊,通过反射,那么你通过反射,你想想我要通过反射,这是mayxc是不是一个类啊,那我是不是就可以拿到这个类中的所有的方法呀,哎,那就是这样的意思。那带过来,那下面这个是干什么呢?下面这个表示的是从注解器生成的类中获得订阅类的订阅的方法信息啊,它是从注解器,那么注解器那大家看一下这个max,那这是不是都是注解啊,这是不是都注解啊,那么你通过注解的方式,那是不是直接就这两个方法是注解,那你是不是获取的非常快呀,你要通过这个反射,你是不是把这些所有的方法。都反射到了这些全先得反射到了,哎全能拿到,那么它这个效率是不是低啊,哎,所以说呢,下面这个啊方法是啊快的那啊他正常也会先执行这个方法,那我们来看一下。好,进来,进来之后呢,首先经过了这么一个方法,Fund state。
08:03
啊,那我们就看一下这个方法是干嘛的,查找状态,看着下面这个啊,是不是一个池子啊,它是干嘛的呢?它是一个查找的状态池啊,状态池帮助你去查找的,那为啥用用这个状态池啊,啊大家之前是不是以前用过这个啊,线程池啊,是不是这个你创建线程的时候是不是有有很大的开销啊,每创建一个对象每就是很耗资源呢,那么你要从池子中去取,那是不是这个创建对象啊,或者创建这个线程,创建这个状态池啊,状态的时候啊,也就是说减少了这个资源啊,减少了时间啊,性能上会更好一些,所以说呢,这底层用的是这个啊状态池,状态池。那好,那么他如果拿到了这么一个啊状态,那么它就返回了,那我们也返回来。拿到它之后,首先呢,它对它进行了初始化。
09:01
啊,将这个max类这一类啊传进去,对它进行初始化,初始化完事之后啊,往下走啊,这些他都不会走,他最终走到哪呢?走到这。获取订阅的方法。啊,获取定义的方法,再往下进来。进来之后,它会首先走这个方法,它会直接get decline的方法啊,也就是获取你的公有的方法啊,公共的方法啊,这方法如果他获取不到,它就会往下走。通过反射啊获取定义类中的所有方法。Find state.class啊,这个class呢,其实就是这个main activity,那么get measure,通过反射获取所有的方法啊,就上面呢,是通过这个注解,如果你能获取到就获取到,获取不到,那最终还是通过这个反射啊来获取。那么如果说你获取到了这个方法啊,获取到这个方法之后呢,你干嘛呢,便利你所有获取的方法。
10:06
啊,那么它进行啊条件判断,如果你不是公有的,那我就直接过滤掉了啊,它为啥要是这个非得是公有的呢,你看一下。你所有注册的这个订阅事件啊,这个接收的订阅的方法是不是都是公有的啊,都是这个public类型,所以说呢,他就会把这个啊,Protect还有这个啊,包括上面这个private类型啊,啊全部除掉啊,他是这个意思,好,那么往下走,那么他后来又做了一件事情,Method get啊他。Parameter types,也就是获取传入的参数的类型啊,这个长度呢,必须为一啊,为什么为一呢?我们再看一下这个注射的订阅事件,它有什么特点,它的参数是不是都是唯一啊,啊,只有这么一个参数啊,所有的事件都为一个参数。
11:01
好,那么长度为一,那再往下保证一个只有一个参数,最后校验是否添加该方法啊,是否把这个方法添加到一个集合中。那么什么条件是能通过呢?啊,这里是表示如果添加过就不再添加,没添加过再添加,那看一下这里面具体的实现。具体看一下这里面呢,通过这么一个类型啊,Put一个你这个事件类型和这个方法看是否添加过啊,如果添加过直接return就不再添加了,只有没有添加过的时候,我再将这个事件类型添加到啊这个几个中。啊,好。返回。返回之后呢,我就会将当前的这个方法啊传到啊,传到这个订阅的方法中,这个一个集合中啊爱进来。
12:02
至此呢,啊,可以看到,首先会得到。订阅类的class对象,并通过反射获取订阅类中的所有的订阅的方法。目的就一个,就是获取到这个mayxc中所有你订阅的这个这个方法啊,拿到它。啊,就干这一个事儿了。通啊,然后通过筛选获取得到订阅类的方法的集合啊,程序执行到此,我们获得了订阅类中所有定阅的方法信息。啊,至此呢,我们就拿到了这两个方法啊,这里面是这两个啊,你要是别的类,那可能拿到了其他的。这是以它为例。好,这是啊,这地方,那么获取到所有的方法之后,那么再返回,返回到哪呢。那返回到这儿,我们再来一下。注册。这地方啊,也就是返回到这儿。啊,你通过这么一顿查找啊,最终的目的其实就一个,就是拿到这个M中你所有的注册的订阅的事件啊这个方法。
13:10
拿到它干什么呢?哎,拿到它之后。它就循环便利你这个定位的方法。啊,把你这个每个事件都取出来,也就是把你这两个啊,比如说先拿着它啊,然后再拿着它进行循环遍历啊,那它循环遍历干什么的呢?注册订阅的方法,哎,注册订阅方法,也就是说将你当前这两个方法注册到总的。这个事件总线中,比如说当前这个是。啊,没有,它这里面有两个实验方法,一个是实训类型的。一个是呢,那个method event啊,代表了event,这是两个事件类型啊一啊,那么它就循环便利这两个方法。
14:00
啊,他去干什么呢,他要注册到总的这个。这个事件总线上,它为啥要放在它总的事件上,你想想我这边不止一个activity吧,可能还有一个b activity。啊b activity,那么这里面是不是也有相应的定位的方法,定阅的方法啊啊,然后呢,我这面还有可能有一个c activity,那这里面也有它的定阅的方法和注射的方法,那么这么多方法,哎,而且他这里也有可能注册了这个实际类型的。啊,那么我是不是把他们要统一归到我这个总的这个金坝总线上,这样的话,我在发送我这个实训类型的事件的时候。我得知道给谁发呀,对不对啊,我得知道谁注册了我才给能给谁发呀,啊,所以说我先把这些东西都注册到统一到我这个inma总线的集合中啊,注册完之后,那么我在发送的时候,我就哎便利你这个种子的集合,我就给你发就OK了啊就这么个意思。
15:06
好,那我们就要看一下这个注册订阅的方法啊,变换进来,将这个方法啊传进来,这个呢是当前的订阅者,也就是这个main activity2个参数,一个是main activity,一个是注射的方法好进来。进来之后啊,首先呢,干了什么事情呢?获取订阅方法的四件类型。啊,也就是拿到。你是MY还是?好,那么拿到它之后,他又干什么了呢?首先它是通过它啊event type拿到它。拿到它之后,根据订阅事件类型获取所有的订阅者。也就是说根据你当前,比如说传递的是这个实质类型啊,还是这个message event啊,不管你是谁,根据你这个类型,那么我就拿到。
16:03
你所有的订阅者,也就是拿到你这个。因霸总建筑。所有的定位啊,这面是这个是我是。这个是。把你这里面所有定义了这个实类型的注册者啊,定义者拿到。啊,所有的订阅者拿到。那么拿到之后,将订阅者添加到这个script啊,百万的这个集中啊,也就是保存到这个集合中。啊,这个呢,也就是这个bus总线,它总的这一个集合,啊,总的集合是它。那么它这里呢,将这个S啊添加到这里面来,如果它等于空的,我就添加进来啊,就是以前没有添加过啊,我就添加进来。
17:00
好,那么如果找到这个添加进来之后,它还要干什么呢?还要根据优先级将订阅者插入到指定的位置。啊,他要对这些订阅者啊进行一个排序啊,Priority对它进行排序,排序完之后再添加到这个subscription啊这个是订阅者的集合啊,这个呢,你一出来它啊,它这里的数据呢,就会变化啊对它进行排序。是这个过程。那你想啊,其实就是很简单的一件事情啊,带大家看一下这张图。啊,在这张图大家捋一下,首先呢,它就这么一件事,这是这个main activity这里面呢,订阅了两个方法。啊,定阅量方法,但是呢,它还有其他的一些方法啊,他第一件事通过反射或注解的方式获取当前订阅者所有的订阅方法。
18:08
啊,获取定阅方法,其实的目的就是获取这个订阅方法一和订阅方法二。啊拿它,那么具体代码是哪呢?带大家捋一下。啊,讲这个圆啊,还是挺痛苦的啊,大家这个要认真听。嗯,找到这儿。进来这盖体泡我就不说了啊,进来进来之后首先从订阅类中获取所有的订阅方法信息啊,也就是执行这个过程。啊,这些这个。Deb。通过反射和注解,拿到这里面所有的定义方法。啊,然后他。那么。走进来。进来之后。一个是通过反射,一个是通过注解器啊,两种方式。都行,那么进入这个注解器进来,进来之后呢,这里面有一个状态的池啊,状态池呢,主要是为了节省这个开销啊,提高这个性能啊,下面呢,是对它进行初始化,初始化完事之后就是获取订阅的方法啊,主要是这个地方,那么就进来。
19:17
进来呢,首先你可以通过注解啊放获取所有的这个公共的方法啊,如果能获取到那就自然就好了,如果获取不到,那我就通过这个反射啊获取定阅类中所有的方法。啊之后呢,这里面经过啊一顿过滤,包括必须得是共有的啊,参数呢,必须是一个参数长度必须是一个啊同时呢,下面这个还没有添加到集合中啊,如果添加到还不行啊,那么最终就添加到这个集合中了啊,它也是这个过程。获取当前订阅者。啊,订阅方法的事件类型,也就是获取这里面的实质类型还是message event类型啊,接下来根据订阅的事件类型获取even bus的中档,所有的订阅者啊,所有的订阅者啥意思呢?包括你这个B还是C推塔啊这里呢,所有的实时类型我全部拿到。
20:18
啊,也就是把你这个B妹和C啊,它是所有的订阅者,订阅者是包括他他。啊,全部拿到啊,拿到之后将当前订阅者添加到even bus总的这个集合中,啊,拿到他们之后呢,我将我这个main activity也存入到这个总的这个霸集合中。都存到这儿,全部存到这儿。传过来之后,根据优先级将订阅者插入到指定的位置啊,比如说你这个B啊,May和这个C都订阅了这个事件,那么谁先来接受这个事件呢?哎,那么就需要根据你的优先级对你们进行统一的排序啊,这个事情接下来获取当前订阅者所有订阅的世界类型。
21:12
啊,那么我要获取你这个ma xc,它你不注册了吗?这里面有几个事件类型呢,有个实例有一个。一个两个。时间类型。统一添加到这个type by啊,这个集合中,我为啥要把这些事件都添加到这个集合中呢?大家有没有想过?啊,为啥把这个事件添加到这里,我也把这个事件添加到这里,为啥要这么干呢?啊。大家想没想过这个问题,我这是注册了,那如果我on的时候。我是不是要将这些注册的事件都给他解注册啊,啊,那我得知道我要解注册谁吧,啊,所以说呢,我把这些方法全部存到这里面啊,在我解注册的时候,那我就循环便利它,哎将这些事件啊找到,然后呢,统一把这些事件在这个集合中进行删除掉,是不是这样就OK了。
22:12
啊,这两个集合的含义啊,接下来将该事件类型添加到啊这个集合中。好,那其实呢,这里面有两个集合啊,一个是这一个集合。一个是。这即可。换下啊。这一个。这一个两个集合,那么这两个集合干什么呢?再给大家统一说一遍啊,比如说这还有一个BX,这里面呢,也定义了一个实质类型。啊,实质类型这里面呢,它也是实质类型啊,实质类型,那么我首先将你这个BXT放在这里,Mayx也放在这里,我对你们这两个啊订阅者进行排序。啊,等我发消息的时候,我得知道给谁发啊,是给你B发,还是给你这个mayx的发。
23:04
那同时我还定义了这么一个集合,这个集合是干什么呢?它存的是每一个订阅者里面的订阅方法啊,包括它。那么你我存到这里。你。我也存到这里,那么在我on解注册的时候。我就可以啊,循环遍历这个集合啊,遍历这个集合,将你们一一从总的集合中进行删除掉啊,是这个意思啊,其实非常简单,就两个集合,你能搞明白就OK了啊。好。
我来说两句