返回

怎么解决WindowBackground的Drawable被缓存?

Android

之前查看页面启动耗时时候,发现一件事,这个页面在style中设置了windowBackground,首次启动该页面,发现有个getDrawable方法耗时上百毫秒,第二次进入却只有几十毫秒,退出该页面,手动gc后又是耗时上百毫秒,以此决定看看AppCompatActivity的windowBackground是如何缓存drawable的。

AppCompatActivity的windowBackground属性是一个Drawable属性,它的drawable资源在创建窗口时被加载并缓存,因此第一次加载需要更多的时间。后续加载将从缓存中获取drawable,因此速度更快。

要解决这个问题,有两种方法:

  • 使用TintDrawable:TintDrawable是一个支持着色的Drawable,它可以被用来包装原始的drawable,这样原始的drawable就不会被缓存。

  • 使用AppCompatDelegateCompat.setCompatVectorFromResourcesEnabled()方法:该方法可以禁用AppCompatDelegate的矢量图标着色功能,从而防止drawable被缓存。

这两种方法都可以有效地解决windowBackground的drawable被缓存的问题,从而提高应用程序的启动速度。

这里提供一个使用TintDrawable解决该问题的示例代码:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 获取windowBackground的drawable资源
        Drawable drawable = getWindow().getDecorView().getBackground();

        // 将drawable包装成TintDrawable
        TintDrawable tintDrawable = new TintDrawable(drawable);

        // 将TintDrawable设置给windowBackground
        getWindow().setBackgroundDrawable(tintDrawable);
    }
}

使用AppCompatDelegateCompat.setCompatVectorFromResourcesEnabled()方法解决该问题的示例代码如下:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 禁用AppCompatDelegate的矢量图标着色功能
        AppCompatDelegateCompat.setCompatVectorFromResourcesEnabled(false);

        // 获取windowBackground的drawable资源
        Drawable drawable = getWindow().getDecorView().getBackground();

        // 将drawable设置给windowBackground
        getWindow().setBackgroundDrawable(drawable);
    }
}

希望这些信息对您有所帮助!