package com.lody.virtual.client.ipc; import android.os.DeadObjectException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * @author Lody */ public class LocalProxyUtils { /** * Generates the Proxy instance for a base object, each IPC call will clean its calling identity. * @param interfaceClass interface class * @param base base object * @param handler retry to get the remote object when server dead. * @return proxy object */ public static <T> T genProxy(Class<T> interfaceClass, final Object base, final DeadServerHandler handler) { //noinspection unchecked return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[]{ interfaceClass }, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { return method.invoke(base, args); } catch (Throwable e) { if (e.getCause() instanceof DeadObjectException) { ServiceManagerNative.clearServerFetcher(); if (handler != null) { Object newBase = handler.getNewRemoteInterface(); if (newBase != null) { try { return method.invoke(newBase, args); } catch (Throwable retry_e) { throw retry_e.getCause(); } } throw e.getCause(); } } throw e.getCause() == null ? e : e.getCause(); } } }); } public interface DeadServerHandler { Object getNewRemoteInterface(); } }