}
@Override
public boolean addAll(Collection<? extends T> collection) {
int oldSize = size();
boolean added = super.addAll(collection);
if (added) {
notifyAdd(oldSize, size() - oldSize);
}
return added;
}
@Override
public void clear() {
int oldSize = size();
super.clear();
if (oldSize != 0) {
notifyRemove(0, oldSize);
}
}
@Override
public T remove(int index) {
T val = super.remove(index);
notifyRemove(index, 1);
return val;
}
@Override
public boolean remove(Object object) {
int index = indexOf(object);
if (index >= 0) {
remove(index);
return true;
} else {
return false;
}
}
@Override
public T set(int index, T object) {
T val = super.set(index, object);
if (mListeners != null) {
for (OnListChangeListener listener : mListeners) {
listener.onChange(this, index, 1);
}
}
return val;
}
@Override
protected void removeRange(int fromIndex, int toIndex) {
super.removeRange(fromIndex, toIndex);
notifyRemove(fromIndex, toIndex - fromIndex);
}
private void notifyAdd(int start, int count) {
if (mListeners != null) {
for (OnListChangeListener listener : mListeners) {
listener.onAdd(this, start, count);
}
}
}
private void notifyRemove(int start, int count) {
if (mListeners != null) {
for (OnListChangeListener listener : mListeners) {
listener.onRemove(this, start, count);
}
}
}
public interface OnListChangeListener {
void onChange(ArrayList list, int index, int count);
void onAdd(ArrayList list, int start, int count);
void onRemove(ArrayList list, int start, int count);
}
}
接下来就是执行hook操作:
/**
- @param enable 是否开启全局灰色调
*/
public static void enable(boolean enable) {
if (!enable) {
return;
}
try {
//灰色调Paint
final Paint mPaint = new Paint();
ColorMatrix mColorMatrix = new ColorMatrix();
mColorMatrix.setSaturation(0);
mPaint.setColorFilter(new ColorMatrixColorFilter(mColorMatrix));
//反射获取windowManagerGlobal
@SuppressLint(“PrivateApi”)
Class<?> windowManagerGlobal = Class.forName(“android.view.WindowManagerGlobal”);
@SuppressLint(“DiscouragedPrivateApi”)
java.lang.reflect.Method getInstanceMethod = windowManagerGlobal.getDeclaredMethod(“getInstance”);
getInstanceMethod.setAccessible(true);
Object windowManagerGlobalInstance = getInstanceMethod.invoke(windowManagerGlobal);
//反射获取mViews
Field mViewsField = windowManagerGlobal.getDeclaredField(“mViews”);
mViewsField.setAccessible(true);
Object mViewsObject = mViewsField.get(windowManagerGlobalInstance);
//创建具有数据感知能力的ObservableArrayList
ObservableArrayList observerArrayList = new ObservableArrayList<>();
observerArrayList.addOnListChangedListener(new ObservableArrayList.OnListChangeListener() {
@Override
public void onChange(ArrayList list, int index, int count) {
}
@Override
public void onAdd(ArrayList list, int start, int count) {
View view = (View) list.get(start);
if (view != null) {
view.setLayerType(View.LAYER_TYPE_HARDWARE, mPaint);
}
}
@Override
public void onRemove(ArrayList list, int start, int count) {
}
});
//将原有的数据添加到新创建的list
observerArrayList.addAll((ArrayList) mViewsObject);
//替换掉原有的mViews
mViewsField.set(windowManagerGlobalInstance, observerArrayList);
} catch (Exception e) {
e.printStackTrace();
}
}
最后,只需在Application的onCreate中调用上述代码进行hook即可。
已知存在的问题
-
开启了View的硬件加速,可能会存在兼容性问题
-
对于SurfaceView和Textureview以及其子类无效
对于问题1笔者在项目中暂未遇到问题,如果读者朋友们在项目中遇到兼容性问题,欢迎留言;
对于问题2其原因是因为这两个组件内部有独立的绘图表面(Surface),笔者目前未想到好的解决方案,如果有思路欢迎一块交流。
组件封装
为了方便大家使用,我将上述代码封装成了组件并上传到了jitpack,使用方法如下:
首先在你项目的build.gradle文件中添加jitpack的仓库
allprojects {
repositories {
…
maven { url ‘https://jitpack.io’ }
}
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
尾声
以薪资待遇为基础,以发展为最终目标,要在高薪资的地方,谋求最好的发展!
下面是有几位Android行业大佬对应上方技术点整理的一些进阶资料。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
、讲解视频,并且会持续更新!**
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
尾声
以薪资待遇为基础,以发展为最终目标,要在高薪资的地方,谋求最好的发展!
下面是有几位Android行业大佬对应上方技术点整理的一些进阶资料。
[外链图片转存中…(img-sVADB8mG-1712451443081)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!