Android插件化之startActivity hook实现登录拦截

Android 26及以上:startActivity -> startActivityForResult -> mInstrumentation.execStartActivity -> ActivityManagerNative.getDefault().startActivity
Android 26以下:startActivity -> startActivityForResult -> mInstrumentation.execStartActivity -> ActivityManager.getService().startActivity

startActivity hook

public class AuthHookHelper {
    private static AuthHookHelper mAuthHookHelper;
    private Context context;

    private AuthHookHelper(Context context) {
        this.context = context;
    }

    public static AuthHookHelper getInstance(Context context) {
        if (mAuthHookHelper == null) {
            synchronized (AuthHookHelper.class) {
                if (mAuthHookHelper == null) {
                    mAuthHookHelper = new AuthHookHelper(context.getApplicationContext());
                }
            }
        }
        return mAuthHookHelper;
    }

    public void hookAms() {
        try {
            Class<?> activityManagerClass;
            Field iActivityManagerSingleton;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                activityManagerClass = Class.forName("android.app.ActivityManager");
                iActivityManagerSingleton = activityManagerClass.getDeclaredField("IActivityManagerSingleton");
            } else {
                activityManagerClass = Class.forName("android.app.ActivityManagerNative");
                iActivityManagerSingleton = activityManagerClass.getDeclaredField("gDefault");
            }
            iActivityManagerSingleton.setAccessible(true);
            Object defaultValue = iActivityManagerSingleton.get(null);

            Class<?> singletonClass = Class.forName("android.util.Singleton");
            Field mInstance = singletonClass.getDeclaredField("mInstance");
            mInstance.setAccessible(true);
            Object iActivityManagerObject = mInstance.get(defaultValue);

            Class<?> IActivityManager = Class.forName("android.app.IActivityManager");
            Object proxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                    new Class[] {IActivityManager},
                    new AmsInvocationHandler(iActivityManagerObject));
            mInstance.set(defaultValue, proxy);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    class AmsInvocationHandler implements InvocationHandler {
        private Object iActivityManagerObject;

        public AmsInvocationHandler(Object iActivityManagerObject) {
            this.iActivityManagerObject = iActivityManagerObject;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
            if ("startActivity".contains(method.getName())) {
                Log.i("yezhou", "invoke: startActivity");
                Intent intent = null;
                int index = 0;
                for (int i = 0; i < args.length; i++) {
                    Object arg = args[i];
                    if (arg instanceof Intent) {
                        intent = (Intent) args[i];
                        index = i;
                        break;
                    }
                }
                if (!Constants.inLogin) {
                    Intent proxyIntent = new Intent();
                    ComponentName componentName = new ComponentName(context, LoginActivity.class);
                    proxyIntent.setComponent(componentName);
                    proxyIntent.putExtra("extraIntent", intent.getComponent().getClassName());
                    args[index] = proxyIntent;
                }
            }
            return method.invoke(iActivityManagerObject, args);
        }
    }

}

登录拦截测试

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        AuthHookHelper.getInstance(this).hookAms();
    }

    public void firstActivity(View view) {
        Intent intent = new Intent(this, FirstActivity.class);
        startActivity(intent);
    }
}
public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);
    }

}
public class LoginActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        Constants.inLogin = true;
    }

}
上一篇 Android DialogFragment生命周期show->onCreateView
下一篇 ARouter解析之基本使用
目录
文章列表
1 Android组件化开发+自定义路由框架
Android组件化开发+自定义路由框架
2
Flutter Widget之Icon
Flutter Widget之Icon
3
Spring Security Oauth2 中优雅的扩展自定义(短信验证码)登录方式
Spring Security Oauth2 中优雅的扩展自定义(短信验证码)登录方式
4
Android NDK调用C++标准库问题
Android NDK调用C++标准库问题
5
银行卡号码校验算法(Luhn算法,又叫模10算法)
银行卡号码校验算法(Luhn算法,又叫模10算法)
最新评论
一位WordPress评论者
一位WordPress评论者
2月12日
您好,这是一条评论。若需要审核、编辑或删除评论,请访问仪表盘的评论界面。评论者头像来自 Gravatar。