关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。
目录
一、导读
我们继续总结学习,温故知新。
二、概览
本文讲述如何遍历获取页面中所有的view,并输出对应的id,textview文本内容,imageview实际大小及设置的图片大小。
可用于检测android应用中的大图。
三、实践
不多说,直接上代码,
图片大小检测思路。
java
fun checkBitmapFromView(){
//1、遍历activity中的各个View控件
//2、获取View控件加载的Bitmap
//3、对比Bitmap宽高与View宽高
}
示例代码:
遍历获取所有的view,并输出相应的信息
java
List<View> viewList=new ArrayList<>();
@Override
protected void onResume() {
super.onResume();
logoIcon.postDelayed(new Runnable() {
@Override
public void run() {
getAllViews((ViewGroup) getWindow().getDecorView());
for (View view: viewList) {
if(view instanceof TextView) {
Log.d("xyz", view.toString());
Log.d("xyz", ((TextView)view).getText().toString());
} else if(view instanceof ImageView) {
Log.d("xyz", view.toString());
checkBitmap(view, ((ImageView)view).getDrawable());
} else {
Log.d("xyz", view.toString());
}
}
}
}, 3000);
}
java
//获取所有的子view,我们这里只保存imageview及textview,用于测试
private List<View> getAllViews(ViewGroup viewGroup){
for(int i=0;i< viewGroup.getChildCount(); i++){
View view = viewGroup.getChildAt(i);
if(view instanceof ViewGroup) {
getAllViews((ViewGroup) view);
} else {
if(view instanceof ImageView || view instanceof TextView) {
viewList.add(view);
}
if(view.getVisibility() == View.VISIBLE) {
}
}
}
return viewList;
}
ImageView大小检测
java
private void checkBitmap(Object thiz, Drawable drawable) {
if (drawable instanceof BitmapDrawable && thiz instanceof View) {
final Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
final View view = (View) thiz;
int width = view.getWidth();
int height = view.getHeight();
if (bitmap != null) {
if (width > 0 && height > 0) {
// 图标宽高都大于view带下的2倍以上,则警告
if (bitmap.getWidth() >= (width << 1)
&& bitmap.getHeight() >= (height << 1)) {
// warn(bitmap.getWidth(), bitmap.getHeight(), width, height, new RuntimeException("Bitmap size too large"));
}
warn(bitmap.getWidth(), bitmap.getHeight(), width, height, new RuntimeException("log"));
} else {
final Throwable stackTrace = new RuntimeException();
view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
int w = view.getWidth();
int h = view.getHeight();
if (w > 0 && h > 0) {
if (bitmap.getWidth() >= (w << 1)
&& bitmap.getHeight() >= (h << 1)) {
// warn(bitmap.getWidth(), bitmap.getHeight(), w, h, stackTrace);
}
warn(bitmap.getWidth(), bitmap.getHeight(), w, h, stackTrace);
view.getViewTreeObserver().removeOnPreDrawListener(this);
}
return true;
}
});
}
} else {
warn(bitmap.getWidth(), bitmap.getHeight(), width, height, new RuntimeException("bitmap null"));
}
}
}
private void warn(int bitmapWidth, int bitmapHeight, int viewWidth, int viewHeight, Throwable t) {
String warnInfo = new StringBuilder("Bitmap info: ")
.append("\n real size: (").append(bitmapWidth).append(',').append(bitmapHeight).append(')')
.append("\n desired size: (").append(viewWidth).append(',').append(viewHeight).append(')')
.append("\n call stack trace: \n").append(Log.getStackTraceString(t)).append('\n')
.toString();
Log.d("xyz", warnInfo);
}
我们看下log输出
java
com.xxx.xxx.xxx.ImageViewFor{e292c7e VFED..C.. ........ 540,1348-900,1528 #7f0a024e app:id/bt_phone}
2023-08-23 18:28:47.956 12556-12556 xyz com.xxx.xxx D Bitmap info:
real size: (144,144)
desired size: (360,180)
call stack trace:
java.lang.RuntimeException: log
at com.xxx.xxx.ui.LoginActivity.checkBitmap(LoginActivity.java:235)
at com.xxx.xxx.ui.LoginActivity.access$100(LoginActivity.java:79)
at com.xxx.xxx.ui.LoginActivity$2.run(LoginActivity.java:193)
at android.os.Handler.handleCallback(Handler.java:900)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8673)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)