丝袜人妻一区二区三区_少妇福利无码视频_亚洲理论片在线观看_一级毛片国产A级片

當(dāng)前位置:首頁(yè) > 時(shí)尚生活

returning 性能優(yōu)化,還得看AspectJ

最近,在紐約證券交易所上市一年后,中國(guó)電動(dòng)汽車(chē)初創(chuàng)公司威來(lái)似乎遇到了麻煩。第二季度財(cái)報(bào)顯示,由于旗艦電動(dòng)車(chē)ES8銷(xiāo)量大幅下滑,公司2019年第二季度虧損4.79億美元,僅實(shí)現(xiàn)收入2.2億美元。

這篇文章來(lái)自verymrq的提交,分享了AspectJ的相關(guān)知識(shí),AspectJ是性能優(yōu)化的產(chǎn)物。相信會(huì)對(duì)大家有幫助!同時(shí)也感謝作者精彩的文章。

verymrq的博客地址:

https://me.csdn.net/verymrq

/ AOP /

面向方面編程。

如果OOP把問(wèn)題分成單個(gè)模塊,AOP統(tǒng)一管理某一類(lèi)涉及多個(gè)模塊的問(wèn)題。比如登錄、傳輸、大文件上傳三個(gè)模塊?,F(xiàn)在,有必要添加性能測(cè)試功能來(lái)計(jì)算這三個(gè)模塊各花費(fèi)多少時(shí)間。

OOP思想是設(shè)計(jì)一個(gè)性能檢測(cè)模塊,提供這三個(gè)模塊調(diào)用的接口。這樣,每個(gè)模塊都應(yīng)該調(diào)用性能測(cè)試模塊的接口。如果改變接口,需要在每次調(diào)用這三個(gè)模塊的地方進(jìn)行修改。

AOP的思想是在特定的切入點(diǎn)掛接這些獨(dú)立的模塊,在不影響原有模塊獨(dú)立性的情況下,給模塊增加共同的邏輯。

所以,這就是我上面說(shuō)的:統(tǒng)一管理某一類(lèi)涉及多個(gè)模塊的問(wèn)題。

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

APT應(yīng)用:Dagger,butterKnife,組件化方案等等AspectJ:主要用于性能監(jiān)控,日志埋點(diǎn)等Javassist:熱更新(可以在編譯后,打包Dex之前干事情,可以突破一下限制)

/ AspectJ /

AspectJ是今天的主角,主要用在不想侵犯原代碼的場(chǎng)景中。比如SDK需要在不入侵的情況下向主機(jī)中插入一些代碼,進(jìn)行日志記錄、性能監(jiān)控、動(dòng)態(tài)權(quán)限控制,甚至代碼調(diào)試。

訪(fǎng)問(wèn)說(shuō)明

首先,您需要在項(xiàng)目根目錄的build.gradle中添加依賴(lài)項(xiàng):

構(gòu)建{

倉(cāng)庫(kù){

共享

}

依賴(lài)項(xiàng){

class path ' com . Android . tools . build:gradle:2 . 3 . 0-beta 2 '

類(lèi)路徑' com . Hu Jiang . aspectjx:gradle-Android-plugin-aspectjx:2 . 0 . 6 '

}

}

然后將AspectJ依賴(lài)項(xiàng)添加到主項(xiàng)目或庫(kù)的build.gradle中:

compile ' org . AspectJ:AspectJ rt:1 . 8 . 9 '

同時(shí),添加AspectJX模塊進(jìn)行build.gradle:

應(yīng)用插件:' android-aspectjx '

這樣就配置好了Android Studio中AspectJ的環(huán)境。如果在編譯過(guò)程中遇到“無(wú)法確定缺失類(lèi)型xxxxx的超類(lèi)”等錯(cuò)誤,請(qǐng)參考項(xiàng)目自述文件中excludeJarFilter的使用。

aspectjx {

//包含您想要編制的libs

包括圖像過(guò)濾器'通用圖像加載器',' AspectJX-演示/庫(kù)'

//不包括您不想編制的lib

排除圖像過(guò)濾器'通用圖像加載器'

}

基本用途

直接看代碼,在活動(dòng):

@覆蓋

protected void oncreate(@ Nullable Bundle savedInstanceState){

super . OnCreate(SaveDinstancestate);

testMethod

}

privatevoidtestMethod{

Log.e(DemoAspect。標(biāo)簽,“TestMethod-invoke”);

}

創(chuàng)建新的DemoAspect類(lèi):

@方面

publicclassDemoAspect{

publicationstatifinString TAG = " DeMoaspect ";

@ Before(" execution(* com . Hu Jiang . library . demo . demo activity . test *(..))")

publicvoidtestAspectBefore(連接點(diǎn)){

Log.e(TAG,point . GetSignature . GetName+"-before ");

}

}

運(yùn)行時(shí)打印:

test method-before com . hujiang . library . demo E/demo aspect:test method-invoke

為了完成插入操作,我們只需要

類(lèi)上加入注釋@Aspect方法上加入注釋@BeforeBefore里寫(xiě)入要插入的相關(guān)信息

很簡(jiǎn)單嗎?下面詳細(xì)解釋一下。

建議

也就是說(shuō),要插入的代碼是如何插入的,就是方法上的注釋。

前后都很好理解,上面的例子已經(jīng)說(shuō)的很清楚了。

返回后

適用于需要獲取返回值的情況,如:

privateintAfterReturningTest {

Log.e(DemoAspect。標(biāo)簽,“after returning-invoke”);

返回10;

}

@ after returning(value = " execution(* com . hujiang . library . demo . demo activity . after returning *(..))",返回= "num ")

public void testaspectafterreturning(int num){

Log.e(TAG," after returning-num:"+num);

}

這樣就可以在cut方法中得到返回值。值得注意的是,方法參數(shù)必須與注釋中的值一致。

【returning = "num"】===【intnum】

事后

適用于收集和監(jiān)控異常信息。

privatevoidAfterThrowingTest {

視圖v = null

設(shè)置可見(jiàn)性(視圖。VISIble);

}

@ AFTERROWwing(value = " execution(* com . Hu Jiang . library . demo . demo activity . AFTERROWwing *(..))”,拋出=“異常”)

publicationvoutestaspectafterreturning(異常異常){

Log.e(TAG," after hrowing-exception:"+exception . getmessage);

}

同樣,參數(shù)和注釋中的值必須一致。崩潰也會(huì)在這里發(fā)生,不會(huì)因?yàn)榍衅僮鞫苯颖徊东@,只會(huì)在拋出異常之前打印異常信息。

圍繞

可以在方法執(zhí)行前后調(diào)用,更加靈活。

privatevoidAroundTest{

Log.e(DemoAspect。標(biāo)簽,“around test-invoke”);

}

@ about(" execution(* com . hujiang . library . demo . demo activity . Around test(..))")

public void testaspectround(proceedingjoint point)throws throwable {

Log.e(TAG,point . GetSignature . GetName+"-before ");

繼續(xù);

Log.e(TAG,point . GetSignature . GetName+"-after ");

}

原方法通過(guò)執(zhí)行ProceedingJoinPoint的Proceeding方法調(diào)用,控件靈活。如果你愿意,可以不調(diào)用就截取。

切入點(diǎn)

告訴代碼注入工具在哪里注入特定代碼段的表達(dá)式。也就是例子中的這句話(huà):

@ Before(" execution(* com . Hu Jiang . library . demo . demo activity . test *(..))")

我們分成幾個(gè)部分依次來(lái)看:

@ before: advice,也就是具體的插入點(diǎn),我們已經(jīng)介紹過(guò)了

執(zhí)行:處理連接點(diǎn)的類(lèi)型,如調(diào)用、執(zhí)行和代碼內(nèi)

其中,調(diào)用和執(zhí)行是類(lèi)似的,也就是插入代碼。不同的是執(zhí)行是在切入方法中,調(diào)用是在調(diào)用切入方法之前或者之后。

//通話(huà):

呼叫(之前)

切入點(diǎn){

切入點(diǎn)方法

}

呼叫(之后)

//執(zhí)行:

切入點(diǎn){

執(zhí)行(之前)

切入點(diǎn)方法

執(zhí)行(之后)

}

Withcode通常用于過(guò)濾一些切入條件,以實(shí)現(xiàn)更精確的切入控制,例如:

@覆蓋

受保護(hù)的無(wú)效創(chuàng)建(捆綁保存的實(shí)例){

super . OnCreate(SaveDinstancestate);

setContentView(r . layout . activity _ main);

test1

test2

}

publicvoidtest{

Log.e("丘云飛"," test ");

}

publicvoidtest1{

測(cè)試;

}

publicvoidtest2{

測(cè)試;

}

如果我們想剪切測(cè)試方法,但只想在test2中調(diào)用test來(lái)執(zhí)行剪切方法,我們需要使用withincode。

//在測(cè)試方法中

@ Pointcut(" within code(* com . Hu Jiang . library . aspect . main activity . test2(..))")

publicvoidinvoke2{

}

//調(diào)用測(cè)試方法時(shí)

@ Pointcut(" call(* com . Hu Jiang . library . aspect . main activity . test(..))")

publicvoidinvoke{

}

//同時(shí)滿(mǎn)足前面的條件,即在切入之前在test2方法中調(diào)用測(cè)試方法

@切入點(diǎn)(“調(diào)用& amp& ampinvoke2”)

publicationvoinvokeaonly 2 {

}

@ Before(" invoke only 2 ")

publicationvotybeforeivokeonly 2(連接點(diǎn)連接點(diǎn)){

string key = join point . GetSignature . tostring;

Log.d(TAG," BeforeInvokOnly 2:"+key);

}

MethodPattern:這是最重要的表達(dá)式,大概:@ comment和access right,返回值類(lèi)型和包名。函數(shù)名(參數(shù))

@注釋和訪(fǎng)問(wèn)權(quán)限(public/private/protect和static/final):它們是可選的。如果沒(méi)有設(shè)置,默認(rèn)情況下都是選中的。以訪(fǎng)問(wèn)權(quán)限為例。如果未將訪(fǎng)問(wèn)權(quán)限設(shè)置為條件,將搜索公共、私有、保護(hù)、靜態(tài)和最終功能。

返回值類(lèi)型:是普通函數(shù)的返回值類(lèi)型。如果類(lèi)型不受限制,則用*通配符表示。

包名。函數(shù)名:用于查找匹配的函數(shù)。可以使用通配符,包括and …和+。其中該符號(hào)用于匹配除。,而...表示任何包,符號(hào)+表示子類(lèi)。

* com . Hu Jiang . library . demo . demo activity . test *(..)

第一部分:“”表示返回值,“”表示返回值為任意類(lèi)型。

第二部分:是典型的包名路徑,可以包含""進(jìn)行一般分配,幾個(gè)" "沒(méi)有區(qū)別。在「時(shí)間」,你可以使用「&:& amp;、||、! "結(jié)合各種條件。類(lèi)似于[test*]的寫(xiě)法,是指任何方法名稱(chēng)以test開(kāi)頭的方法。

第三部分:表示這個(gè)方法的參數(shù),可以指定類(lèi)型,比如android.os.Bundle,或者(…)表示任意類(lèi)型任意個(gè)數(shù)的參數(shù),也可以混合編寫(xiě)(android.os.Bundle,…)表示第一個(gè)參數(shù)為Bundle,以下可選。

自定義切入點(diǎn):有時(shí)候需要指定哪些方法需要AOP操作,目標(biāo)明確,也可以通過(guò)標(biāo)注來(lái)完成。先聲明評(píng)論:

@Retention(保留策略。班級(jí))

@Target({ElementType。方法,元素類(lèi)型。類(lèi)型})

public @ InterfaceSpectannotation {

}

然后在切片類(lèi)中定義它:

//使用這個(gè)注釋定義一個(gè)切入點(diǎn)

@ Pointcut(" execution(@ com . Hu Jiang . library . aspect . aspectannotation * *(..))")

publicationvotyaspectannotation {

}

@Before("AspectAnnotation ")

publicvoidtestAspectAnnotation(連接點(diǎn)){

Log.e(TAG,point . getsignature . getname+"-Before ");

}

//用于活動(dòng)

@覆蓋

protected void oncreate(@ Nullable Bundle savedInstanceState){

super . OnCreate(SaveDinstancestate);

注釋測(cè)試;

}

@ AspectannoStation

privatevoidAnnotationTest{

Log.e(DemoAspect。TAG," AnnotationTest-invoke ");

}

很好用,MethodPattern之前也有介紹,所以這里不能省略@這個(gè)注釋。

/AspectJ實(shí)戰(zhàn)/

實(shí)施登錄檢查操作

很多應(yīng)用都有這個(gè)要求,操作前提醒用戶(hù)注冊(cè)登錄,跳轉(zhuǎn)到注冊(cè)或登錄界面,如果用AspectJ實(shí)現(xiàn)的話(huà),非常簡(jiǎn)潔無(wú)創(chuàng)。

privateStaticFinaliString TAG = " AspectCommonTool ";

@ Pointcut(" execution(@ XXX . AspectJ . annotation . NeedLogon * *(..))")

publicvoidneedLoginMethod{

}

/**

*插入@ NeedLogin方法

*如果在非活動(dòng)中使用@ NeedLogin,則必須將參數(shù)作為跳轉(zhuǎn)開(kāi)始頁(yè)傳遞到上下文中

*/

@周?chē)?“需求方法”)

public void connected loginaround(proceedingjointpoint proceedingjointpoint)throws可瀏覽{

mContext = null

///proceedingjointpoint . getthis可以獲取調(diào)用此方法的對(duì)象

if(proceedingjointpoint . getthiinstancefcontext){

mccontext =(Context)proceedingjointpoint . getthis;

} else{

///proceedingjointpoint . getargs可以獲取方法的所有參數(shù)

for(對(duì)象上下文:proceedingjointpoint . getargs){

if(上下文實(shí)例上下文){

mContext =(Context)Context;

打破;

}

}

}

if(McContext = = null){

返回;

}

if(LoginUtils.isLogin) {

/**

*如果用戶(hù)登錄,執(zhí)行原始方法

*/

proceedingJoinPoint.proceed .繼續(xù);

} else{

/**

*不登錄跳轉(zhuǎn)到登錄注冊(cè)主界面

*/

}

使用方便,無(wú)創(chuàng),后期維護(hù)容易??梢詫?shí)現(xiàn)類(lèi)似的思路:查看網(wǎng)絡(luò)狀態(tài)、查看權(quán)限狀態(tài)、避免多次點(diǎn)擊按鈕、自動(dòng)完成緩存等。

性能監(jiān)控

其實(shí)AspectJ在Android中的應(yīng)用主要集中在性能監(jiān)控、日志嵌入等方面。下面是一個(gè)簡(jiǎn)單的例子:

我們監(jiān)控布局加載時(shí)間,判斷布局是否嵌套過(guò)多或復(fù)制過(guò)多,導(dǎo)致活動(dòng)開(kāi)始堵塞。首先,我們知道活動(dòng)通過(guò)設(shè)置內(nèi)容視圖方法加載布局:

布局解析過(guò)程,IO過(guò)程創(chuàng)建View為反射過(guò)程

這兩個(gè)步驟都是耗時(shí)的操作,所以我們需要監(jiān)控setContentView。

@ about(" execution(* Android . app . Activity . SetContentView(..))")

publicationgetcontentviewtime(proceedingjoint point)throws throwable {

string name = point . GetSignature . ToshortString;

long time = system . CurrentiMemillis;

繼續(xù);

Log.e(TAG,name+" cost:"+(System . CurrentiMemillis-time));

}

//活動(dòng)

publicClassDemoactivityExtendsAppCompactivity {

@覆蓋

protected void oncreate(@ Nullable Bundle savedInstanceState){

super . OnCreate(SaveDinstancestate);

setContentView(r . layout . activity _ main);

}

}

按如下方式打印日志:

demo aspect:AppCompactivity . SetContentView(..)成本:76

在日常開(kāi)發(fā)中,我們可以將時(shí)間上傳到服務(wù)器,收集用戶(hù)信息,找到Caton Activity,進(jìn)行相應(yīng)的優(yōu)化。

當(dāng)然,這是一個(gè)非常簡(jiǎn)單的實(shí)現(xiàn),您也可以在實(shí)際開(kāi)發(fā)中監(jiān)控您想要監(jiān)控的各種位置。

1.《returning 性能優(yōu)化,還得看AspectJ》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識(shí),僅代表作者本人觀點(diǎn),與本網(wǎng)站無(wú)關(guān),侵刪請(qǐng)聯(lián)系頁(yè)腳下方聯(lián)系方式。

2.《returning 性能優(yōu)化,還得看AspectJ》僅供讀者參考,本網(wǎng)站未對(duì)該內(nèi)容進(jìn)行證實(shí),對(duì)其原創(chuàng)性、真實(shí)性、完整性、及時(shí)性不作任何保證。

3.文章轉(zhuǎn)載時(shí)請(qǐng)保留本站內(nèi)容來(lái)源地址,http://f99ss.com/shehui/1085691.html

上一篇

房客退租滿(mǎn)屋垃圾 登上網(wǎng)絡(luò)熱搜了!

下一篇

造物法則2先鋒英雄 造物法則2先鋒英雄:新玩法上線(xiàn)!銀月討伐來(lái)襲

淘貨源批發(fā) 開(kāi)淘寶店找貨源的九種方法,總有一種適合你

淘貨源批發(fā) 開(kāi)淘寶店找貨源的九種方法,總有一種適合你

剛?cè)胄械男≠u(mài)家可能沒(méi)有意識(shí)到產(chǎn)品的重要性。以為可以直通車(chē),可以?xún)?yōu)化,可以掌握各種秘籍,可以把任何一個(gè)寶都推成爆款,其實(shí)忽略了銷(xiāo)售的本質(zhì)。 反之,如果有貨源好,性?xún)r(jià)比高,寶貝,那就推舟。小賣(mài)家最頭疼的就是如何找到好的貨源。這次主要說(shuō)找哪些渠道。 首先,寄售 這是最常見(jiàn)最簡(jiǎn)單的。百度搜索很多,門(mén)...

速算24點(diǎn)的小竅門(mén) 紙牌游戲24點(diǎn)的規(guī)則和方法分享

速算24點(diǎn)的小竅門(mén) 紙牌游戲24點(diǎn)的規(guī)則和方法分享

24點(diǎn)算法是一種棋牌數(shù)學(xué)休閑益智游戲,將四張撲克牌的數(shù)字相加、相減、相乘、相除(包括括號(hào))使計(jì)算結(jié)果等于24。這個(gè)小游戲可以訓(xùn)練人的快速反應(yīng)能力。除了平時(shí)的休閑娛樂(lè)之外,它在數(shù)學(xué)課堂教學(xué)或數(shù)學(xué)周的小競(jìng)賽中經(jīng)常被許多老師使用,因?yàn)樗梢詷O大地調(diào)動(dòng)學(xué)生各種感官的協(xié)調(diào)能力,非常有利于培養(yǎng)學(xué)生的心算...

便秘怎么辦快速排便的方法 大便硬、拉不出,便秘怎么辦?這些日常方法有助你快速排便~

  • 便秘怎么辦快速排便的方法 大便硬、拉不出,便秘怎么辦?這些日常方法有助你快速排便~
  • 便秘怎么辦快速排便的方法 大便硬、拉不出,便秘怎么辦?這些日常方法有助你快速排便~
  • 便秘怎么辦快速排便的方法 大便硬、拉不出,便秘怎么辦?這些日常方法有助你快速排便~

字體安裝方法 電腦字體快速安裝刪除管理的方法

  • 字體安裝方法 電腦字體快速安裝刪除管理的方法
  • 字體安裝方法 電腦字體快速安裝刪除管理的方法
  • 字體安裝方法 電腦字體快速安裝刪除管理的方法

搜圖 以圖搜圖的方法,不管你能不能找到,反正我能!

  • 搜圖 以圖搜圖的方法,不管你能不能找到,反正我能!
  • 搜圖 以圖搜圖的方法,不管你能不能找到,反正我能!
  • 搜圖 以圖搜圖的方法,不管你能不能找到,反正我能!

意大利翻譯 意大利語(yǔ)怎么翻譯成英文?這三個(gè)方法簡(jiǎn)單又實(shí)用

  • 意大利翻譯 意大利語(yǔ)怎么翻譯成英文?這三個(gè)方法簡(jiǎn)單又實(shí)用
  • 意大利翻譯 意大利語(yǔ)怎么翻譯成英文?這三個(gè)方法簡(jiǎn)單又實(shí)用
  • 意大利翻譯 意大利語(yǔ)怎么翻譯成英文?這三個(gè)方法簡(jiǎn)單又實(shí)用

瘊子的最佳治療方法 治療尋常疣這三種方法最好不要選!

  • 瘊子的最佳治療方法 治療尋常疣這三種方法最好不要選!
  • 瘊子的最佳治療方法 治療尋常疣這三種方法最好不要選!
  • 瘊子的最佳治療方法 治療尋常疣這三種方法最好不要選!

starnet 值得收藏!基于激光雷達(dá)數(shù)據(jù)的深度學(xué)習(xí)目標(biāo)檢測(cè)方法大合集(下)

  • starnet 值得收藏!基于激光雷達(dá)數(shù)據(jù)的深度學(xué)習(xí)目標(biāo)檢測(cè)方法大合集(下)
  • starnet 值得收藏!基于激光雷達(dá)數(shù)據(jù)的深度學(xué)習(xí)目標(biāo)檢測(cè)方法大合集(下)
  • starnet 值得收藏!基于激光雷達(dá)數(shù)據(jù)的深度學(xué)習(xí)目標(biāo)檢測(cè)方法大合集(下)