纸板样本,必须从 UI 线程调用方法

Cardboard sample, method must be called from UI thread

尝试为 google cardboard 开发应用程序,我从官方 sdk 下载了示例。在内部 class ImageLoaderTask(它应该是管理线程的助手 class)

    class ImageLoaderTask extends AsyncTask<Pair<Uri, Options>, Void, Boolean> {

    /**
     * Reads the bitmap from disk in the background and waits until it's loaded by pano widget.
     */
    @Override
    protected Boolean doInBackground(Pair<Uri, Options>... fileInformation) {
      Options panoOptions = null;  // It's safe to use null VrPanoramaView.Options.
      InputStream istr = null;
      if (fileInformation == null || fileInformation.length < 1
          || fileInformation[0] == null || fileInformation[0].first == null) {
        AssetManager assetManager = getAssets();
        try {
          istr = assetManager.open("andes.jpg");
          panoOptions = new Options();
          panoOptions.inputType = Options.TYPE_STEREO_OVER_UNDER;
        } catch (IOException e) {
          Log.e(TAG, "Could not decode default bitmap: " + e);
          return false;
        }
      } else {
        try {
          istr = new FileInputStream(new File(fileInformation[0].first.getPath()));
          panoOptions = fileInformation[0].second;
        } catch (IOException e) {
          Log.e(TAG, "Could not load file: " + e);
          return false;
        }
      }

      panoWidgetView.loadImageFromBitmap(BitmapFactory.decodeStream(istr), panoOptions);
      try {
        istr.close();
      } catch (IOException e) {
        Log.e(TAG, "Could not close input stream: " + e);
      }

      return true;
    }
  }

panoWidgetView 是全景图的小部件,它在 activity 中声明,其中包含此内部 class。 但是 Android Studio 给我这个错误: 方法 loadImageFromBitmap 必须从 UI 线程调用,当前推断线程是 worker。 任何可能的解决方案?

是的,不要在后台线程上调用 loadImageFromBitmap。您调用它的方法是 doInBackground。如果您使用 onPostExecute 方法将位图传递给主线程,您可以在那里进行。

尝试在 onPostExecute 中移动 "loadImageFromBitmap" :

class ImageLoaderTask extends AsyncTask<Pair<Uri, BitmapFactory.Options>, Void, Boolean> {
        Options panoOptions = null;  // It's safe to use null VrPanoramaView.Options.
        InputStream istr = null;

        /**
         * Reads the bitmap from disk in the background and waits until it's loaded by pano widget.
         */
        @Override
        protected Boolean doInBackground(Pair<Uri, BitmapFactory.Options>... fileInformation) {

            if (fileInformation == null || fileInformation.length < 1
                    || fileInformation[0] == null || fileInformation[0].first == null) {
                AssetManager assetManager = getAssets();
                try {
                    istr = assetManager.open("andes.jpg");
                    panoOptions = new Options();
                    panoOptions.inputType = Options.TYPE_STEREO_OVER_UNDER;
                } catch (IOException e) {
                    Log.e(TAG, "Could not decode default bitmap: " + e);
                    return false;
                }
            } else {
                try {
                    istr = new FileInputStream(new File(fileInformation[0].first.getPath()));
                    panoOptions = fileInformation[0].second;
                } catch (IOException e) {
                    Log.e(TAG, "Could not load file: " + e);
                    return false;
                }
            }

            try {
                istr.close();
            } catch (IOException e) {
                Log.e(TAG, "Could not close input stream: " + e);
            }

            return true;
        }

        @Override
        protected void onPostExecute(Boolean aBoolean) {
            if( istr!=null && panoOptions!=null){
                 panoWidgetView.loadImageFromBitmap(BitmapFactory.decodeStream(istr), panoOptions);
            }
            super.onPostExecute(aBoolean);
        }
    }

您不能对 doInBackground 执行 UI 操作。
您应该在 onPostExecute 上执行该任务。


但是你仍然想在 doInBackground 上实现那么你可以用这种方式

  runOnUiThread(new Runnable() {
            @Override
            public void run() {
                panoWidgetView.loadImageFromBitmap(BitmapFactory.decodeStream(istr), panoOptions); 
        }
    });