Arouter, for example

  • How do I add a method/property to a class/interface and call the new method at code time?
  • How do I modify the content of a method?

arouter-api-onActivitResult

There are two requirements:

Add an onActivityResult method to the ARouter callback NavigationCallback

through

ARouter.getInstance().navigation(mContext, this, requestCode, callback)
Copy the code

Receive the result of onActivityResult directly in the callback.

Prerequisites: Existing libraries:

Through the API ‘com. Making. Hss01248. StartActivityResult: activityresult: 1.0.2’ library, can implement the activity callback one line of code:

StartActivityUtil.startActivity(activity, null, intent, requestCode ! =0
                    , new TheActivityListener<Activity>() {
                        @Override
                        public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
                            super.onActivityResult(requestCode, resultCode, data);
                            if(callback ! =null) { callback.onActivityResult(requestCode, resultCode, data); }}@Override
                        public void onActivityNotFound(Throwable e) {
                            super.onActivityNotFound(e);
                            if(callback ! =null) { callback.onLost(postcard); }}});Copy the code

The key is how to add a nonexistent onActivityResult method to the NavigationCallback in the com.alibaba: Aroutout-API library and make it work.

1. Adding methods:

Write an interface class with the same package name and path. Add the onActivityResult method

Using the classpath “Com. Making. SkyNet2017: JarFilterPlugin: 2.5.5” plug-in, packed out arouter NavigationCallback – API library, so that the more we write their own NavigationCallbac of the method K to take effect.

2. To make the callback work:

Find the startActivityForReuslt code in the arouterter-API and use AspectJX to cut in and replace the entire method implementation:

@Aspect
public class ARouterAspect {

    @Around("execution(* com.alibaba.android.arouter.launcher._ARouter.startActivity(..) )"
    public Object weaveJoinPoint(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        Object result = null;
        
        final int requestCode = (int) args[0];
        Context currentContext = (Context) args[1];
        Intent intent = (Intent) args[2];
        final Postcard postcard = (Postcard) args[3];
        final NavigationCallback callback = (NavigationCallback) args[4];

        if (currentContext instanceof FragmentActivity) {
            FragmentActivity activity = (FragmentActivity) currentContext;
            StartActivityUtil.startActivity(activity, null, intent, requestCode ! =0
                    , new TheActivityListener<Activity>() {
                        @Override
                        public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
                            super.onActivityResult(requestCode, resultCode, data);
                            if(callback ! =null) { callback.onActivityResult(requestCode, resultCode, data); }}@Override
                        public void onActivityNotFound(Throwable e) {
                            super.onActivityNotFound(e);
                            if(callback ! =null) { callback.onLost(postcard); }}}); }else {
            ActivityCompat.startActivity(currentContext, intent, postcard.getOptionsBundle());
        }

        if ((-1! = postcard.getEnterAnim() && -1! = postcard.getExitAnim()) && currentContextinstanceof Activity) {    // Old version.
            ((Activity) currentContext).overridePendingTransition(postcard.getEnterAnim(), postcard.getExitAnim());
        }

        if (null! = callback) {// Navigation over.
            callback.onArrival(postcard);
        }

        returnresult; }}Copy the code

Note the addition of obfuscation rules and the include configuration of AspecJX

Add a log to arouter’s key steps, even to the database for debug purposes

To find the pointcut, aspectJ cuts in. Callback is the interface, using dynamic proxy injection replacement

@Aspect
public class ArouterLogAspect {

    @Around("execution(* com.alibaba.android.arouter.launcher.ARouter.navigation(..) )"
    public Object callbackProxy(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        if(args.length ! =4) {return joinPoint.proceed(args);
        }
        NavigationCallback callback = (NavigationCallback) args[3];
        args[3] = LogProxy.getProxy(callback);
        return joinPoint.proceed(args);
    }
    
    @Around("execution(* com.alibaba.android.arouter.facade.Postcard.setProvider(..) )"
    public Object providerProxy(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        IProvider provider = (IProvider) args[0];
        args[0] = LogProxy.getProxy(provider);
        returnjoinPoint.proceed(args); }}Copy the code