package com.tws.plugin.servicemanager; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import android.annotation.TargetApi; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import com.tws.plugin.servicemanager.compat.BundleCompat; import com.tws.plugin.servicemanager.compat.ContentProviderCompat; import com.tws.plugin.servicemanager.util.ParamUtil; /** * @author yongchen */ public class RemoteProxy { public static Object getProxyService(final String name, String iFaceClassName, ClassLoader classloader) { try { //classloader Class clientClass = classloader.loadClass(iFaceClassName); return Proxy.newProxyInstance(classloader, new Class[]{clientClass}, new InvocationHandler() { Boolean isInProviderProcess; String desciptpr; IBinder iBinder; @TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Bundle argsBundle = ParamUtil.wrapperParams(name, method.toGenericString(), args); if (isInProviderProcess == null) { prepare(argsBundle); } if (Boolean.TRUE.equals(isInProviderProcess)) { return MethodRouter.routerToProvider(name, argsBundle); } else if (desciptpr != null && iBinder != null) { return MethodRouter.routerToBinder(desciptpr, iBinder, argsBundle); } else { //服务所在进程已死,重启服务进程可自动恢复 Log.w("RemoteProxy", "not active,service May Died!"); } if (!method.getReturnType().isPrimitive()) { //是包装类,返回null return null; } else { //不是包装类,默认返回值没法给,throws RemoteExecption throw new IllegalStateException("Service not active! Remote process may died"); } } private void prepare(Bundle argsBundle) throws Throwable { Bundle queryResult = ContentProviderCompat.call(ServiceProvider.buildUri(), ServiceProvider.QUERY_SERVICE, name, argsBundle); if (queryResult != null) { isInProviderProcess = queryResult.getBoolean(ServiceProvider.QUERY_SERVICE_RESULT_IS_IN_PROVIDIDER_PROCESS, false); iBinder = BundleCompat.getBinder(queryResult, ServiceProvider.QUERY_SERVICE_RESULT_BINDER); desciptpr = queryResult.getString(ServiceProvider.QUERY_SERVICE_RESULT_DESCRIPTOR); if (iBinder != null) { iBinder.linkToDeath(new IBinder.DeathRecipient() { @Override public void binderDied() { isInProviderProcess = null; iBinder = null; desciptpr = null; } }, 0); } } } }); } catch (Exception e) { e.printStackTrace(); } return null; } }