Android检测背景图片是否超大

Android中使用Glide加载图片时,它会修改图片大小以适应ImageView的实际尺寸。但它不能处理写在xml中background属性设置的背景图。下面代码动态检测图片尺寸是否会超大。

核心想法是,注册ActivityLifecycleCallback,在Activity处于stop状态时,获取Activity或Fragment中的所有View。检查其背景的BitmapDrawable,如果超大,则弹出Toast报警。

import android.app.Activity;
import android.app.Application;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Looper;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.android.base.helper.Toast;
import java.util.ArrayList;
import java.util.List;

public class BitmapChecker {

  /**
   * 比例限制, 根据实际情况设置
   */
  private static final float ratio = 1.2F;
  private static Application sApp;

  public static void install(Application app) {
    if (Looper.getMainLooper().getThread() != Thread.currentThread()) {
      return;
    }
    sApp = app;
    registerActivityLifecycleCallback(app);
  }

  /**
   * 递归地获取一个ViewGroup下的所有View
   */
  private static void getImageViews(View v, List views) {
    if (v instanceof ViewGroup) {
      for (int i = 0; i < ((ViewGroup) v).getChildCount(); i++) {
        getImageViews(((ViewGroup) v).getChildAt(i), views);
      }
    } else {
      if (!views.contains(v)) {
        views.add(v);
      }
    }
  }

  /**
   * 检查ImageView或View的背景图是否超大
   */
  private static void checkBitmap(List views) {
    for (View v : views) {
      Drawable drawable;

      if (v instanceof ImageView) {
        drawable = ((ImageView) v).getDrawable();
      } else {
        drawable = v.getBackground();
      }

      if (drawable instanceof BitmapDrawable) {
        Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
        if (bitmap.getWidth() > v.getWidth() * ratio
            || bitmap.getHeight() > v.getHeight() * ratio) {
          String id = "NoId";
          if (v.getId() != View.NO_ID) {
            id = sApp.getResources().getResourceEntryName(v.getId());
          }
          Toast.show("Image too big View id="
              + id
              + " require width="
              + v.getWidth()
              + " require height="
              + v.getHeight()
              + " Supplied width=" + bitmap.getWidth()
              + " Supplied height=" + bitmap.getHeight());
        }
      }
    }
  }

  /**
   * 注册生命周期方法
   */
  private static void registerActivityLifecycleCallback(Application app) {
    app.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
      @Override
      public void onActivityStopped(@NonNull Activity activity) {
        List imageViews = new ArrayList<>();
        if (activity instanceof FragmentActivity) {
          List fragments =
              ((FragmentActivity) activity).getSupportFragmentManager().getFragments();
          for (Fragment fragment : fragments) {
            getImageViews(fragment.getView(), imageViews);
          }
        } else {
          getImageViews(activity.getWindow().getDecorView(), imageViews);
        }
        checkBitmap(imageViews);
      }

      @Override
      public void onActivityCreated(@NonNull Activity activity,
          @Nullable Bundle savedInstanceState) {

      }

      @Override
      public void onActivityStarted(@NonNull Activity activity) {

      }

      @Override
      public void onActivityResumed(@NonNull Activity activity) {

      }

      @Override
      public void onActivityPaused(@NonNull Activity activity) {

      }

      @Override
      public void onActivitySaveInstanceState(@NonNull Activity activity,
          @NonNull Bundle outState) {

      }

      @Override
      public void onActivityDestroyed(@NonNull Activity activity) {

      }
    });
  }
}

你可能感兴趣的:(Android检测背景图片是否超大)