纸板样本,必须从 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);
}
});
尝试为 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);
}
});