更换调用setImageResource()与setImageBitmap,以减少打嗝?以减少、setImageResource、setImageBitmap

2023-09-07 03:25:23 作者:勇闯寡妇村√

Android的 setImageResource()文档规定:

Android's setImageResource() documentation states:

这确实在UI线程位图读取和解码,从而可以  导致延迟打嗝。如果这是一个问题,可以考虑使用  setImageDrawable(android.graphics.drawable.Drawable)或  setImageBitmap(android.graphics.Bitmap)和BitmapFactory来代替。

This does Bitmap reading and decoding on the UI thread, which can cause a latency hiccup. If that's a concern, consider using setImageDrawable(android.graphics.drawable.Drawable) or setImageBitmap(android.graphics.Bitmap) and BitmapFactory instead.

我期待在我的示例应用程序来解决这个问题的准确。我想我应该和字里行间在这里和取代我的电话:

I'm looking to solve this exact issue in my example application. I think I'm supposed to "read between the lines" here and and replace my call from :

((ImageView) rootView.findViewById(R.id.screen_image)).setImageResource(imageId);

改为调用

InputStream is = this.getResources().openRawResource(imageId);
Bitmap imageBitmap = BitmapFactory.decodeStream(is);
((ImageView) rootView.findViewById(R.id.screen_image)).setImageBitmap(imageBitmap);

但是从另一个线程内做到这一点,通过使用类似的的AsyncTask -

我在我的理解是否正确,或者是有一个简单的解决方案?

Am I correct in my understanding, or is there a simpler solution?

更新:

它看起来像有在显示位图一整节的效率在developer.android.com - 我调查,现在

It looks like there is an entire section on displaying bitmaps efficiently on developer.android.com - I'm investigating that now.

推荐答案

解决这个问题的最简单方法是创建一个的作为丝线放描述工作者线程;流程文档。作为它提到,异步任务可以用来替换这对于较复杂的code。最终的解决方案是改变我的code在 OnCreateView()方法,取代了原有的laggy code:

The simplest way to solve this issue is create a worker thread as described in the thread & process documentation. As it mentions, async task can be used to replace this for more complex code. the final solution was to change my code in the OnCreateView() method, replacing the original laggy code:

 final View rootView = inflater.inflate(R.layout.fragment_screen, container, false);
 int i = getArguments().getInt(ARG_PANEL_NUMBER);
 String panel = getResources().getStringArray(R.array.panel_array)[i];
 int imageId = getResources().getIdentifier(panel.toLowerCase(Locale.getDefault()),
                "drawable", getActivity().getPackageName());

 ((ImageView) rootView.findViewById(R.id.screen_image)).setImageDrawable(getResources().getDrawable(imageId));

一个新的后台线程

with a new background thread:

final View rootView = inflater.inflate(R.layout.fragment_screen, container, false);

// Load image in a separate thread to ensure navigation drawer animation is smooth.
// Replace with Async Task if necessary
    new Thread(new Runnable() {
        public void run() {
            int i = getArguments().getInt(ARG_PANEL_NUMBER);
            final String panel = getResources().getStringArray(R.array.panel_array)[i];

            int imageId = getResources().getIdentifier(panel.toLowerCase(Locale.getDefault()),
                    "drawable", getActivity().getPackageName());

            InputStream is = getActivity().getResources().openRawResource(imageId);
            final Bitmap imageBitmap = BitmapFactory.decodeStream(is);
            rootView.post( new Runnable() {
                public void run() {
                    ((ImageView) rootView.findViewById(R.id.screen_image)).setImageBitmap(imageBitmap);
                    getActivity().setTitle(panel);
                }
            });
        }

    }).start();

正如上面的文档中描述的,使用异步任务,如果这个code增长过大是更具可扩展性和可维护性。

As described in the documentation above, using an async task is more extensible and maintainable if this code grows to be too large.