您的位置:首页 > 移动开发 > Android开发

360 Android 插件开发 DroidPlugin 代码分析 -随笔

2015-09-29 14:09 801 查看
备注:本文是个人的随笔,之后如果有时间,会书写比较正式的分析博客60的插件DroidPlugin引用的工程DroidPlugin中在资源清单文件中几乎申请了所有的权限在demo中配置插件的启动PluginHelper.getInstance().applicationOnCreate(getBaseContext());是核心操作,进行了初始化的一系列的工作PluginHelper.getInstance().applicationAttachBaseContext(base);并没有做什么操作,只是注册了crash之后的log发送之类的信息分析PluginHelper.getInstance().applicationOnCreate(getBaseContext());
publicvoidapplicationOnCreate(finalContextbaseContext){
initPlugin(baseContext);
}
[/code]1.安装钩子函数相关2.判断是否允许钩子函数的运行3.注册插件service的监听4.启动插件service
privatevoidinitPlugin(ContextbaseContext){
longb=System.currentTimeMillis();
try{
try{
fixMiUiLbeSecurity();
}catch(Throwablee){
Log.e(TAG,"fixMiUiLbeSecurityhaserror",e);
}
try{
PluginProcessManager.installHook(baseContext);
}catch(Throwablee){
Log.e(TAG,"installHookhaserror",e);
}
try{
if(PluginProcessManager.isPluginProcess(baseContext)){
PluginProcessManager.setHookEnable(true);
}else{
PluginProcessManager.setHookEnable(false);
}
}catch(Throwablee){
Log.e(TAG,"setHookEnablehaserror",e);
}
try{
PluginManager.getInstance().addServiceConnection(PluginHelper.this);
PluginManager.getInstance().init(baseContext);
}catch(Throwablee){
Log.e(TAG,"installHookhaserror",e);
}
}finally{
Log.i(TAG,"Initplugininprocesscost%sms",(System.currentTimeMillis()-b));
}
}
[/code]PluginProcessManager.installHook(baseContext);
publicstaticvoidinstallHook(ContexthostContext)throwsThrowable{
HookFactory.getInstance().installHook(hostContext,null);
}
[/code]
publicfinalvoidinstallHook(Contextcontext,ClassLoaderclassLoader)throwsThrowable{
installHook(newIClipboardBinderHook(context),classLoader);
//forISearchManager
installHook(newISearchManagerBinderHook(context),classLoader);
//forINotificationManager
installHook(newINotificationManagerBinderHook(context),classLoader);
installHook(newIMountServiceBinder(context),classLoader);
installHook(newIAudioServiceBinderHook(context),classLoader);
installHook(newIContentServiceBinderHook(context),classLoader);
installHook(newIWindowManagerBinderHook(context),classLoader);
if(VERSION.SDK_INT>=VERSION_CODES.LOLLIPOP_MR1){
installHook(newIGraphicsStatsBinderHook(context),classLoader);
}
if(VERSION.SDK_INT>=VERSION_CODES.KITKAT){
installHook(newIMediaRouterServiceBinderHook(context),classLoader);
}
if(VERSION.SDK_INT>=VERSION_CODES.LOLLIPOP){
installHook(newISessionManagerBinderHook(context),classLoader);
}
if(VERSION.SDK_INT>=VERSION_CODES.JELLY_BEAN_MR2){
installHook(newIWifiManagerBinderHook(context),classLoader);
}
if(VERSION.SDK_INT>=VERSION_CODES.JELLY_BEAN_MR2){
installHook(newIInputMethodManagerBinderHook(context),classLoader);
}
installHook(newIPackageManagerHook(context),classLoader);
installHook(newIActivityManagerHook(context),classLoader);//以此为案例,做分析
installHook(newPluginCallbackHook(context),classLoader);
installHook(newInstrumentationHook(context),classLoader);
installHook(newLibCoreHook(context),classLoader);
installHook(newSQLiteDatabaseHook(context),classLoader);
}
[/code]
publicvoidinstallHook(Hookhook,ClassLoadercl){
try{
hook.onInstall(cl);
synchronized(mHookList){
mHookList.add(hook);
}
}catch(Throwablethrowable){
Log.e(TAG,"installHook%serror",throwable,hook);
}
}
[/code]以IActivityManagerHook为例,在初始化之后,调用了onInstall的方法,先记录到此处现在查看Hook的体系结构Hook--|ProxyHook--|IActivityManagerHookHook基类,1.设置是否可以enablehook2.在构造时,需要创建hook的处理类3.install和uninstallhook
publicabstractclassHook{
privatebooleanmEnable=false;
protectedContextmHostContext;
protectedBaseHookHandlemHookHandles;
publicvoidsetEnable(booleanenable,booleanreInstallHook){
this.mEnable=enable;
}
publicfinalvoidsetEnable(booleanenable){
setEnable(enable,false);
}
publicbooleanisEnable(){
returnmEnable;
}
protectedHook(ContexthostContext){
mHostContext=hostContext;
mHookHandles=createHookHandle();
}
protectedabstractBaseHookHandlecreateHookHandle();
protectedabstractvoidonInstall(ClassLoaderclassLoader)throwsThrowable;
protectedvoidonUnInstall(ClassLoaderclassLoader)throwsThrowable{
}
}
[/code]下面查看ProxyHook因为是代理,1.提供了一个setOldobj的方法,用户缓存OldObj2.实现了Java体系中默认的动态代理方式3.如果当前的handle不为空,并且是enabled的情况下,那么交给HookedMethodHandle.doHookInner()方法来处理
publicabstractclassProxyHookextendsHookimplementsInvocationHandler{
protectedObjectmOldObj;
publicProxyHook(ContexthostContext){
super(hostContext);
}
publicvoidsetOldObj(ObjectoldObj){
this.mOldObj=oldObj;
}
publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{
try{
if(!isEnable()){
returnmethod.invoke(mOldObj,args);
}
HookedMethodHandlerhookedMethodHandler=mHookHandles.getHookedMethodHandler(method);
if(hookedMethodHandler!=null){
returnhookedMethodHandler.doHookInner(mOldObj,method,args);
}
returnmethod.invoke(mOldObj,args);
}catch(InvocationTargetExceptione){
Throwablecause=e.getTargetException();
if(cause!=null&&MyProxy.isMethodDeclaredThrowable(method,cause)){
throwcause;
}elseif(cause!=null){
RuntimeExceptionruntimeException=!TextUtils.isEmpty(cause.getMessage())?newRuntimeException(cause.getMessage()):newRuntimeException();
runtimeException.initCause(cause);
throwruntimeException;
}else{
RuntimeExceptionruntimeException=!TextUtils.isEmpty(e.getMessage())?newRuntimeException(e.getMessage()):newRuntimeException();
runtimeException.initCause(e);
throwruntimeException;
}
}catch(Throwablee){
if(MyProxy.isMethodDeclaredThrowable(method,e)){
throwe;
}else{
RuntimeExceptionruntimeException=!TextUtils.isEmpty(e.getMessage())?newRuntimeException(e.getMessage()):newRuntimeException();
runtimeException.initCause(e);
throwruntimeException;
}
}
}
}
[/code]插曲: HookedMethodHandle的内容核心内容: doHookInner实现代理的逻辑{1.先执行beforeInvoke方法,如果返回true,那么便拦截掉了这个事件2.如果beforeInvoke返回false,那么继续处理这个事件3.调用afterInvoke的方法}
publicclassHookedMethodHandler{
privatestaticfinalStringTAG=HookedMethodHandler.class.getSimpleName();
protectedfinalContextmHostContext;
privateObjectmFakedResult=null;
privatebooleanmUseFakedResult=false;
publicHookedMethodHandler(ContexthostContext){
this.mHostContext=hostContext;
}
publicsynchronizedObjectdoHookInner(Objectreceiver,Methodmethod,Object[]args)throwsThrowable{
longb=System.currentTimeMillis();
try{
mUseFakedResult=false;
mFakedResult=null;
booleansuc=beforeInvoke(receiver,method,args);
ObjectinvokeResult=null;
if(!suc){
invokeResult=method.invoke(receiver,args);
}
afterInvoke(receiver,method,args,invokeResult);
if(mUseFakedResult){
returnmFakedResult;
}else{
returninvokeResult;
}
}finally{
longtime=System.currentTimeMillis()-b;
if(time>5){
Log.i(TAG,"doHookInnermethod(%s.%s)cost%sms",method.getDeclaringClass().getName(),method.getName(),time);
}
}
}
publicvoidsetFakedResult(ObjectfakedResult){
this.mFakedResult=fakedResult;
mUseFakedResult=true;
}
/**
*在某个方法被调用之前执行,如果返回true,则不执行原始的方法,否则执行原始方法
*/
protectedbooleanbeforeInvoke(Objectreceiver,Methodmethod,Object[]args)throwsThrowable{
returnfalse;
}
protectedvoidafterInvoke(Objectreceiver,Methodmethod,Object[]args,ObjectinvokeResult)throwsThrowable{
}
publicbooleanisFakedResult(){
returnmUseFakedResult;
}
publicObjectgetFakedResult(){
returnmFakedResult;
}
}
[/code]插曲结束继续分析Hook的结构:IActivityManagerHook1. 在createHookHandle()的时候,新创建了一个IActivityManagerHookHandle2.onInstall为安装此Hook的调用方法
publicclassIActivityManagerHookextendsProxyHook{
privatestaticfinalStringTAG=IActivityManagerHook.class.getSimpleName();
publicIActivityManagerHook(ContexthostContext){
super(hostContext);
}
@Override
publicBaseHookHandlecreateHookHandle(){
returnnewIActivityManagerHookHandle(mHostContext);
}
@Override
publicvoidonInstall(ClassLoaderclassLoader)throwsThrowable{
//TODO------解析来分析-------
}
}
[/code]IActivityManagerHook-->onInstall方法分析1.找到系统的IActivityManager2.接下来判断此IActivityManager是否是单例,根据是否是单例,做不同的代理的处理但是这个对于我们想要看的逻辑没有大的影响,我们按照简单的看(个人查看android2.3的源码时(在线查看地址: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.7_r1/android/app/ActivityManagerNative.java),发现是单例,我们不按照单例的看,为什么,是因为简单,便于理解!)
@Override
publicvoidonInstall(ClassLoaderclassLoader)throwsThrowable{
Classcls=ActivityManagerNativeCompat.Class();
Objectobj=FieldUtils.readStaticField(cls,"gDefault");
if(obj==null){
ActivityManagerNativeCompat.getDefault();
obj=FieldUtils.readStaticField(cls,"gDefault");
}
if(IActivityManagerCompat.isIActivityManager(obj)){
setOldObj(obj);
Class<?>objClass=mOldObj.getClass();
List<Class<?>>interfaces=Utils.getAllInterfaces(objClass);
Class[]ifs=interfaces!=null&&interfaces.size()>0?interfaces.toArray(newClass[interfaces.size()]):newClass[0];
ObjectproxiedActivityManager=MyProxy.newProxyInstance(objClass.getClassLoader(),ifs,this);
FieldUtils.writeStaticField(cls,"gDefault",proxiedActivityManager);
Log.i(TAG,"InstallActivityManagerHook1old=%s,new=%s",mOldObj,proxiedActivityManager);
}elseif(SingletonCompat.isSingleton(obj)){
Objectobj1=FieldUtils.readField(obj,"mInstance");
if(obj1==null){
SingletonCompat.get(obj);
obj1=FieldUtils.readField(obj,"mInstance");
}
setOldObj(obj1);
List<Class<?>>interfaces=Utils.getAllInterfaces(mOldObj.getClass());
Class[]ifs=interfaces!=null&&interfaces.size()>0?interfaces.toArray(newClass[interfaces.size()]):newClass[0];
finalObjectobject=MyProxy.newProxyInstance(mOldObj.getClass().getClassLoader(),ifs,IActivityManagerHook.this);
Objectiam1=ActivityManagerNativeCompat.getDefault();
//这里先写一次,防止后面找不到Singleton类导致的挂钩子失败的问题。
FieldUtils.writeField(obj,"mInstance",object);
//这里使用方式1,如果成功的话,会导致上面的写操作被覆盖。
FieldUtils.writeStaticField(cls,"gDefault",newandroid.util.Singleton<Object>(){
@Override
protectedObjectcreate(){
Log.e(TAG,"InstallActivityManager3Hookold=%s,new=%s",mOldObj,object);
returnobject;
}
});
Log.i(TAG,"InstallActivityManagerHook2old=%s,new=%s",mOldObj.toString(),object);
Objectiam2=ActivityManagerNativeCompat.getDefault();
//方式2
if(iam1==iam2){
//这段代码是废的,没啥用,写这里只是不想改而已。
FieldUtils.writeField(obj,"mInstance",object);
}
}else{
thrownewAndroidRuntimeException("CannotinstallIActivityManagerNativehook");
}
}
[/code]这里采用了java的动态代理,用的activityManager是我们经过代理的activityManager非静态代理的源码:
setOldObj(obj);
Class<?>objClass=mOldObj.getClass();
List<Class<?>>interfaces=Utils.getAllInterfaces(objClass);
Class[]ifs=interfaces!=null&&interfaces.size()>0?interfaces.toArray(newClass[interfaces.size()]):newClass[0];
ObjectproxiedActivityManager=MyProxy.newProxyInstance(objClass.getClassLoader(),ifs,this);
FieldUtils.writeStaticField(cls,"gDefault",proxiedActivityManager);
Log.i(TAG,"InstallActivityManagerHook1old=%s,new=%s",mOldObj,proxiedActivityManager);
[/code]既然是经过代理的,那么代理部分肯定是部分经过我们处理的,那么这部分逻辑就是关键了,看到代理的回调部分是交给IActivityManagerHook处理的,其实就是基类ProxyHook来处理的刚才已经分析,就是invoke的插曲部分那么现在需要关心的就是HookedMethodHandler的实现逻辑了但是在HookedMethodHandler中,我们只是看到了逻辑框架部分,具体的处理逻辑需要在子类中查看,那么对应IActivityManagerHook的Handler是那个呢?在IActivityManagerHook的createHookHandle()的方法中,我们已经看到使用的是IActivityManagerHookHandle,那么现在我们需要关系新的就是IActivityManagerHookHandle中做了怎么样的逻辑处理,但是在这之前,我们先看看IActivityManagerHookHandle的构造部分代码看起来很长的样子,其实就是sHookedMethodHandlers中存放了当前需要关联的函数名字和对应的处理内容
publicIActivityManagerHookHandle(ContexthostContext){
super(hostContext);
}
@Override
protectedvoidinit(){
sHookedMethodHandlers.put("startActivity",newstartActivity(mHostContext));
sHookedMethodHandlers.put("startActivityAsUser",newstartActivityAsUser(mHostContext));
sHookedMethodHandlers.put("startActivityAsCaller",newstartActivityAsCaller(mHostContext));
sHookedMethodHandlers.put("startActivityAndWait",newstartActivityAndWait(mHostContext));
sHookedMethodHandlers.put("startActivityWithConfig",newstartActivityWithConfig(mHostContext));
sHookedMethodHandlers.put("startActivityIntentSender",newstartActivityIntentSender(mHostContext));
sHookedMethodHandlers.put("startVoiceActivity",newstartVoiceActivity(mHostContext));
sHookedMethodHandlers.put("startNextMatchingActivity",newstartNextMatchingActivity(mHostContext));
sHookedMethodHandlers.put("startActivityFromRecents",newstartActivityFromRecents(mHostContext));
sHookedMethodHandlers.put("finishActivity",newfinishActivity(mHostContext));
sHookedMethodHandlers.put("registerReceiver",newregisterReceiver(mHostContext));
sHookedMethodHandlers.put("broadcastIntent",newbroadcastIntent(mHostContext));
sHookedMethodHandlers.put("unbroadcastIntent",newunbroadcastIntent(mHostContext));
sHookedMethodHandlers.put("getCallingPackage",newgetCallingPackage(mHostContext));
sHookedMethodHandlers.put("getCallingActivity",newgetCallingActivity(mHostContext));
sHookedMethodHandlers.put("getAppTasks",newgetAppTasks(mHostContext));
sHookedMethodHandlers.put("addAppTask",newaddAppTask(mHostContext));
sHookedMethodHandlers.put("getTasks",newgetTasks(mHostContext));
sHookedMethodHandlers.put("getServices",newgetServices(mHostContext));
sHookedMethodHandlers.put("getProcessesInErrorState",newgetProcessesInErrorState(mHostContext));
sHookedMethodHandlers.put("getContentProvider",newgetContentProvider(mHostContext));
sHookedMethodHandlers.put("getContentProviderExternal",newgetContentProviderExternal(mHostContext));
sHookedMethodHandlers.put("removeContentProviderExternal",newremoveContentProviderExternal(mHostContext));
sHookedMethodHandlers.put("publishContentProviders",newpublishContentProviders(mHostContext));
sHookedMethodHandlers.put("getRunningServiceControlPanel",newgetRunningServiceControlPanel(mHostContext));
sHookedMethodHandlers.put("startService",newstartService(mHostContext));
sHookedMethodHandlers.put("stopService",newstopService(mHostContext));
sHookedMethodHandlers.put("stopServiceToken",newstopServiceToken(mHostContext));
sHookedMethodHandlers.put("setServiceForeground",newsetServiceForeground(mHostContext));
sHookedMethodHandlers.put("bindService",newbindService(mHostContext));
sHookedMethodHandlers.put("publishService",newpublishService(mHostContext));
sHookedMethodHandlers.put("unbindFinished",newunbindFinished(mHostContext));
sHookedMethodHandlers.put("peekService",newpeekService(mHostContext));
sHookedMethodHandlers.put("bindBackupAgent",newbindBackupAgent(mHostContext));
sHookedMethodHandlers.put("backupAgentCreated",newbackupAgentCreated(mHostContext));
sHookedMethodHandlers.put("unbindBackupAgent",newunbindBackupAgent(mHostContext));
sHookedMethodHandlers.put("killApplicationProcess",newkillApplicationProcess(mHostContext));
sHookedMethodHandlers.put("startInstrumentation",newstartInstrumentation(mHostContext));
sHookedMethodHandlers.put("getActivityClassForToken",newgetActivityClassForToken(mHostContext));
sHookedMethodHandlers.put("getPackageForToken",newgetPackageForToken(mHostContext));
sHookedMethodHandlers.put("getIntentSender",newgetIntentSender(mHostContext));
sHookedMethodHandlers.put("clearApplicationUserData",newclearApplicationUserData(mHostContext));
sHookedMethodHandlers.put("handleIncomingUser",newhandleIncomingUser(mHostContext));
sHookedMethodHandlers.put("grantUriPermission",newgrantUriPermission(mHostContext));
sHookedMethodHandlers.put("getPersistedUriPermissions",newgetPersistedUriPermissions(mHostContext));
sHookedMethodHandlers.put("killBackgroundProcesses",newkillBackgroundProcesses(mHostContext));
sHookedMethodHandlers.put("forceStopPackage",newforceStopPackage(mHostContext));
sHookedMethodHandlers.put("getRunningAppProcesses",newgetRunningAppProcesses(mHostContext));
sHookedMethodHandlers.put("getRunningExternalApplications",newgetRunningExternalApplications(mHostContext));
sHookedMethodHandlers.put("getMyMemoryState",newgetMyMemoryState(mHostContext));
sHookedMethodHandlers.put("crashApplication",newcrashApplication(mHostContext));
sHookedMethodHandlers.put("grantUriPermissionFromOwner",newgrantUriPermissionFromOwner(mHostContext));
sHookedMethodHandlers.put("checkGrantUriPermission",newcheckGrantUriPermission(mHostContext));
sHookedMethodHandlers.put("startActivities",newstartActivities(mHostContext));
sHookedMethodHandlers.put("getPackageScreenCompatMode",newgetPackageScreenCompatMode(mHostContext));
sHookedMethodHandlers.put("setPackageScreenCompatMode",newsetPackageScreenCompatMode(mHostContext));
sHookedMethodHandlers.put("getPackageAskScreenCompat",newgetPackageAskScreenCompat(mHostContext));
sHookedMethodHandlers.put("setPackageAskScreenCompat",newsetPackageAskScreenCompat(mHostContext));
sHookedMethodHandlers.put("navigateUpTo",newnavigateUpTo(mHostContext));
sHookedMethodHandlers.put("serviceDoneExecuting",newserviceDoneExecuting(mHostContext));
}
[/code]这样在ProxyHook的invoke的方法中,便可以获取到对应的方法需要处理的HookedMethodHandler,假如此方法需要处理,那么便调用此方法的doHookInner方法即可
publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{
try{
if(!isEnable()){
returnmethod.invoke(mOldObj,args);
}
HookedMethodHandlerhookedMethodHandler=mHookHandles.getHookedMethodHandler(method);
if(hookedMethodHandler!=null){
returnhookedMethodHandler.doHookInner(mOldObj,method,args);
}
returnmethod.invoke(mOldObj,args);
}catch(InvocationTargetExceptione){
Throwablecause=e.getTargetException();
if(cause!=null&&MyProxy.isMethodDeclaredThrowable(method,cause)){
throwcause;
}elseif(cause!=null){
RuntimeExceptionruntimeException=!TextUtils.isEmpty(cause.getMessage())?newRuntimeException(cause.getMessage()):newRuntimeException();
runtimeException.initCause(cause);
throwruntimeException;
}else{
RuntimeExceptionruntimeException=!TextUtils.isEmpty(e.getMessage())?newRuntimeException(e.getMessage()):newRuntimeException();
runtimeException.initCause(e);
throwruntimeException;
}
}catch(Throwablee){
if(MyProxy.isMethodDeclaredThrowable(method,e)){
throwe;
}else{
RuntimeExceptionruntimeException=!TextUtils.isEmpty(e.getMessage())?newRuntimeException(e.getMessage()):newRuntimeException();
runtimeException.initCause(e);
throwruntimeException;
}
}
}
[/code]以startActivity为例,代码如下:关于HookedMethodHandler的处理逻辑我们已经介绍,下面,只需要关心子类的beforeInvoke方法和afterInvoke方法即可发现startActivity类,只是做了beforeInvoke的逻辑,并且没有返回true,因而,还是会调用系统的startActivity方法,但是为什么就可以打开作为插件打开呢?这就是beforeInvoke的逻辑了
privatestaticclassstartActivityextendsHookedMethodHandler{
publicstartActivity(ContexthostContext){
super(hostContext);
}
protectedvoiddoReplaceIntentForStartActivityAPIHigh(Object[]args)throwsRemoteException{
intintentOfArgIndex=findFirstIntentIndexInArgs(args);
if(args!=null&&args.length>1&&intentOfArgIndex>=0){
Intentintent=(Intent)args[intentOfArgIndex];
//XXXStringcallingPackage=(String)args[1];
ActivityInfoactivityInfo=resolveActivity(intent);
if(activityInfo!=null&&isPackagePlugin(activityInfo.packageName)){
ComponentNamecomponent=selectProxyActivity(intent);
if(component!=null){
IntentnewIntent=newIntent();
try{
ClassLoaderpluginClassLoader=PluginProcessManager.getPluginClassLoader(component.getPackageName());
setIntentClassLoader(newIntent,pluginClassLoader);
}catch(IllegalAccessExceptione){
e.printStackTrace();
}catch(NoSuchMethodExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}catch(InvocationTargetExceptione){
e.printStackTrace();
}
newIntent.setComponent(component);
newIntent.putExtra(Env.EXTRA_TARGET_INTENT,intent);
StringcallingPackage=(String)args[1];
if(TextUtils.equals(mHostContext.getPackageName(),callingPackage)){
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
args[intentOfArgIndex]=newIntent;
args[1]=mHostContext.getPackageName();
}else{
Log.w(TAG,"startActivity,replaceselectProxyActivityfail");
}
}
}
}
privatevoidsetIntentClassLoader(Intentintent,ClassLoaderclassLoader){
try{
BundlemExtras=(Bundle)FieldUtils.readField(intent,"mExtras");
if(mExtras!=null){
mExtras.setClassLoader(classLoader);
}else{
Bundlevalue=newBundle();
value.setClassLoader(classLoader);
FieldUtils.writeField(intent,"mExtras",value);
}
}catch(Exceptione){
}finally{
intent.setExtrasClassLoader(classLoader);
}
}
protectedvoiddoReplaceIntentForStartActivityAPILow(Object[]args)throwsRemoteException{
intintentOfArgIndex=findFirstIntentIndexInArgs(args);
if(args!=null&&args.length>1&&intentOfArgIndex>=0){
Intentintent=(Intent)args[intentOfArgIndex];
ActivityInfoactivityInfo=resolveActivity(intent);
if(activityInfo!=null&&isPackagePlugin(activityInfo.packageName)){
ComponentNamecomponent=selectProxyActivity(intent);
if(component!=null){
IntentnewIntent=newIntent();
newIntent.setComponent(component);
newIntent.putExtra(Env.EXTRA_TARGET_INTENT,intent);
if(TextUtils.equals(mHostContext.getPackageName(),activityInfo.packageName)){
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
args[intentOfArgIndex]=newIntent;
}else{
Log.w(TAG,"startActivity,replaceselectProxyActivityfail");
}
}
}
}
@Override
protectedbooleanbeforeInvoke(Objectreceiver,Methodmethod,Object[]args)throwsThrowable{
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.JELLY_BEAN_MR2){
doReplaceIntentForStartActivityAPILow(args);
}else{
doReplaceIntentForStartActivityAPIHigh(args);
}
returnsuper.beforeInvoke(receiver,method,args);
}
}
[/code]看到:版本18以前和以后的处理方式是不同的,我们以版本低的为例处理的步骤:1.找到反射中的intent2.根据intent解析为activityInfo3.判断是否需要插件来打开,如果不是,不需要处理4.如果是,找到对应的代理的acitivity5.替换反射中的intent
protectedvoiddoReplaceIntentForStartActivityAPILow(Object[]args)throwsRemoteException{
intintentOfArgIndex=findFirstIntentIndexInArgs(args);
if(args!=null&&args.length>1&&intentOfArgIndex>=0){
Intentintent=(Intent)args[intentOfArgIndex];
ActivityInfoactivityInfo=resolveActivity(intent);
if(activityInfo!=null&&isPackagePlugin(activityInfo.packageName)){
ComponentNamecomponent=selectProxyActivity(intent);
if(component!=null){
IntentnewIntent=newIntent();
newIntent.setComponent(component);
newIntent.putExtra(Env.EXTRA_TARGET_INTENT,intent);
if(TextUtils.equals(mHostContext.getPackageName(),activityInfo.packageName)){
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
args[intentOfArgIndex]=newIntent;
}else{
Log.w(TAG,"startActivity,replaceselectProxyActivityfail");
}
}
}
}
[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: