【问题标题】:Android - Bitmap.CreateBitmap - null pointer exceptionAndroid - Bitmap.CreateBitmap - 空指针异常
【发布时间】:2015-12-11 08:57:09
【问题描述】:

有时当我尝试创建模糊位图时,我会收到“空指针异常”。

发生在这段代码中(我最近开始捕获异常,所以至少它不会使应用程序崩溃):

try
{
    using (Bitmap.Config config = Bitmap.Config.Rgb565) {
        return Bitmap.CreateBitmap (blurredBitmap, width, height, config);
    }
}
catch (Java.Lang.Exception exception)
{
    Util.Log(exception.ToString());
}

请参阅这些图片以了解有关我传递给“CreateBitmap”方法的参数的更多详细信息:

这里是扩展参数:

完全例外:

异常 {Java.Lang.NullPointerException: 异常类型 'Java.Lang.NullPointerException' 被抛出。在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000b] 在 /Users/builder/data/lanes/2058/58099c53/source/mono/mcs/class/corlib/System.Runtime.ExceptionServices/ExceptionDispatchInfo.cs:61 在 Android.Runtime.JNIEnv.CallStaticObjectMethod (IntPtr jclass, IntPtr jmethod, Android.Runtime.JValue* parms) [0x00064] in /Users/builder/data/lanes/2058/58099c53/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:1301 在 Android.Graphics.Bitmap.CreateBitmap (System.Int32[] 颜色,Int32 宽度,Int32 高度,Android.Graphics.Config 配置)[0x00088] 在 /Users/builder/data/lanes/2058/58099c53/source/monodroid/src/Mono.Android/platforms/android-22/src/generated/Android.Graphics.Bitmap.cs:735 在 Psonar.Apps.Droid.PayPerPlay.StackBlur.GetBlurredBitmap (Android.Graphics.Bitmap original, Int32 radius) [0x00375] in d:\Dev\psonar\Source\Psonar.Apps\Psonar.Apps.Droid\Psonar.Apps.Droid.PayPerPlay\Utilities\StackBlur.cs:123 --- 托管异常堆栈跟踪结束 --- java.lang.NullPointerException at android.graphics.Bitmap.createBitmap(Bitmap.java:687) 在 android.graphics.Bitmap.createBitmap(Bitmap.java:707) 在 dalvik.system.NativeStart.run(本机方法) } Java.Lang.NullPointerException

不确定这是否是 Xamarin 中的错误或传递的参数错误。

【问题讨论】:

    标签: c# android bitmap xamarin xamarin.android


    【解决方案1】:

    我收到了 Xamarin 团队的一位成员 Jonathan Pryor 的回复:

    NullPointerException 来自 Java 代码:

    在 android.graphics.Bitmap.createBitmap(Bitmap.java:687) 在 android.graphics.Bitmap.createBitmap(Bitmap.java:707) 在 dalvik.system.NativeStart.run(Native Method)

    快速浏览各种版本,Jelly Bean 可能适合:

    https://github.com/android/platform_frameworks_base/blob/jb-release/graphics/java/android/graphics/Bitmap.java#L687

        return nativeCreate(colors, offset, stride, width, height,
                            config.nativeInt, false);
    

    快速浏览一下周围的方法体表明config 不检查是否为空,所以如果 null 被传递,这将导致 在 NullPointerException 中。

    不过,问题是您没有传递 null:

    using (Bitmap.Config config = Bitmap.Config.Rgb565) {
        return Bitmap.CreateBitmap (blurredBitmap, width, height, config);
    }
    

    ...你是吗?

    我建议您删除 using 块:

    return Bitmap.CreateBitmap (blurredBitmap, width, height,
            Bitmap.Config.Rgb565);
    

    以下是我认为可能发生的情况,但首先,题外话:

    在 Xamarin.Android 的核心深处,存在 Java 之间的映射 对象及其对应的 C# 包装器对象。构造函数 调用、Java.Lang.Object.GetObject() 等将创建 映射; Java.lang.Object.Dispose() 将删除映射。

    其中一个核心部分是对象身份:当一个 Java 实例被 暴露给 C# 代码并创建一个 C# 包装器,same C# 包装器 应该继续为该 Java 实例重用实例。

    一个隐含的结果是 any 实例是有效的 全局,因为如果有多个代码路径/线程/等。获取相同 Java 实例的 JNI 句柄,它们将获得相同的 C# 包装器。

    这让我们回到了我的假设和您的代码块: Bitmap.Config 是一个 Java 枚举,这意味着每个成员都是一个 Java 对象。 此外,它们是全局值,因此每个线程都可以访问 这些成员,意味着 C# Bitmap.Config.Rgb565 实例是 实际上是一个全局变量。

    您正在 Dispose() 处理的全局变量。

    这是“好的”,因为下一个时间 Bitmap.Config.Rgb565 是 访问,将创建一个新的包装器。

    但问题是,如果您有多个线程访问 Bitmap.Config.Rgb565 在〜同时,每个都试图 实例的 Dispose()。在这一点上,这是完全合理的 这两个线程可以引用 same 包装器实例,并且 因此,来自一个线程的 Dispose() 将使所使用的实例无效 另一个线程。

    这将导致 null 被传递给 Bitmap.createBitmap() 调用,这正是您所观察到的。

    请尝试删除 using 块,看看是否有帮助。

    The whole thread is accessible here.

    然后我问:

    Jonathan Pryor - 为这个建议喝彩。我的问题是,如果我 去掉 using 语句,会不会引入内存泄漏?意义 如果我停止释放新的配置实例?

    他回答:

    这就是 GC 的用途!

    (在这里插入咳嗽和笑声。)

    我们可以吹毛求疵。我会争辩说这不是内存泄漏, 因为记忆根深蒂固,广为人知;不断访问 Bitmap.Config.Rgb565 将返回先前创建的实例, 不会不断地创建新实例。没有这样的“泄漏”。

    我会争辩说,实例和底层 GREF 是一个 “税”;它被“烧毁”了,是做生意成本的一部分。虽然它 将这些成本降至最低会“很好”,但移除这些成本是不切实际的 所有这些(例如,我们通过 .class_ref 为每个类“丢失”一个 GREF, 用于查找方法 ID...),至少不是当前的 架构。

    (我也想不出另一种架构会导致 不同的成本/“税收”。虽然我确实有一些关于允许的想法 某些方面有待改进的地方,它们并不大。)

    我建议不要担心 Bitmap.Config.Rgb565 和类似的东西 成员太多,除非/直到分析器或 GREF 计数显示 否则。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-29
      相关资源
      最近更新 更多