为其余对象提供一种代理以控制对这个对象的访问bash
主要做用:控制对象访问网络
编译时期就已经存在,通常首先须要定义接口,而被代理的对象和代理对象一块儿实现相同的接口。ide
public interface Play {
//唱歌
void sing(int count);
//演出
void show();
}
复制代码
public class Actor implements Play {
@Override
public void sing(int count) {
System.out.print("唱了" + count + "首歌");
}
@Override
public void show() {
System.out.print("进行演出");
}
}
复制代码
被代理对象提供了几个具体方法实现post
public class Agent implements Play {
//被代理对象
private Play player;
private long money;
public void setMoney(long money){
this.money = money;
}
/**
* @param player
* @param money 收费
*/
public Agent(Play player, long money) {
this.player = player;
this.money = money;
}
@Override
public void sing(int count) {
player.sing(count);
}
//控制了被代理对象的访问
@Override
public void show() {
if (money > 100) {
player.show();
} else {
System.out.println("baibai...");
}
}
}
复制代码
public class PlayTest {
public static void main(String[] args){
Actor actor = new Actor();
Agent agent = new Agent(actor, 50);
agent.sing(2);
agent.show();
agent.setMoney(200);
agent.show();
}
}
复制代码
代理对象经过自身的逻辑处理对目标对象的功能进行控制。ui
动态通常指的是在运行时的状态,是相对编译时的静态来区分,就是在运行时生成一个代理对象帮咱们作一些逻辑处理。主要使用反射技术得到类的加载器而且建立实例。
动态代理能够在运行时动态建立一个类,实现一个或多个接口,能够在不修改原有类的基础上动态为经过该类获取的对象添加方法、修改行为。this
InvocationHandler是动态代理接口,动态代理类须要实现该接口,并在invoke方法中对代理类的方法进行处理spa
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
复制代码
参数说明:插件
Proxy类能够经过newProxyInstance建立一个代理对象代理
#Proxy
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException {
if (h == null) {
throw new NullPointerException();
}
Class<?> cl = getProxyClass0(loader, interfaces);
try {
//经过反射完成了代理对象的建立
final Constructor<?> cons = cl.getConstructor(constructorParams);
return newInstance(cons, h);
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString());
}
}
复制代码
参数说明:code
(1)定义动态代理类
public class ActorProxy implements InvocationHandler {
private Play player;
public ActorProxy(Play player){
this.player = player;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//处理被代理对象的方法实现
if ("show".equals(method.getName())){
System.out.println("代理处理show....");
return method.invoke(player, null);
}else if ("sing".equals(method.getName())){
System.out.println("代理处理sing....");
return method.invoke(player, 2);
}
return null;
}
}
复制代码
代理类实现InvocationHandler接口,在invoke方法中对player(被代理对象)作相应的逻辑处理。
(2)使用
public class ProxyTest {
public static void main(String[] args) {
Play actor = new Actor();
//经过调用Proxy.newProxyInstance方法生成代理对象
Play proxy = (Play) Proxy.newProxyInstance(actor.getClass().getClassLoader()
, actor.getClass().getInterfaces(), new ActorProxy(actor));
//调用代理类相关方法
proxy.show();
proxy.sing(3);
}
}
复制代码
(1)Retrofit使用:
定义接口
public interface MyService {
@GET("users/{user}/list")
Call<String> getMyList(@Path("user") String user);
}
复制代码
新建retrofit对象,而后产生一个接口对象,而后调用具体方法去完成请求。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://xxx.com")
.build();
MyService myService = retrofit.create(MyService.class);
Call<String> myList = myService.getMyList("my");
复制代码
retrofit.create方法就是经过动态代理的方式传入一个接口,返回了一个对象
(2)动态代理分析:
public <T> T create(final Class<T> service) {
//判断是否为接口
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
//建立请求接口的动态代理对象
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//将接口中方法传入返回了ServiceMethod
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
复制代码
经过Proxy.newProxyInstance,该动态代理对象能够拿到请求接口实例上全部注解,而后经过代理对象进行网络请求。
远程代理:为某个对象在不一样的内存地址空间提供局部的代理对象
(1)AMS、ApplicationThread
(2)Binder模型
在插件化中,例如VirtualApk,hook住AMS的本地代理对象IActivityManager,至关于IActivityManager的一个代理,控制了IActivityManager的某些行为
(1)建立动态代理
protected void hookSystemServices() {
try {
Singleton<IActivityManager> defaultSingleton;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
defaultSingleton = Reflector.on(ActivityManager.class).field("IActivityManagerSingleton").get();
} else {
defaultSingleton = Reflector.on(ActivityManagerNative.class).field("gDefault").get();
}
IActivityManager origin = defaultSingleton.get();
//建立动态代理对象ActivityManagerProxy
IActivityManager activityManagerProxy = (IActivityManager) Proxy.newProxyInstance(mContext.getClassLoader(), new Class[] { IActivityManager.class },
createActivityManagerProxy(origin));
// 经过反射Hook住了IActivityManager
Reflector.with(defaultSingleton).field("mInstance").set(activityManagerProxy);
if (defaultSingleton.get() == activityManagerProxy) {
this.mActivityManager = activityManagerProxy;
Log.d(TAG, "hookSystemServices succeed : " + mActivityManager);
}
} catch (Exception e) {
Log.w(TAG, e);
}
}
protected ActivityManagerProxy createActivityManagerProxy(IActivityManager origin) throws Exception {
return new ActivityManagerProxy(this, origin);
}
复制代码
建立动态代理ActivityManagerProxy,并经过反射对IActivityManager进行hook
(2)动态代理对象
public class ActivityManagerProxy implements InvocationHandler {
......
//被代理对象
private IActivityManager mActivityManager;
public ActivityManagerProxy(PluginManager pluginManager, IActivityManager activityManager) {
this.mPluginManager = pluginManager;
this.mActivityManager = activityManager;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//经过监听被代理对象的某些方法,执行本身的相关逻辑
if ("startService".equals(method.getName())) {
try {
return startService(proxy, method, args);
} catch (Throwable e) {
Log.e(TAG, "Start service error", e);
}
}
......
}
}
复制代码
ActivityManagerProxy实现InvocationHandler,并持有了IActivityManager,在IActivityManager方法执行时,进行控制并执行本身的相应逻辑