本文主要说图片过大导致Activity启动慢的问题

Activity启动慢的问题

前言:今天写个demo 无意间发现布居中只有两个常规的控件但是Activity的启动时间达到惊人的 5s184ms 如下

1
03-15 18:15:39.578 1093-1120/? I/ActivityManager: Displayed com.yasin.androidndemo/.activity.AnimationActivity: +5s184ms

然后我就不淡定了,这是什么鬼?我决定找到元凶并解决它!

1.定位问题

  • 1.首先把Activity中初始化的东西全部注释

    结果:运行时间并没有什么大变化 所以排除代码的问题

  • 2.注释父控件布局内的所有控件

    结果:时间变成AnimationActivity: +183ms 启动时间锐减啊,这说明启动慢是控件的问题

  • 3.一层一层放开注释 最终发现影响启动时间的是一个ImageView
    这是我突然想到 不会是==图片过大==吧!!!
    打开图片一看 还真是 400*386 的分辨率

    2.解决问题

    找到问题就好解决了这两有两种方案
  • 1 .通过代码压缩图片显示
    这样方式就不在ImageView中设置图片 在代码中通过压缩图片大小来显示图片(一种是自己写BitmapFactory 调整inSampleSize ,另一种是直接使用图片加载框架glide等)

:这个方式写起来简单,但是扩展性不强

  • 2 .自定义View
    写一个继承ImageView的View 在初始化中处理
    加载图片逻辑
    现在来实现下这个过程

    • 1)在values的 attrs.xml中创建一个属性集合ImageViewNative 和一个xml属性srcNative,并指定类型integer(也就是图片的类型在项目中是id)如下:

      1
      2
      3
         	<declare-styleable name="ImageViewNative">
      <attr name="srcNative" format="integer"/>
      </declare-styleable>
    • 2)在View的构造方法中解析相应标签并做处理

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      public class ImageViewNative extends AppCompatImageView {
      ImageViewNative aNative;

      public ImageViewNative(Context context) {
      super(context);
      }

      public ImageViewNative(Context context, AttributeSet attrs) {
      super(context, attrs);
      init(context, attrs);
      }

      public ImageViewNative(Context context, AttributeSet attrs, int defStyleAttr) {
      super(context, attrs, defStyleAttr);
      init(context, attrs);
      }

      private void init(Context context, AttributeSet attrs) {
      TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ImageViewNative);
      if (!isInEditMode()) {
      int img = array.getResourceId(R.styleable.ImageViewNative_srcNative, 0);
      array.recycle();
      if (img != 0)
      GlideUtils.displayNative(this, img);
      }
      }}

      : GlideUtils.displayNative(this, img); 是一段Glide图片加载的封装,你可以使用其他方式替代

    • 3)在布局中使用自定义属性

      1
      2
      3
      4
      5
      6
      7
      <com.yasin.androidndemo.view.ImageViewNative
      android:id="@+id/tv_logo"
      android:layout_width="100dp"
      android:layout_height="100dp"
      android:layout_marginBottom="@dimen/margin_30dp"
      app:srcNative="@mipmap/ic_logo"
      />
使用自定义属性需要在布局文件中添加schemas声明
1
xmlns:app="http://schemas.android.com/apk/res-auto"

自定义View可以在自定义的View中处理图片而不用去每个类中修改代码,另外它的扩展性比较强 如果不需要设置圆角等其他定制的话可以方便添加

最后

使用新的方案加载结果为 .activity.AnimationActivity: +264ms 效果很明显