在 AsyncTask 中使用 Picasso 从 URL 获取位图
Posted
技术标签:
【中文标题】在 AsyncTask 中使用 Picasso 从 URL 获取位图【英文标题】:Getting bitmap from URL using Picasso in AsyncTask 【发布时间】:2016-10-02 16:16:29 【问题描述】:编辑:我已修复“方法调用...”错误。现在我的主要问题实际上是从我的 URL 加载位图。我显然没有正确处理它,当我尝试使用 PIcasso 的 .get()
方法时,我得到了 java.lang.OutOfMemoryError
。
最好的方法是什么?我什至不需要整个图像,只需要一个中心裁剪来填充我设备上的壁纸。但是如果不先加载它,我就无法裁剪它,这是我的问题。
所以我尝试使用 Picasso 从给定 URL 获取位图,然后在其顶部绘制文本并将其设置为我的墙纸背景。我目前正在尝试从 AsyncTask 中的 onPostExecute 执行此操作。我得到的错误是:
java.lang.IllegalStateException: Method call should not happen from the main thread.
导致问题的代码行是:
Bitmap bitmap = Picasso.with(myContext)
.load(url + ".jpg")
.fit()
.centerCrop()
.get();
以及整个 onPostExcute 函数:
protected void onPostExecute(String url)
ImageView imageView = (ImageView) rootView.findViewById(R.id.preview);
try
Bitmap bitmap = Picasso.with(myContext)
.load(url + ".jpg")
.fit()
.centerCrop().get();
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(Color.RED); //Text Color
paint.setStrokeWidth(72); //Text Size
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); //Text Overlapping Pattern
canvas.drawBitmap(bitmap, 0, 0, paint);
canvas.drawText("Test...", 10, 10, paint);
((ImageView) rootView.findViewById(R.id.preview)).setImageBitmap(bitmap);
WallpaperManager wallpaperManager = WallpaperManager.getInstance(myContext);
//wallpaperManager.suggestDesiredDimensions(width, height);
wallpaperManager.setBitmap(bitmap);
Toast.makeText(myContext, "Wallpaper set successfully.", Toast.LENGTH_SHORT).show();
catch (Exception e)
android.util.Log.e(TAG, "Failed to set wallpaper", e);
我什至无法测试所有画布/绘画代码以查看它是否有效。如果您也发现其中有任何问题,请告诉我。非常感谢任何和所有提示。谢谢。
【问题讨论】:
检查这是否有帮助 ***.com/a/27180835/2686502 毕加索为你做异步,你为什么在上面使用AsyncTask
?如果你想将毕加索与你的异步任务结合起来,你所做的必须部分进入doInBackgroundMethod
。返回加载和修改后的图片,并设置在onPostExecute
中。
【参考方案1】:
只需将@jayeshsolanki93 和@zapl cmets 放在一起即可。您收到该错误是因为您在主线程上从Picasso
调用方法get()
。 get()
是一种同步方法,因此会出现错误。你有两个选择:
-
将
get()
的调用移动到AsyncTask
的doInBackground
方法,然后在onPostExecute
上执行所有画布操作。
充分利用 Picasso 并使用已有的异步方法并执行以下操作:
Picasso.with(context).load(url).into(new Target()
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from)
Log.i(TAG, "The image was obtained correctly, now you can do your canvas operation!");
@Override
public void onBitmapFailed(Drawable errorDrawable)
Log.e(TAG, "The image was not obtained");
@Override
public void onPrepareLoad(Drawable placeHolderDrawable)
Log.(TAG, "Getting ready to get the image");
//Here you should place a loading gif in the ImageView to
//while image is being obtained.
);
【讨论】:
我在 AsyncTask 中使用 Picasso 的原因是我有一些网络代码用于获取要传递给 Picasso 的 URL。你们帮我解决了主线程问题(仍在学习),但现在我正在处理 java.lang.OutOfMemoryError 由于未能正确调整传入图像的大小。我正在尝试使用不起作用的 .resize(w,h).centerCrop().get() 。有什么想法吗?以上是关于在 AsyncTask 中使用 Picasso 从 URL 获取位图的主要内容,如果未能解决你的问题,请参考以下文章