Android感知View的出现

最近在做一个播放组件端上防作弊的效果,播放的时候判断广告是否被部分或者完全遮挡了。

比较重要的载体是Window,实际的表现形式是View,所以重点往监控Window和View的创建这样的思路出发。

目前的话一共想到三种方案:
①监控View的创建:
通过给LayoutInflater 设置factory2来感知View的创建:

LayoutInflater.from(context).setFactory2()

当LayoutInflater调用createViewFromTag时:

 View view;
  	 if (mFactory2 != null) {
  	     view = mFactory2.onCreateView(parent, name, context, attrs);
  	 } else if (mFactory != null) {
  	     view = mFactory.onCreateView(name, context, attrs);
  	 } else {
  	     view = null;
  	 }

给设置的factory2接口方法onCreateView就能感知到。
缺点是场景有限,只有需要解析xml生成View的时候才能感知到,直接new View就不行了。

②监听Window的创建
创建Window是这么创建的:

Window w = PolicyManager.makeNewWindow(mContext);
#PolicyManager
public static Window makeNewWindow(Context context) {
    return sPolicy.makeNewWindow(context);
}

而这个spolicy是个静态接口对象
private static final IPolicy sPolicy;
实现是com.android.internal.policy.impl.Policy
所以我们可以hook这个sPolicy对象,感知makeNewWindow的时机。
缺点:高版本中不用PolicyManager创建Window,相应的代码处直接变为new PhoneWindow()

③监听WindowManager.addView方法
WindowManagerService服务在app本地的代理对象为WindowMangerImpl,而里面依赖了WindowManagerGlobal这个对象,它是个单例,但是不是个接口,就不能用动态代理的方式去hook。hook WindowManagerGlobal的好处是兼容性强,这个类从低版本到高版本几乎没修改过。

在WindowManagerGlobal有几个:

private final ArrayList<View> mViews = new ArrayList<View>();
private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
private final ArrayList<WindowManager.LayoutParams> mParams =
        new ArrayList<WindowManager.LayoutParams>();

他们会在调用addView,removeView,updateView时做操作,所以通过hook这些集合也可以感知到addView的出现:写一个继承ArrayList的ObserverList,覆写add的方法,替换回去。

还有一个比较关键的是需要知道加进来这个View在屏幕的位置,通过是
view.getLocationOnScreen(int[])
这个方法可以得到view在屏幕的位置,接着拿到view的宽高判断和我们View的重叠和层级关系。

④跨进程的Dialog,比如crash弹窗:
这个可以根据点击事件的MotionEvent的flag来判断是否有遮挡:
https://stackoverflow.com/questions/44197671/detecting-android-screen-overlays-programmatically

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值