自从我将SDK / ADT升级到自Android 4.4以来的最新更改以来,我不确定这是否与此相关,但这是自此错误开始以来唯一的重大更改,我在我的错误中得到了此错误应用
日志没有说明我的应用程序在哪里发生这种情况。虽然有DrawerLayout
的引用。它似乎也引用了支持库v4,但我使用的是v13。
11-16 15:45:12.406: E/AndroidRuntime(1236): FATAL EXCEPTION: main
11-16 15:45:12.406: E/AndroidRuntime(1236): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@41f1e4e8
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.graphics.Canvas.throwIfRecycled(Canvas.java:1058)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.graphics.Canvas.drawBitmap(Canvas.java:1097)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.View.draw(View.java:13854)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.drawChild(ViewGroup.java:3086)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.support.v4.widget.DrawerLayout.drawChild(DrawerLayout.java:804)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2923)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.View.draw(View.java:13823)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.drawChild(ViewGroup.java:3086)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2923)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.View.draw(View.java:13823)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.drawChild(ViewGroup.java:3086)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2923)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.View.draw(View.java:13823)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.drawChild(ViewGroup.java:3086)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2923)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.View.draw(View.java:13947)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.widget.FrameLayout.draw(FrameLayout.java:467)
11-16 15:45:12.406: E/AndroidRuntime(1236): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2224)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:2482)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewRootImpl.draw(ViewRootImpl.java:2395)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2239)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1872)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.Choreographer.doCallbacks(Choreographer.java:562)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.Choreographer.doFrame(Choreographer.java:532)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.os.Handler.handleCallback(Handler.java:730)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.os.Handler.dispatchMessage(Handler.java:92)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.os.Looper.loop(Looper.java:137)
11-16 15:45:12.406: E/AndroidRuntime(1236): at android.app.ActivityThread.main(ActivityThread.java:5103)
11-16 15:45:12.406: E/AndroidRuntime(1236): at java.lang.reflect.Method.invokeNative(Native Method)
11-16 15:45:12.406: E/AndroidRuntime(1236): at java.lang.reflect.Method.invoke(Method.java:525)
11-16 15:45:12.406: E/AndroidRuntime(1236): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
11-16 15:45:12.406: E/AndroidRuntime(1236): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-16 15:45:12.406: E/AndroidRuntime(1236): at dalvik.system.NativeStart.main(Native Method)
这是我在AsyncTask中使用BitMap
的唯一代码;这适用于我的Drawer listView
标题中的图像:
static class GetProfileImageURL extends AsyncTask<String, String, Void> {
private Bitmap b;
private Context mContext;
public GetProfileImageURL(Context c) {
mContext = c;
}
@Override
protected Void doInBackground(String... params) {
URL url;
try {
String profImage = String.valueOf(Rateit.userId);
url = new URL(Rateit.PROFILE_PIC_URL + profImage + ".jpg");
b = BitmapFactory.decodeStream(url.openConnection()
.getInputStream());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Void v) {
if (mContext != null) {
if (b != null) {
userIcon.setImageBitmap(ImageHelper.getRoundedCornerBitmap(
b, 50));
}
}
}
}
创建AsyncTask
时,Activity
仅被调用。
根据要求,ImageHelper
班级:
public class ImageHelper {
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
final Rect topRightRect = new Rect(bitmap.getWidth()/2, 0, bitmap.getWidth(), bitmap.getHeight()/2);
final Rect bottomRect = new Rect(0, bitmap.getHeight()/2, bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
// Fill in upper right corner
canvas.drawRect(topRightRect, paint);
// Fill in bottom corners
canvas.drawRect(bottomRect, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
答案 0 :(得分:3)
据我所知,只有当android尝试呈现一个设置了位图对象的视图并且在渲染过程中如果android发现之前设置的位图对象已经被回收然后发生此异常时,才会出现此问题(在api升级之后,位图因某些奇怪或熟悉的原因而被回收!!!)
(考虑到你没有在任何地方调用过bitmap.recycle())
我试图修复的方式是:
首次尝试:
相应地调整onPostExecute:
protected void onPostExecute(Bitmap bmp) {
if (mContext != null) {
if (bmp != null) {
userIcon.setImageBitmap(ImageHelper.getRoundedCornerBitmap(
bmp, 50));
}
}
}
第二次尝试:
protected void onPostExecute(Void v) {
if (mContext != null) {
if (b != null) {
Bitmap roundedbmp = ImageHelper.getRoundedCornerBitmap(
b, 50);
}
}
}
仅检查此项以确保位图回收问题不是源自ImageHelper.getRoundedCornerBitmap(b,50)此代码。
protected void onPostExecute(Void v) {
if (mContext != null) {
if (b != null) {
Bitmap roundedbmp = ImageHelper.getRoundedCornerBitmap(
b, 50);
if(roundedbmp!=null){
userIcon.setImageBitmap(roundedbmp);
}
}
}
}
我试图提出的解决方案纯粹基于假设和我过去的经验,所以不要误会我的意思。正如你所看到的那样,第二个解决方案根本没有意义,但它可能与视图有关,也可能没有。另一方面,在Bitmap对象引用方面,第一个解决方案对我来说有点意义。在位图处理过程中我可以理解这个对象正在被回收,基于这个事实,我尝试了两种方法。 希望这对你有所帮助。
答案 1 :(得分:1)
我会猜测......
在OnCreate中,您以布局mgr的方式引用抽屉的布局组件。 inflater不知道您的任务中固有的异步延迟,因此它在不知道异步任务尚未完成的情况下继续进行。
问题可能是您在onCreate()中构建的视图需要能够在任务完成之前将某些内容放在一起。任务完成后,它需要更改View资源的状态,并表示应刷新某些视图组件。例如,代表圆形位图的资源中的虚拟bmp很快就会出现在网络上的异步检索中。
我不知道为什么你不会在&lt; 4.4。
我认为您的问题与方向更改无关。
this code可能会进一步澄清由于asnyc导致滞后的一些问题。可能根本不相关。
答案 2 :(得分:0)
检查你是否在任何地方使用bitmap_image.recycle()?然后将其评论出来并检查它是否有效。我遇到了类似的问题并修复了它。