为什么用插件化架构:
- 1.减小apk的大小,用到了才去下,很多功能是用不到的,主apk + 从apk(服务器) 30M 15M + 15M 启动没安装的apk(解决问题)
- 2.为了更新,为了用户体验
插件化实现
我们一般人实现思路,需要加载插件里面的activity,是不会在AndroidManifest.xml里面配置的, 那么就肯定会报错,还要加载类,需要加载插件的资源等等。
解决怎么样让没有在AndroidMnifest.xml里面没有配置的activity也能启动?
- 我要知道activity的启动流程,知道为什么报错
- 想办法绕过去
代理模式使用场景
1 mvp架构
静态代理动态代理都要用 p 绑定 v, p 解绑 v 每个方面都需要判断v还在不在(动态代理)2 DL插件化架构
Activity生命周期都是由代理的Activity调用的,静态代理。3 数据库懒加载
就要使用静态代理。用到了才去加载4 xutils的源码也用到了
setOnclickLstener setOnTouchListner等等 都是动态代理设计模式
静态代理案例:去银行卡办理业务
首先业务:
public interface IBank {
//办卡
public void applyBlank();
//挂失
public void loseBank();
}
Man办卡的人:
public class Man implements IBank{
@Override
public void applyBlank() {
System.out.println("man申请办卡成功");
}
@Override
public void loseBank() {
System.out.println("man挂失银行卡");
}
}
Salesman代理银行人员
public class Salesman implements IBank {
private IBank mBank;
public Salesman(IBank bank) {
mBank = bank;
}
@Override
public void applyBlank() {
if (mBank != null) {
System.out.println("先搞完一些流程");
//调用我们的方法
mBank.applyBlank();
System.out.println("办理完毕");
}
}
@Override
public void loseBank() {
System.out.println("做一些事情");
//调用我们的方法
mBank.loseBank();
System.out.println("完毕");
}
}
客户端调用
Man man=new Man();
Salesman salesman=new Salesman(man);
salesman.applyBlank();
salesman.loseBank();
静态代理的弊端:很多代码相似,代码量会上去
动态代理
public class DynamicClient {
@Test
public void main() {
Man man = new Man();
IBank proxy = (IBank) Proxy.newProxyInstance(
man.getClass().getClassLoader(),
new Class<?>[]{IBank.class},
new BankInvocationHandler(man));
proxy.applyBank();
System.out.println("-----------------------");
proxy.loseBank();
}
private static class BankInvocationHandler implements InvocationHandler {
private IBank mBank;
public BankInvocationHandler(Man man) {
this.mBank = man;
}
// proxy代理对象
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 方法回掉 方法执行还是要 Man 执行
System.out.println("做一些事情");
Object object = method.invoke(mBank, args);
System.out.println("完毕");
return object;
}
}
}
动态代理源码分析
Proxy.newProxyInstance源码分析
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
//主要看这个源码
Class<?> cl = getProxyClass0(loader, intfs);
try {
//通过获得构造函数的new方式创建Object
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
cons.setAccessible(true);
}
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
Class<?> cl = getProxyClass0(loader, intfs);源码分析
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
return proxyClassCache.get(loader, interfaces);
}
proxyClassCache源码分析
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
ProxyClassFactory看这个
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
//代理类的前缀名
private static final String proxyClassNamePrefix = "$Proxy";
// next number to use for generation of unique proxy class names
private static final AtomicLong nextUniqueNumber = new AtomicLong();
@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
//接口集合
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
for (Class<?> intf : interfaces) {
Class<?> interfaceClass = null;
try {
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
//判断是否是个接口
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(
interfaceClass.getName() + " is not an interface");
}
//验证接口是否已经有了
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
throw new IllegalArgumentException(
"repeated interface: " + interfaceClass.getName());
}
}
String proxyPkg = null; // 代理类的包名
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;\
//循环所有的接口集合
for (Class<?> intf : interfaces) {
//获得修饰符
int flags = intf.getModifiers();
//是否是public
if (!Modifier.isPublic(flags)) {
accessFlags = Modifier.FINAL;
String name = intf.getName();//接口的名字
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) {
throw new IllegalArgumentException(
"non-public interfaces from different packages");
}
}
}
if (proxyPkg == null) {
// if no non-public proxy interfaces, use the default package.
proxyPkg = "";
}
{
//获得所有接口中的方法
List<Method> methods = getMethods(interfaces);
//进行排序
Collections.sort(methods, ORDER_BY_SIGNATURE_AND_SUBTYPE);
validateReturnTypes(methods);
List<Class<?>[]> exceptions = deduplicateAndGetExceptions(methods);
//转换成数组
Method[] methodsArray = methods.toArray(new Method[methods.size()]);
Class<?>[][] exceptionsArray = exceptions.toArray(new Class<?>[exceptions.size()][]);
long num = nextUniqueNumber.getAndIncrement();
//代理类名=包名+$Proxy
String proxyName = proxyPkg + proxyClassNamePrefix + num;
return generateProxy(proxyName, interfaces, loader, methodsArray,
exceptionsArray);
}
}
}
动态代理,解析interface所有方法,新建一个class,class的名 包名+$Proxy,
实例化了proxy对象,proxy的里面包含InvocationHandler,
每次调方法其实执行的是InvocationHandler里面的invoke