Android - 加载drawables而不跳帧

Posted

技术标签:

【中文标题】Android - 加载drawables而不跳帧【英文标题】:Android - Loading drawables without skipping frames 【发布时间】:2016-05-08 13:39:29 【问题描述】:

好的,所以我在活动中使用可绘制的 PNG(1200 x 1920, 30kb)作为背景。我的 XML 代码的 sn-p 如下所示。我的问题是应用程序跳帧并且响应滞后。谁能告诉我为什么会这样,或者解决我的问题的好方法?我仍然希望能够使用这个 PNG 文件作为背景。谢谢

XML 片段:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:background="@drawable/MY_PNG_BACKGROUND"
    tools:context=".MainActivity">

Logcat 消息:

I/Choreographer: Skipped 53 frames!  The application may be doing too much work on its main thread.

我看过的东西:

Imageview skipped frames(如果有人能告诉我如何在 XML 中而不是在 Java 中以编程方式进行操作,这可能对我有用) background images causing frames to be skipped

【问题讨论】:

“谁能告诉我为什么会这样”——解码一个 9MB 的图像不会很快(其中 9MB 是指使用的堆空间量)。这不仅需要花一点时间,而且可能会触发一个或多个GC_FOR_ALLOC 调用以释放内存以便能够处理图像。另外,由于您选择将其放在可绘制资源中,Android 可能会重新采样图像以处理屏幕密度差异。而且,最重要的是,绝大多数 Android 设备的屏幕分辨率较低,无法使用如此大的高分辨率图像。 对不起,我忘了提到所提到的 PNG 是用于平板电脑视图的。唯一的解决方案是拥有更小/更少分辨率的背景吗? @CommonsWare 我建议您首先确认问题的确切性质,例如使用 Android Studio 进行方法跟踪并查看您将时间花在哪里。 53 帧几乎是主应用程序线程上占用的整整一秒。然后,查找紧接在您的 Choreographer 之前的其他 LogCat 消息(例如,GC_FOR_ALLOC),以尝试确定这是否是您的问题的一部分。您可能尝试在后台线程上预加载此图像,尽管我从未尝试过将其用于资源。另外,请确保此资源位于 res/drawable-nodpi/res/drawable-anydpi/ 好的,我在图形方面遇到了很多麻烦,所以我可能会考虑预加载图像。如果您碰巧知道这样做的好方法并想将其放入答案中,我可以将其标记为正确。感谢@CommonsWare 的帮助 【参考方案1】:

感谢 cmets 中 CommonsWare 的一些帮助,我能够解决这个问题。我在后台使用 AsyncTask 在我的 java 类中预加载了 drawable。这是一个代码示例:

public class MainActivity extends Activity 

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

        //Calling the task to be done in the background, in this case loading the drawable
        new LoadDrawable().execute();

    

    private class LoadDrawable extends AsyncTask<Drawable, Void, Drawable> 
        @Override
        protected Drawable doInBackground(Drawable... params) 
            //Loading the drawable in the background
            final Drawable image = getResources().getDrawable(R.drawable.my_drawable);
            //After the drawable is loaded, onPostExecute is called
            return image;
        

        @Override
        protected void onPostExecute(Drawable loaded) 
            //Hide the progress bar
            ProgressBar progress = (ProgressBar) findViewById(R.id.progress_bar);
            progress.setVisibility(View.GONE);
            //Set the layout background with your loaded drawable
            RelativeLayout layout = (RelativeLayout) findViewById(R.id.my_layout);
            layout.setBackgroundDrawable(loaded);
        

        @Override
        protected void onPreExecute() 

        @Override
        protected void onProgressUpdate(Void... values) 
    

【讨论】:

我尝试了同样的方法,但仍然有非常明显的滞后

以上是关于Android - 加载drawables而不跳帧的主要内容,如果未能解决你的问题,请参考以下文章

Android 大量跳帧错误

android ImageLoader 混淆加载drawable出现黑色图片的解决方案

Android操作系统中默认的loading动画怎么调用

Xcopy共享违规,如何仍然复制而不跳过

使用 SQL Server Rank 函数对行进行排名而不跳过排名号

android Loading 加载之后怎么跳转到主页面,代码如下,在线等,求大神