Android代理模式基础,android性能优化和内存优化

文章探讨了Android中AIDL的静态代理实现,以及如何通过动态代理扩展接口。作者对比了两者在扩展性和灵活性上的差异,并展示了动态代理的典型用法和源码分析。
摘要由CSDN通过智能技术生成

@Override
public android.os.IBinder asBinder() {
return null;
}
}
/** Local-side IPC implementation stub class. /
public static abstract class Stub extends android.os.Binder implements com.bc.sample.IMyAidlInterface {
private static final java.lang.String DESCRIPTOR = “com.bc.sample.IMyAidlInterface”;
/
* Construct the stub at attach it to the interface. /
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/
*

  • Cast an IBinder object into an com.bc.sample.IMyAidlInterface interface,
  • generating a proxy if needed.
    */
    public static com.bc.sample.IMyAidlInterface asInterface(android.os.IBinder obj) {
    if ((obj==null)) {
    return null;
    }
    android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
    if (((iin!=null)&&(iin instanceof com.bc.sample.IMyAidlInterface))) {
    return ((com.bc.sample.IMyAidlInterface)iin);
    }
    return new com.bc.sample.IMyAidlInterface.Stub.Proxy(obj);
    }
    @Override public android.os.IBinder asBinder() {
    return this;
    }
    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
    java.lang.String descriptor = DESCRIPTOR;
    switch (code)
    {
    case INTERFACE_TRANSACTION:
    {
    reply.writeString(descriptor);
    return true;
    }
    case TRANSACTION_testFun:
    {
    data.enforceInterface(descriptor);
    this.testFun();
    reply.writeNoException();
    return true;
    }
    default:
    {
    return super.onTransact(code, data, reply, flags);
    }
    }
    }

// 主要关注代理模式的实现;可以看到AIDL的Proxy是通过静态代理模式实现
private static class Proxy implements com.bc.sample.IMyAidlInterface {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override public void testFun() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
boolean _status = mRemote.transact(Stub.TRANSACTION_testFun, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
getDefaultImpl().testFun();
return;
}
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
public static com.bc.sample.IMyAidlInterface sDefaultImpl;
}
static final int TRANSACTION_testFun = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
public static boolean setDefaultImpl(com.bc.sample.IMyAidlInterface impl) {
// Only one user of this interface can use this function
// at a time. This is a heuristic to detect if two different
// users in the same process use this function.
if (Stub.Proxy.sDefaultImpl != null) {
throw new IllegalStateException(“setDefaultImpl() called twice”);
}
if (impl != null) {
Stub.Proxy.sDefaultImpl = impl;
return true;
}
return false;
}
public static com.bc.sample.IMyAidlInterface getDefaultImpl() {
return Stub.Proxy.sDefaultImpl;
}
}
public void testFun() throws android.os.RemoteException;
}

三、动态代理

在2.1的静态代理代码中,如果现在需要扩展一个新的接口,那就需要分别在接口层、实际处理类、代理类中分别改动,如下所示:

// 1.首先定义接口层
interface ILogSender {
public void sendLog(String log);
}

// 2.定义实现类
public class MainLogSender implements ILogSender {

@Override
public void sendLog(String log) {
Log.d(“LogSender”, “MainLogSender send” + log);
}
}

// 3.定义代理类
public class LogSenderProxy implements ILogSender {
// 代理类持有被代理类的引用
private ILogSender mainLogSender = new MainLogSender();

@Override
public void sendLog(String log) {
// 代理类需要完成的一些额外处理
Log.d(“LogSender”, “ProxyLogSender” + log);
String finalLog = Thread.currentThread() + log;
mainLogSender.sendLog(finalLog);
}
}

当代理一个新的接口时可见,新的代理类与其他代理类代码是高度相似的,因此可以采用动态代理的方式来完成类似的功能。

3.1 基础用法

与静态代理不同,动态代理类的class是在运行过程中动态生成的。

3.1.1 基础用法

首先定义接口层:

// 定义接口层
interface ILogProcessor {
public void printLog(String log);
}

然后使用Proxy.newProxyInstance完成动态代理如下:

private void main() {
ILogProcessor proxy = (ILogProcessor) Proxy.newProxyInstance(this.getClassLoader(), new Class<?>[] {ILogPrinter.class}, new InvocationHandler() {

/**

  • @param proxy 代理对象
  • @param method 被调用的方法
  • @param args 被调用的方法的参数列表
    */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
    String log = (String)args[0];
    Log.d(“LogProcessor”, “ProxyLogProcessor” + log);
    String finalLog = Thread.currentThread() + log;
    Log.d(“LogProcessor”, “printLog” + finalLog);
    return null;
    }
    });

proxy.printLog(“”);
}

其中,InvocationHandler就是将静态代理中需要实现的部分抽离了出来,即动态生成的Proxy代理了InvocationHandler。

3.1.2 动态生成的class

动态生成的代理类的方法实际调用都到了InvocationHandler的invoke方法,动态生成的代理类class伪代码如下:

public final class $Proxy0 extends Proxy implements ILogProcessor {
static {
m3 = Class.forName(“com.bc.sample.ILogProcessor”).getMethod(“printLog”);
}
private static Method m3;
public void printLog(String log) {
// 实际调用到了InvocationHandler的invoke方法
super.h.invoke(this, m3, (Object[])log);
}
}

3.1.3 源码分析

下面分析Proxy.newProxyInstance的源码:

public class Proxy implements java.io.Serializable {

// 动态生成的class的缓存;ProxyClassFactory可动态生成代理class
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

img
img

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip204888 备注Android获取(资料价值较高,非无偿)
img

学习交流

群内有许多来自一线的技术大牛,也有在小厂或外包公司奋斗的码农,我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。

35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。

11547963455)]

[外链图片转存中…(img-WhZzPPFZ-1711547963455)]

群内有许多来自一线的技术大牛,也有在小厂或外包公司奋斗的码农,我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。

35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值