android - 使用UI-Thread更新ImageView的位图

标签 android multithreading android-imageview ui-thread android-runonuithread

在另一项操作期间,我必须每秒操作一次位图的像素,并将结果显示在ImageView中。这是一种操作位图并更新ImageView的方法:

private void overlay(Bitmap bitmap) {
int j = 70;
while (flag) {
    //here I manipulate some pixels of bitmap that corresponds to "j" 
    //and save result in "tempBmp":
    ...
    //update imageView:
    iv1.setImageBitmap(tempBmp);
    iv1.postInvalidate();
    //          try {
    //              Thread.sleep(1000);
    //          } catch (InterruptedException e) {
    //          }
    //update "j":
    j = (j+1)%src.rows();
}
}

上面的方法以这种方式从UI线程(按钮的onclick事件)中调用:
runOnUiThread(new Runnable() {
    public void run() {
        overlay(bmp);
    }
});

当App运行时,没有问题,App崩溃或ANR,但是ImageView(iv1)不会更新。我调试代码,并且操作了位图的像素。我也取消注释try/catch块,但结果是相同的。

奇怪的是:当我注释while块的开始和结束时,位图可以正确操作(一次,对于j = 70),并且ImageView会按预期进行更新!

更新问题:

关于eshayne和Onik的评论和答案,我将overlay方法中的像素操作更改为简单的操作并检查了结果,但是结果是相同的。实际的overlay方法使用openCV,但是在这里我更改像素的颜色,因此无需使用openCV即可看到结果:
btn.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View arg0) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                overlay(bmp);
            }
        }).run();
    }
});

叠加方法,已简化:
private void overlay(Bitmap bitmap){
    int j = 0;
    tempBmp = Bitmap.createBitmap(bitmap);
    while (j < bitmap.getHeight()) {
        for (int i = 0; i < bitmap.getWidth(); i++) {
            tempBmp.setPixel(i, j, 0);
        }

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // post the changes to Ui thread
        iv1.post(new Runnable() {
            @Override
            public void run() {
                iv1.setImageBitmap(tempBmp);
            }
        });
        j = (j + 1);
    }

}

如何使用ImageView每秒更新while?我做错了什么吗?

最佳答案

尝试将循环移到UI线程外,然后在UI线程内运行setImageBitmap调用。就像是:

// from non-UI thread:
while (flag) {
    // perform image manipulation
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            iv1.setImageBitmap(tempBmp);
        }
    });
}

关于android - 使用UI-Thread更新ImageView的位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26185034/

相关文章:

java - 为什么线程对象在作用域后没有被销毁?

c - 不同的线程使用不同的策略进行调度

android - 如何调整背景图像大小以适应Android中的应用程序屏幕尺寸

java - 在 Exchange 中使用 JavaMail/Android 通过 IMAP 获取联系人

Android Studio 找不到我的设备

ios - 多线程 : executing method calls only after finished executing other method

android - 查询有关 Android 中 ImageView 上的触摸坐标

android - 从 RemoteViews 调用 setImageDrawable

android - 在库模块中添加工具栏

java - 如何使用 skyepub 读取 epub 文件?