安卓AOP實(shí)戰(zhàn):Javassist強(qiáng)擼EventBus

前言

EventBus到了3.0版本,使用Apt注解處理器來(lái)在編譯期通過(guò)讀取@Subscribe()注解并解析生成java類來(lái)保存訂閱者關(guān)于的信息,比在之前使用反射來(lái)獲得這些訂閱者的信息速度要快屿聋。但是事件觸發(fā)依然是使用method.invoke來(lái)調(diào)用征字“鑫縱觀EventBus的源碼刑枝,還是有大量使用反射的地方。

然而惧辈,盡管反射非常強(qiáng)大,但也不能隨意大量使用。如果一個(gè)功能可以不用反射完成凑懂,那么最好就不用。由于反射允許代碼執(zhí)行一些在正常情況下不被允許的操作(比如訪問(wèn)私有的屬性和方法)梧宫,所以使用反射可能會(huì)導(dǎo)致意料之外的副作用接谨,使用反射相對(duì)來(lái)說(shuō)不安全 --代碼有功能上的錯(cuò)誤,降低可移植性塘匣。反射代碼破壞了類的封裝性抽象性脓豪,因此當(dāng)平臺(tái)發(fā)生改變的時(shí)候,代碼的行為就有可能也隨著變化忌卤。而且使用反射的性能較低扫夜。

反射這個(gè)異教徒,并不屬于OOP的范疇驰徊,簡(jiǎn)直就是代碼界的IS笤闯,強(qiáng)行蹂躪對(duì)象,破壞原有結(jié)構(gòu)棍厂,對(duì)面向?qū)ο蟮氖澜缬^進(jìn)行殘(危)酷(言)肢(聳)解(聽(tīng))颗味。好了,進(jìn)入正題:

我眼中EventBus的缺點(diǎn):
一牺弹,不夠簡(jiǎn)潔:需要手寫(xiě)大量register和unregister的垃圾代碼浦马,這對(duì)我來(lái)說(shuō)是致命的缺點(diǎn)
二时呀、不夠高效:雖然用了Apt和METHOD_CACHE來(lái)優(yōu)化了反射,單仍然不夠完美理想化
三捐韩、不夠?qū)Wⅲ菏录鬟f的框架退唠,就不需要關(guān)心線程切換什么的吧,你這么牛逼RxJava知道嗎

好了荤胁,話不多說(shuō)瞧预,開(kāi)車。

先看效果:

OkBus

對(duì)仅政,沒(méi)錯(cuò)垢油,觸發(fā)事件一句代碼:

OkBus.getInstance().onEvent(EventTags.JUMP_TO_MAIN, null);

接收事件一句代碼

@Bus(tag = EventTags.JUMP_TO_MAIN)

支持粘連事件(先觸發(fā)后注冊(cè))

OkBus.getInstance().onStickyEvent(EventTags.FLASH_INIT_UI, null);

什么?注冊(cè)和反注冊(cè)圆丹?這些代碼全部都是插件自動(dòng)生成滩愁,不用再手動(dòng)寫(xiě)啦!

Javassist在編譯期間通過(guò)插件辫封,已經(jīng)幫你自動(dòng)生成注冊(cè)硝枉、反注冊(cè)、事件分發(fā)的代碼并且?guī)湍慵由侠簿胛ⅲ∪绻麤](méi)有這樣的方法妻味,會(huì)自動(dòng)生成并加上,如果本來(lái)就有欣福,就更簡(jiǎn)單了责球,直接在方法里面追加就可以了。

來(lái)看build/intermediates/transforms下的源代碼


transforms下的源代碼

Activity(Fragment)有onCreate(onActivityCreated)拓劝,onDestroy可以自動(dòng)加雏逾,想在別的地方用怎么辦?

請(qǐng)看Presenter中用法:

Presenter中用法

即使沒(méi)有那樣的時(shí)機(jī)讓插件自動(dòng)插入郑临,那只要吱個(gè)聲(加個(gè)注解)栖博,插件也會(huì)自己自動(dòng)幫你加。

添加后的代碼:

自動(dòng)插入后的代碼

需要在哪個(gè)方法里注冊(cè)就加上@BusRegister注解厢洞,反注冊(cè)就加@BusUnRegister仇让,現(xiàn)在你可以在任何地方使用了。

那要是忘加注解了怎么辦犀变?

別急妹孙,插件依然會(huì)在編譯期間提醒你:

非正常使用會(huì)報(bào)錯(cuò)

所有一切都是編譯期間所做的秋柄,零反射零代理获枝。實(shí)現(xiàn)的方式,不過(guò)一類骇笔,一插件省店,一注解嚣崭,百余行代碼而已。

1懦傍、OkBus類

OkBus屬性:

主要就是基本信息的存儲(chǔ)和單例的實(shí)現(xiàn)

OkBus屬性
OkBus register方法:

注冊(cè)的時(shí)候放入回調(diào)列表雹舀,如果是粘連事件,注冊(cè)時(shí)就去已分發(fā)的粘連事件庫(kù)存去拿參數(shù)并觸發(fā)回調(diào)粗俱。

OkBus register方法
OkBus反注冊(cè)和觸發(fā)事件方法:

反注冊(cè)就直接remove回調(diào)说榆,觸發(fā)時(shí)分普通事件和粘連事件,粘連事件就存庫(kù)里備用

OkBus反注冊(cè)和觸發(fā)事件方法

OK寸认,以上就是全部代碼签财。這里直接用回調(diào)實(shí)現(xiàn)事件通知,沒(méi)有什么復(fù)雜的邏輯偏塞,現(xiàn)在考慮的情況也比較簡(jiǎn)單

2唱蒸、插件代碼

剩下的都是插件代碼:

BusInfo類:

存儲(chǔ)事件的相關(guān)的信息,便于生成代碼邏輯:

BusInfo類
transform操作

然后在transform中灸叼,根據(jù)源代碼創(chuàng)建BusInfo神汹,處理BusInfo、利用BusHelper操作源代碼進(jìn)行方法和代碼的插入古今,

在transform中屁魏,根據(jù)源代碼創(chuàng)建BusInfo,BusHelper處理BusInfo
BusHelper生成代碼

BusHelper里面有一些模版代碼:

模版代碼

處理BusInfo:

處理BusInfo

獲取初始化OkBus方法的代碼


獲取初始化OkBus方法的代碼

生成event事件分發(fā)的邏輯代碼


生成event事件分發(fā)的邏輯代碼

生成取消事件注冊(cè)的代碼


生成取消事件注冊(cè)的代碼

Ok沧卢,以上便是全部代碼蚁堤,百十行而已(Log占了一大部分),Gradle插件雖然是使用用groovy但狭,我真的完全沒(méi)看過(guò)任何博客學(xué)過(guò)groovy披诗,因?yàn)間roovy完全兼容java,閉著眼睛當(dāng)java寫(xiě)好像并沒(méi)有什么不對(duì)(不要噴我立磁,呈队,,)唱歧。

Javassist實(shí)現(xiàn)邏輯插入的部分宪摧,說(shuō)高深點(diǎn)叫操作修改字節(jié)碼,說(shuō)簡(jiǎn)單點(diǎn)就是字符串拼接颅崩,插入代碼或者方法几于。相比ASM,真的太適合java開(kāi)發(fā)者來(lái)使用了沿后。

以上代碼在T-MVP可以看到沿彭,TMVP本來(lái)想做成庫(kù),現(xiàn)在已經(jīng)徹底淪為實(shí)驗(yàn)室尖滚,歡迎各位客官前來(lái)把玩喉刘。

OK瞧柔,車已到站,下車請(qǐng)刷卡

QQ群:AndroidMVP 555343041

更新日志:

2017/1/31:AOP新增SysPermissionAspect支持動(dòng)態(tài)申請(qǐng)系統(tǒng)權(quán)限切片睦裳,輕松適配6.0+

2017/1/27:AOP新增DbRealmAspect支持Realm數(shù)據(jù)庫(kù)造锅,數(shù)據(jù)庫(kù)突破你想像的簡(jiǎn)單(年夜特供)

2017/1/8: 使用Apt封裝Retrofit生成ApiFactory替換掉所有的Repository,狂刪代碼

2017/1/7: 使用DataBinding替換掉所有的ButterKnife廉邑,狂刪代碼

2017/1/6: 使用DataBinding替換掉所有的ViewHolder哥蔚,狂刪代碼,從此邁向新時(shí)代

2016/12/30:使用Apt生成全局路由TRouter蛛蒙,更優(yōu)雅的頁(yè)面跳轉(zhuǎn)肺素,支持傳遞參數(shù)和共享view轉(zhuǎn)場(chǎng)動(dòng)畫(huà)

2016/12/29:去掉BaseMultiVH新增VHClassSelector支持更完美的多ViewHolder

2016/12/28:使用Apt生成全局的ApiFactory替代所有的Model

2016/12/27:增加了BaseMultiVH擴(kuò)展支持多類型的ViewHolder

2016/12/26:抽離CoreAdapterPresenter優(yōu)化TRecyclerView

安卓AOP實(shí)戰(zhàn):面向切片編程

Android實(shí)用技巧之:用好泛型,少寫(xiě)代碼

安卓AOP實(shí)戰(zhàn):APT打造極簡(jiǎn)路由

全局路由TRouter,更優(yōu)雅的頁(yè)面跳轉(zhuǎn)

安卓AOP實(shí)戰(zhàn):Javassist強(qiáng)擼EventBus

加入OkBus宇驾,實(shí)現(xiàn)注解傳遞事件

安卓AOP三劍客:APT,AspectJ,Javassist

1倍靡、去掉所有反射>2、新增apt初始化工廠课舍,替換掉了dagger2塌西。>3、新增aop切片筝尾,處理緩存和日志

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末捡需,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子筹淫,更是在濱河造成了極大的恐慌站辉,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件损姜,死亡現(xiàn)場(chǎng)離奇詭異饰剥,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)摧阅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)汰蓉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人棒卷,你說(shuō)我怎么就攤上這事顾孽。” “怎么了比规?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵若厚,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蜒什,道長(zhǎng)测秸,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮乞封,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘岗憋。我一直安慰自己肃晚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布仔戈。 她就那樣靜靜地躺著关串,像睡著了一般。 火紅的嫁衣襯著肌膚如雪监徘。 梳的紋絲不亂的頭發(fā)上晋修,一...
    開(kāi)封第一講書(shū)人閱讀 51,541評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音凰盔,去河邊找鬼墓卦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛户敬,可吹牛的內(nèi)容都是我干的落剪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼尿庐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼忠怖!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起抄瑟,我...
    開(kāi)封第一講書(shū)人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤凡泣,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后皮假,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鞋拟,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年惹资,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了严卖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡布轿,死狀恐怖哮笆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情汰扭,我是刑警寧澤稠肘,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站萝毛,受9級(jí)特大地震影響项阴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一环揽、第九天 我趴在偏房一處隱蔽的房頂上張望略荡。 院中可真熱鬧,春花似錦歉胶、人聲如沸汛兜。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)粥谬。三九已至,卻和暖如春辫塌,著一層夾襖步出監(jiān)牢的瞬間漏策,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工臼氨, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掺喻,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓储矩,卻偏偏與公主長(zhǎng)得像巢寡,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子椰苟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,133評(píng)論 25 707
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理抑月,服務(wù)發(fā)現(xiàn),斷路器舆蝴,智...
    卡卡羅2017閱讀 134,657評(píng)論 18 139
  • AOP:面向切面編程(Aspect-Oriented Programming)谦絮。如果說(shuō),OOP如果是把問(wèn)題劃分到單...
    North_2016閱讀 46,756評(píng)論 38 269
  • 1. AOP與OOP的區(qū)別 平時(shí)我接觸多的就是OOP(Object Oriented Programming面向?qū)?..
    生椰拿鐵錘閱讀 2,388評(píng)論 3 22
  • 小時(shí)住城墻邊洁仗,屋前后有兩個(gè)院子层皱,周圍大小朋友都愛(ài)來(lái)玩。前院有些果樹(shù)赠潦,因不愛(ài)吃只甜的水果叫胖,無(wú)花果和青葡萄從來(lái)不碰。后...
    貓姆的畫(huà)外音閱讀 183評(píng)論 0 0