android - 在 AsyncTask 中设置 Firebase 存储图像的墙纸
问题描述
我在设置我的设备壁纸时遇到了一些麻烦,同时我的 Firebase 存储代码在里面和 AsyncTask。
首先,将这段代码包含在 AsyncTask 中是否合适?
其次,壁纸已成功下载并设置,但由于某种原因,AsyncTask 在关闭 ProgressDialog 并显示 Toast 告诉我壁纸已成功设置之前并没有等待完成。这里可能出了什么问题?
第三,尽管代码在 AsyncTask 的 doInBackground() 中,但它似乎并没有真正与主线程分开运行,因为我的应用程序在代码运行时完全冻结(最终在完成时解冻)。
对我有什么见解吗?我边走边学,很困惑。
下面是供参考的代码。
private class wallpaperTaskHome extends AsyncTask<Void, Void, String> {
private ProgressDialog dialog = new ProgressDialog(PhotoDetailsActivity.this);
onPreExecute()
@Override
protected void onPreExecute() {
// Progress dialog to show user that the app is working...
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
dialog.setMessage(getString(R.string.wallpaper_please_wait));
dialog.show();
}
做背景()
@Override
protected String doInBackground(Void... params) {
// Get Intent data from intent passed from Photos.java class.
Intent intent = getIntent();
int position = intent.getExtras().getInt("Image int");
final StorageReference fullSizeImagesStoragePath = mStorageRef.child("images_full_size/" + position + ".jpg");
fullSizeImagesStoragePath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
// Retrieve a WallpaperManager
final WallpaperManager wallpaperManager = WallpaperManager
.getInstance(PhotoDetailsActivity.this);
Glide
.with(PhotoDetailsActivity.this)
.asBitmap()
.load(uri)
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
try {
wallpaperManager.setBitmap(resource, null, true, WallpaperManager.FLAG_SYSTEM);
} catch (IOException e) {
}
}
});
}
});
return null;
}
onPostExecute()
protected void onPostExecute(String result) {
if (dialog.isShowing()) {
dialog.dismiss();
}
// Show a Toast message on successful wallpaper change
showToastWallpaperApplied();
}
}
感谢您为我提供的任何帮助!
编辑:我已经将我的doInBackground()
方法更改为如下所示,它基本上做同样的事情,但现在至少它正在尝试异步调用整个代码,因为它给了我错误:java.lang.IllegalArgumentException: You must call this method on the main thread
final WallpaperManager wallpaperManager = WallpaperManager
.getInstance(this);
Intent intent = getIntent();
int position = intent.getExtras().getInt("Image int");
final StorageReference fullSizeImagesStoragePath = mStorageRef.child("images_full_size/" + position + ".jpg");
GlideApp.with(PhotoDetailsActivity.this)
.asBitmap()
.load(fullSizeImagesStoragePath)
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
try {
wallpaperManager.setBitmap(resource, null, true, WallpaperManager.FLAG_SYSTEM);
} catch (IOException e) {
}
}
});
它指向.into(new SimpleTarget<Bitmap>()
只在主线程上运行的方法。帮助?
解决方案
我的猜测是 glide 内部会在 UI 线程上调用 onSuccess,然后你设置壁纸的任务仍然在 ui 线程上运行,即使你将它包装在异步任务中。我建议你检查一下 glide 相关方法的实现。
编辑:如果是这种情况,那么您也需要将设置的墙纸任务包装到异步任务中,这将非常繁琐。我的建议是使用 Rxjava 将这些任务链接在一起,这将是一个更好的方法。
编辑:查看文档, https://github.com/bumptech/glide/wiki/Loading-and-Caching-on-Background-Threads 它说
如果您确实想与后台线程上的解码图像进行交互,而不是使用 downloadOnly 您可以使用返回 FutureTarget 的 into() 版本
因此,您可以尝试在后台线程(通过异步任务)上同步加载图像以避免阻塞 ui,但请确保使用应用程序上下文调用它以避免内存泄漏。
Bitmap myBitmap = Glide.with(applicationContext)
.load(yourUrl)
.asBitmap()
.centerCrop()
.into(500, 500)
.get()
推荐阅读
- openedge - 用户输入字符串拆分
- spring-boot - PreAuthorize 注解在验证失败的情况下发送 HTTP 404 而不是 HTTP 401
- ios - 将 UIImageview 捕获到包含 UIView 的 Objective C 中的图像
- jsf - 如何从 JSF 中的请求/响应中获取 id?
- javascript - React - 如何将道具图像传递给文本组件
- c# - asp.net mvc 显示十进制错误
- selenium - 使用 selenium 的 Protractor e2e 测试未在 IE11 上运行 超时问题
- sql - laravel 如何将 sql 转换为 laravel sql
- openlayers - 如何将 GeoJSON 导入 OpenLayers?
- bash - 如何根据值的特定部分对行进行排序?