Android UI 滞后于设置图像

标签 android imageview android-drawable

我正在尝试创建一个简单的应用程序来了解抽屉导航和设置图像。我基于 Android Studio 为我创建的模板创建了这个应用。

我读到获取可绘制对象可能是一个漫长的过程,所以我为它创建了一个 Asynctask。尽管如此,我的 UI 仍然滞后,并且我收到消息说由于主线程上的工作太多而跳过了帧。我发现是以下行导致了这些问题:

pic.setImageDrawable(drawable);    //(in onPostExecute)

我在后台完成了所有处理,这一行应该只是设置可绘制对象。为什么会这么滞后?

我在某处读到设置尺寸可能会有所不同。现在我将两个维度都设置为 match_parent 并且图像在 View 中居中。我不想给它一个确定的大小。

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {

private ImageView pic;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    pic = (ImageView) findViewById(R.id.pic);

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    //set first item to be selected and set its image
    navigationView.getMenu().getItem(0).setChecked(true);
    new ImageSetter().execute();
}

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    try {
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    } catch (NullPointerException e) {
        Log.e("back pressed", e.getStackTrace().toString());
    }
}

@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();
    new ImageSetter(id).execute();

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

/**
 * class for getting the image drawable in the background and then setting it
 */
private class ImageSetter extends AsyncTask<Integer, Void, Drawable> {

    int id = //image1;

    public ImageSetter() {
    }

    public ImageSetter(int id) {
        this.id = id;
    }

    /**
     * Get drawable in background
     * Precondition: id has already been set
     * @param params
     * @return drawable of the picture to set
     */
    @Override
    protected Drawable doInBackground(Integer... params) {
        int pic = R.drawable.b1;

        switch (id) {
           //set pic
        }

        return getResources().getDrawable(pic);
    }

    // Once complete, see if ImageView is still around and set drawable
    @Override
    protected void onPostExecute(Drawable drawable) {
        if (pic != null) {
            pic.setImageDrawable(drawable);
        }
    }
}

最佳答案

代码对我来说看起来不错。使用 setImageDrawable() 应该不会太滞后并且需要在 UI 线程中运行。您已将任务卸载到另一个线程,这很好。

您要获取的源图像有多大?众所周知,Android 在处理大图像方面表现不佳......

如果你的源图片太大,我会看看Loading Large Bitmaps Efficiently来自 Android 开发者网站。这将为您提供一些处理位图的技巧。

关于Android UI 滞后于设置图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36407544/

相关文章:

Android 可绘制工具提示箭头框

安卓工作室 |无法解析现有的可绘制对象

java - Java (Android) 中的 Debug模式(正则表达式)失败

android - 如何在 Eclipse 中刷新项目

android - View.VISIBLE和INVISIBLE不起作用Kolin

java - 将文本放置在图像中特定位置的直接方法?

java - UDP数据包分离

android - 使用 firebase 添加额外的用户信息

Android:在 GridView 中放大 ImageView 的宽度

Android按钮选择并按下drawable