Android - 从计时器线程更新位图

标签 android multithreading bitmap opengl-es imageview

我得到了一个由带有 ImageView 的单个布局组成的 Android 项目。

public class MainActivity extends AppCompatActivity {

    /* original and stretched sized bitmaps */
    private Bitmap bitmapOriginal;
    private Bitmap bitmapStretched;

    /* the only view */
    private ImageView iv;

    ....
}

此 ImageView 由此可运行函数更新

    runnable = new Runnable() {
        @Override
        public void run() {
            iv.setImageBitmap(bitmapStretched);
        }
    };

runnable 由临时 JNI 函数运行,在后台线程上运行,每秒调用它 60 次。

public void jniTemporizedCallback(int buf[]) {

    /* set data to original sized bitmap */
    bitmapOriginal.setPixels(buf, 0, origWidth, 0, 0, origWidth, origHeight);

    /* calculate the stretched one */
    bitmapStretched = Bitmap.createScaledBitmap(bitmapOriginal, width, height, false);

    /* tell the main thread to update the image view */
    runOnUiThread(runnable);
}

绘制一些帧后,应用程序崩溃并显示以下消息。

A/OpenGLRenderer: Task is already in the queue!

我猜这是因为渲染器没有完成完全渲染 ImageView 的前一帧而生气。

如果我删除 runOnUiThread(runnable); 问题就会消失(显然)

如何避免这种情况?如何将我的应用程序与 openGL 渲染器同步?

我还尝试扩展 ImageView 并将 Canvas 上的位图绘制到 onDraw 函数中,但我得到了相同的结果

最佳答案

我猜你正在尝试在线程之外创建 bitmapOriginal。因此,当编译器在 60 秒后尝试再次调用时,它得到相同的对象并且无法识别任务。我会建议如下更好。

 public void jniTemporizedCallback(int buf[]) {
      // Initialize
      bitmapOriginal = Bitmap.createBitmap(///)
     /* set data to original sized bitmap */
     bitmapOriginal.setPixels(buf, 0, origWidth, 0, 0, origWidth, origHeight);

    /* calculate the stretched one */
    bitmapStretched = Bitmap.createScaledBitmap(bitmapOriginal, width, height,false);

    /* tell the main thread to update the image view */
    runOnUiThread(runnable);
}

关于Android - 从计时器线程更新位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39078403/

相关文章:

java - 毕加索 + Recyclerview

c# - AutoResetEvent 仅在未设置该次数时等待的最佳方法

ImageView 中的 Android 中心位图

android - 如何从编辑文本中的可滚动内容创建位图图像?

java - 如何将当前数据从适配器传递到适配器?

Android:抽屉导航和音频播放器

android - 如何允许在标准搜索对话框中提交空白搜索

java - 为什么在这个例子中使用synchronized(Java并发)是不正确的?

C# 如何在非静态成员函数上调用 Action?

Android getExternalCacheDir() 返回 null