【问题标题】:NullPoint exception on value returned from asyncTask从 asyncTask 返回的值的 NullPoint 异常
【发布时间】:2014-08-25 08:42:20
【问题描述】:

我不明白为什么位图为空。我已经测试了从doInbackGround() 返回的值,它不为空,onPostExecute() 方法也不为空。 AsyncTask 在使用 bitMap 之前被执行,但是这个值还是 null。

我的异步任务:

public class ImageTask extends AsyncTask<Void, Void, Bitmap> {

    private Display display;

    public ImageTask(Display display) {
        this.display = display;
    }

    @Override
    protected Bitmap doInBackground(Void... params) {
        Bitmap overlay;
        try {
            URL url = new URL(...);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            overlay = BitmapFactory.decodeStream(input);
            connection.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return overlay;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (bitmap != null)
            display.setBitmap(bitmap);
    }
}

我在 Display 类中在这里启动 AsyncTask:

public class Display{
     private Bitmap bitmap;
     ...

public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;

    }

public void func(){ 
          ....
          new ImageTask(this).execute();
          canvas.drawBitmap(bitmap, 25, 25, null); -> bitmap  is null here !?!?!
          ....   
}

我的日志:

08-25 10:19:00.757: E/AndroidRuntime(4322):     FATAL EXCEPTION: main
08-25 10:19:00.757: E/AndroidRuntime(4322):     java.lang.NullPointerException
08-25 10:19:00.757: E/AndroidRuntime(4322):     at android.graphics.Canvas.throwIfRecycled(Canvas.java:1025)
08-25 10:19:00.757: E/AndroidRuntime(4322):     at android.graphics.Canvas.drawBitmap(Canvas.java:1065)
08-25 10:19:00.757: E/AndroidRuntime(4322):     at com.graphic.core.Display.addMarker(Display.java:51)

现在我有一个问题,当我执行asyncTask.execute() 时,这条指令下面的行会被执行吗?或者这些行仅在 asyncTask 完成后执行? 我认为这些行是在onPostExecute() 之后执行的,但我想澄清一下。

提前致谢。

【问题讨论】:

    标签: java android bitmap android-asynctask


    【解决方案1】:

    asyncTask.execute() 启动异步操作。这意味着AsyncTask 中的代码将与您的同步代码并行运行。所以asyncTask.execute() 之后的所有代码都将在AsyncTask 中的代码之前或并行运行。所以这段代码:

    new ImageTask(this).execute();
    canvas.drawBitmap(bitmap, 25, 25, null);
    

    不会工作。第一行以AsyncTask 开头,然后您立即尝试绘制Bitmap。您需要做的是在onPostExecute() 中返回Bitmap。当然,您已经在使用 setBitmap() 方法执行此操作,但缺少的是只有 调用 setBitmap() 之后您才应该尝试绘制它。

    【讨论】:

    • 好的,我明白了。如果我遇到这种情况,我有一个问题要问:new Foo(this, new Task(value).execute().get()); 并且此行下方没有行。在这种情况下,传递给 Foo 的 value 将为空?或者在创建对象之前它会等待 asyncTask 完成。
    • 通过调用get(),您将强制UI 线程等待AsyncTask 完成。这正是您想要的。您正在使用AsyncTask 将工作卸载到单独的线程中,因此您的 UI 将始终保持流畅和响应。如果您调用get(),您将强制AsyncTask 中的代码基本上再次同步运行,从而消除AsyncTask 可能必须提供的任何优势!这与根本不使用AsyncTask 相同。
    • 好的,我会记住的,非常感谢您的解释。
    【解决方案2】:

    AsyncTask 与 UI 线程并行运行,因此在下载图像时会调用 canvas.drawBitmap(bitmap, 25, 25, null);。由于图像尚未设置,因此您会得到一个NullPointerException

    尝试将canvas.drawBitmap(bitmap, 25, 25, null); 放入setBitmap(Bitmap); 而不是func();

    【讨论】:

      【解决方案3】:

      将此canvas.drawBitmap(bitmap, 25, 25, null); 移动到onPostExecute() 中。

      AsyncTask 在不同的线程中运行。所以这些行将在不等待 AsyncTask 的结果的情况下执行。

      【讨论】:

        【解决方案4】:

        canvas.drawBitmap 和您的 AsyncTask 并行运行。所以绘图甚至在 AsyncTask 完成之前就发生了。将您的canvas.drawBitmap 移至setBitmap()

        【讨论】:

          【解决方案5】:

          调用时位图为空是正常的

          canvas.drawBitmap(bitmap, 25, 25, null)
          

          因为您没有等待异步任务返回结果。您应该在 onPostExecute 中调用 drawBitmap 并可能在视图上调用 invalidate() 以强制重绘

          【讨论】:

            猜你喜欢
            • 2019-04-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-02-18
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多