最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android AOP框架AspectJ使用詳解

 更新時間:2017年11月18日 09:03:42   作者:三十二蟬  
本篇文章主要介紹了Android AOP框架AspectJ使用詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

前言

之前了解過android的AOP框架,用法主要用來打日志;現(xiàn)在有一個需求需要函數(shù)在新線程中執(zhí)行,并且函數(shù)主體執(zhí)行完之后,在UI線程返回結果。想到手寫的話,每次都要new Thread的操作,比較麻煩;因此就嘗試用注解的方法解決這個問題。

AspectJ的使用核心就是它的編譯器,它就做了一件事,將AspectJ的代碼在編譯期插入目標程序當中,運行時跟在其它地方沒什么兩樣,因此要使用它最關鍵的就是使用它的編譯器去編譯代碼ajc。ajc會構建目標程序與AspectJ代碼的聯(lián)系,在編譯期將AspectJ代碼插入被切出的PointCut中,已達到AOP的目的。

因此,無論在什么IDE上(如果使用命令行就可以直接使用ajc編譯了),問題就是讓IDE使用ajc作為編譯器編譯代碼。

代碼實現(xiàn)

注解使用

代碼主要通過TraceLog、RunOnNewThread、RunOnNewThreadWithUICallback這三個注解與AOP容器關聯(lián)。使用方法如下:

@TraceLog
@RunOnNewThread
public void checkAndRestartDownloadTask(final boolean isAutoCache) {
 DownloadManager.getInstance().startService(isAutoCache);
}


@TraceLog
@RunOnNewThreadWithUICallback
public Boolean isShowTipsForFirstVideoCache(DBQueryCallback<Boolean> callback) {
 if (!PreferenceClient.is_first_video_cache_done.getBoolean() &&
   (DownloadManager.getInstance().getFinishedTaskSize(true, false) > 0 ||
     DownloadManager.getInstance().getFinishedTaskSize(true, true) > 0)) {
  PreferenceClient.is_first_video_cache_done.setBoolean(true);
  return true;
 }
 return false;
}

checkAndRestartDownloadTask方法,希望方法體在一個新的線程執(zhí)行并打印方法執(zhí)行的Log;isShowTipsForFirstVideoCache方法,希望方法體在一個新的線程執(zhí)行,并將函數(shù)的結果通過DBQueryCallback這個回調回傳給UI線程,同時打印方法執(zhí)行的Log。

AOP容器識別這三個注解,并實現(xiàn)注解解釋器。

@Aspect
public class TudouDownloadAspect {
 public static final String TAG = TudouDownloadAspect.class.getSimpleName();

 private static final String THREAD_CALLBACK_POINT_METHOD =
   "execution(@com.download.common.aspect.RunOnNewThreadWithUICallback * *(.., com.download.common.callback.DBQueryCallback))";
 private static final String THREAD_CALLBACK_POINT_CONSTRUCTOR =
   "execution(@com.download.common.aspect.RunOnNewThreadWithUICallback *.new(.., com.download.common.callback.DBQueryCallback))";

 private static final String THREAD_POINT_METHOD =
   "execution(@com.download.common.aspect.RunOnNewThread * *(..))";
 private static final String THREAD_POINT_CONSTRUCTOR =
   "execution(@com.download.common.aspect.RunOnNewThread *.new(..))";

 private static final String LOG_POINT_METHOD =
   "execution(@com.download.common.aspect.TraceLog * *(..))";
 private static final String LOG_POINT_CONSTRUCTOR =
   "execution(@com.download.common.aspect.TraceLog *.new(..))";


 @Pointcut(THREAD_CALLBACK_POINT_METHOD)
 public void methodAnnotatedWithThread(){}
 @Pointcut(THREAD_CALLBACK_POINT_CONSTRUCTOR)
 public void constructorAnnotatedWithThread(){}

 @Pointcut(THREAD_POINT_METHOD)
 public void methodAnnotatedWithNewThread(){}
 @Pointcut(THREAD_POINT_CONSTRUCTOR)
 public void constructorAnnotatedWithNewThread(){}

 @Pointcut(LOG_POINT_METHOD)
 public void methodAnnotatedWithLog(){}
 @Pointcut(LOG_POINT_CONSTRUCTOR)
 public void constructorAnnotatedWithLog(){}

 /**
  * @RunOnNewThreadWithUICallback 的注解解釋器
  * */
 @Around("methodAnnotatedWithThread() || constructorAnnotatedWithThread()")
 public Object wrapNewThreadWithCallback(final ProceedingJoinPoint joinPoint) throws Throwable {
  Log.v(TAG, "in wrapNewThreadWithCallback");
  Object[] objs = joinPoint.getArgs();
  final DBQueryCallback callback = (DBQueryCallback) objs[objs.length-1];
  new Thread(new Runnable() {
   @Override
   public void run() {
    try {
     final Object obj = joinPoint.proceed();
     DownloadClient.getInstance().mainHandler.post(new Runnable() {
      @Override
      public void run() {
       if (obj != null)
        callback.querySuccess(obj);
       else
        callback.queryFail();
      }
     });
    } catch (Throwable throwable) {
     throwable.printStackTrace();
    }
   }
  }).start();
  return null;
 }

 /**
  * @RunOnNewThread 的注解解釋器
  * */
 @Around("methodAnnotatedWithNewThread() || constructorAnnotatedWithNewThread()")
 public void wrapNewThread(final ProceedingJoinPoint joinPoint) throws Throwable {
  Log.v(TAG, "in wrapNewThread");
  new Thread(new Runnable() {
   @Override
   public void run() {
    try {
     joinPoint.proceed();
    } catch (Throwable throwable) {
     throwable.printStackTrace();
    }
   }
  }).start();

 }

 /**
  * @TraceLog 的注解解釋器
  * */
 @Before("methodAnnotatedWithLog() || constructorAnnotatedWithLog()")
 public void wrapWithLog(JoinPoint joinPoint) throws Throwable {
  Log.v(TAG, "before->" + joinPoint.getTarget().toString() + "---" + joinPoint.getSignature().getName());
 }

}

  1. @Aspect:聲明一個AOP容器
  2. @Pointcut:聲明一個切入點
  3. @Around:將函數(shù)主體包裹起來,在函數(shù)主體前、后插入代碼
  4. @Before:在函數(shù)主體執(zhí)行之前插入代碼

使用Gradle腳本加載AOP容器

buildscript {
  repositories {
    mavenLocal()
    maven { url "https://jitpack.io" }
  }
  dependencies {
    classpath 'org.aspectj:aspectjtools:1.8.+' //AspectJ腳本依賴
  }
}

 dependencies {
    compile 'org.aspectj:aspectjrt:1.8.+' //AspectJ 代碼依賴
  }

//AspectJ AOP容器加載腳本
final def log = project.logger
final def variants = project.android.libraryVariants
variants.all { variant ->
  JavaCompile javaCompile = variant.javaCompile
  javaCompile.doLast {
    String[] args = ["-showWeaveInfo",
             "-1.5",
             "-inpath", javaCompile.destinationDir.toString(),
             "-aspectpath", javaCompile.classpath.asPath,
             "-d", javaCompile.destinationDir.toString(),
             "-classpath", javaCompile.classpath.asPath,
             "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)]
    log.debug "ajc args: " + Arrays.toString(args)

    MessageHandler handler = new MessageHandler(true);
    new Main().run(args, handler);
    for (IMessage message : handler.getMessages(null, true)) {
      switch (message.getKind()) {
        case IMessage.ABORT:
        case IMessage.ERROR:
        case IMessage.FAIL:
          log.error message.message, message.thrown
          break;
        case IMessage.WARNING:
          log.warn message.message, message.thrown
          break;
        case IMessage.INFO:
          log.info message.message, message.thrown
          break;
        case IMessage.DEBUG:
          log.debug message.message, message.thrown
          break;
      }
    }
  }
}

備注

@RunOnNewThreadWithUICallback這個注解的匹配規(guī)則需要函數(shù)的最后一個參數(shù)為DBQueryCallback(必須要有一個回調參數(shù),不然怎么回傳給UI線程~)。函數(shù)的返回值必須和DBQueryCallback的泛型類型一致,因為需要將返回值傳入回調當中;

new Thread(new Runnable() {
   @Override
   public void run() {
    try {
     final Object obj = joinPoint.proceed();
     DownloadClient.getInstance().mainHandler.post(new Runnable() {
      @Override
      public void run() {
       if (obj != null)
        callback.querySuccess(obj);
       else
        callback.queryFail();
      }
     });
    } catch (Throwable throwable) {
     throwable.printStackTrace();
    }
   }
  }).start();

注意final Object obj = joinPoint.proceed();,執(zhí)行了函數(shù)體以后,我們默認取到的是一個Object類型的返回值,所以不能用基本數(shù)據類型(bool用Boolean,int用Interger)。還有一點,Java中的null是可以轉化為任意類型的,所以就算在函數(shù)體直接返回null,執(zhí)行final Object obj = joinPoint.proceed();,這個類型轉化也是不會有問題。親測有效,可以放心使用

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Android AsyncTask使用以及源碼解析

    Android AsyncTask使用以及源碼解析

    這篇文章主要為大家詳細解析了Android AsyncTask使用以及源碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Android識別預裝的第三方App方法實例

    Android識別預裝的第三方App方法實例

    這篇文章主要給大家介紹了關于Android如何識別預裝的第三方App的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧
    2019-01-01
  • Android實現(xiàn)短信發(fā)送功能

    Android實現(xiàn)短信發(fā)送功能

    這篇文章主要介紹了Android實現(xiàn)短信發(fā)送功能,對Android實現(xiàn)短信發(fā)送的每一步都進行了詳細的介紹,感興趣的小伙伴們可以參考一下
    2015-12-12
  • Android View進行手勢識別詳解

    Android View進行手勢識別詳解

    本文主要介紹 Android View進行手勢識別,這里整理了相關資料和簡單示例,有興趣的小伙伴可以參考下
    2016-08-08
  • android自定義組件實現(xiàn)方法

    android自定義組件實現(xiàn)方法

    這篇文章主要介紹了android自定義組件實現(xiàn)方法,實例分析了Android實現(xiàn)自定義組件中頁面布局及功能實現(xiàn)的相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • Android中的序列化淺析

    Android中的序列化淺析

    這篇文章主要介紹了Android中的序列化淺析,本文講解了序列化原因、序列化方法和代碼實現(xiàn)等內容,需要的朋友可以參考下
    2015-03-03
  • Kotlin 協(xié)程 supervisorScope {} 運行崩潰解決方法

    Kotlin 協(xié)程 supervisorScope {} 運行崩潰解決方法

    看過很多?supervisorScope {}?文檔的使用,我照抄一摸一樣的代碼,運行就崩潰,最后找到了解決方法,應該是kotlin版本更新做過改動,當前我使用的是?androidx.core:core-ktx:1.9.0,本文給大家介紹Kotlin 協(xié)程 supervisorScope {} 運行崩潰解決方法,感興趣的朋友一起看看吧
    2024-01-01
  • android開發(fā)實現(xiàn)列表控件滾動位置精確保存和恢復的方法(推薦)

    android開發(fā)實現(xiàn)列表控件滾動位置精確保存和恢復的方法(推薦)

    下面小編就為大家?guī)硪黄猘ndroid開發(fā)實現(xiàn)列表控件滾動位置精確保存和恢復的方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • 淺析Android錄屏 MediaRecorder

    淺析Android錄屏 MediaRecorder

    MediaRecorder類是Android sdk提供的一個專門用于音視頻錄制,一般利用手機麥克風采集音頻,攝像頭采集圖片信息。這篇文章主要介紹了Android錄屏 MediaRecorder介紹,需要的朋友可以參考下
    2020-03-03
  • fragment實現(xiàn)隱藏及界面切換效果

    fragment實現(xiàn)隱藏及界面切換效果

    這篇文章主要為大家詳細介紹了fragment實現(xiàn)隱藏及界面切換效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11

最新評論

宝山区| 茶陵县| 蒲城县| 平邑县| 伊通| 辽阳市| 濉溪县| 永新县| 会泽县| 福泉市| 沭阳县| 和龙市| 天气| 南川市| 泸溪县| 姚安县| 和龙市| 凭祥市| 丰都县| 合山市| 马边| 福清市| 太保市| 平邑县| 南充市| 奈曼旗| 上饶县| 稷山县| 大城县| 手机| 禄劝| 乌兰浩特市| 崇仁县| 崇义县| 介休市| 连城县| 泰顺县| 城口县| 曲阜市| 上犹县| 万州区|