android源码中的反射、代理的应用

1、反射

反射机制是 Java 语言提供的一种基础功能,通过反射我们可以直接操作类或者对象,比如获取某个对象的类定义,获取类声明的属性和方法,调用方法或者构造对象,甚至可以运行时修改类定义。

java.lang 或 java.lang.reflect 包下的相关抽象,就会有一个很直观的印象了。Class、Field、Method、Constructor 等,可以操作类和对象。

反射提供的 AccessibleObject.setAccessible​(boolean flag)。它的子类也大都重写了这个方法,这里的所谓 accessible 可以理解成修饰成员的 public、protected、private,这意味着我们可以在运行时修改成员访问限制。

反射在Android中应用很多,这里列举一个在Android源码中的应用,创建Activity。

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        //...
        ContextImpl appContext = createBaseContextForActivity(r);
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }
        //...
    }

这边将反射的作用总结下:

1、使用反射可以直接操作对象

2、获取某个对象的类定义

3、获取类声明属性和方法

4、调用方法或者构造对象

5、运行时修改类定义 

它的缺点:

性能:能不用反射实现的需求则尽可能避免使用。性能低。

安全:反射需要运行时权限,在安全管理器(SecurityManager)下可能不能运行。反射可以访问private因此可能导致副作用,破坏可移植性,打破抽象。

 2、动态代理

首先,它是一个代理机制。代理可以看作是对调用目标的一个包装,这样我们对目标代码的调用不是直接发生的,而是通过代理完成。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在两者之间起到中介的作用(可类比房屋中介,房东委托中介销售房屋、签订合同等)。

再了解下静态代理,它是事先写好代理类,可以手工编写,也可以用工具生成。缺点是每个业务类都要对应一个代理类,非常不灵活。静态代理在Android源码很常见,但是要分清它和外观模式的区别。

看下ActivityManagerService的代理模式。

在Android7.0中ActivityManager主要对Activity进行管理,但这些工作并不是由ActivityManager来处理,而是交由ActivityManagerService来处理。ActivityManager中的方法通过ActivityManagerNative的getDefault方法得到ActivityManagerProxy,通过ActivityManagerProxy就可以与ActivityManagerNative进行通信,而ActivityManagerNative是一个抽象类,它将功能交由它的ActivityManagerService来处理,因此,ActivityManagerProxy就是ActivityManagerService的代理类。

    
    static public IActivityManager getDefault() {
        return gDefault.get();
    }

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        return new ActivityManagerProxy(obj);
    }

ActivityManagerProxy是ActivityManagerNative的内部类,它们都实现了IActivityManager接口,这样它们就可以实现代理模式,具体来讲是远程代理:ActivityManagerProxy和ActivityManagerNative是运行在两个进程中的,ActivityManagerProxy是Client端,ActivityManagerNative则是Server端,而Server端具体功能都是由ActivityManagerNative的子类ActivityManagerService来实现的,因此,ActivityManagerProxy就是ActivityManagerService在Client端的代理类。ActivityManagerNative又实现了Binder类,这样ActivityManagerProxy和ActivityManagerService就可以通过Binder来进行进程间通信,ActivityManager通过ActivityManagerNative的getDefault方法得到ActivityManagerProxy,通过ActivityManagerProxy就理可以和ActivityManagerService进行通信了。

public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
    
    class ActivityManagerProxy implements IActivityManager
    {
    }

}

 

Android8.0的startActivity调用最后的函数execStartActivity

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        Uri referrer = target != null ? target.onProvideReferrer() : null;
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        //
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

在Android8.0中则不是getDefault,而是getService,getService方法调用了IActivityManagerSingleton的get方法,IActivityManagerSingleton是一个Singleton类。它的内部首先得到名为“activity”的引用,也就是IBinder类型的ActivityManagerService的引用。接着将它转换成IActivityManager类型的对象。

    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

这段代码采用的是AIDL,IActivityManager.java类是由AIDL工具在编译是自动生成的,IActivityManager.aidl的文件路劲为frameworks/base/core/java/android/app/IActivityManager.aidl。要实现进程间通信,服务端也就是ActivityManagerService只需要继承IActivityManager.Stub类并实现相应的方法就可以了。

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
}

aidi

interface IActivityManager {

    //其中的startActivity方法
    int startActivity(in IApplicationThread caller, in String callingPackage, in Intent intent,
            in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode,
            int flags, in ProfilerInfo profilerInfo, in Bundle options);

}

再用AIDL后就不用ActivityManagerService的代理类了。

 

而动态代理是运行时自动生成代理对象。

实现动态代理的方式很多,比如 JDK 自身提供的动态代理,就是主要利用了反射机制。还有其他的实现方式,比如利用字节码操作机制,类似 ASM、CGLIB(基于 ASM)、Javassist 等。

常可采用的JDK提供的动态代理接口InvocationHandler来实现动态代理类。其中invoke方法是该接口定义必须实现的,它完成对真实方法的调用。通过InvocationHandler接口,所有方法都由该Handler来进行处理,即所有被代理的方法都由InvocationHandler接管实际的处理任务。此外,我们常可以在invoke方法实现中增加自定义的逻辑实现,实现对被代理类的业务逻辑无侵入。

cglib 动态代理我不太了解,Android好像没有这方面的应用。

Android中最典型用到动态代理的就是retrofit框架,之后深入了解下它的源码。

这里延申下AOP面相切面编程,对象与对象之间、模块与模块之间都是一个切面。减少代码量的一种方式,是OOP的一个延续。所以通过动态代理也可以实现AOP编程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值