【问题标题】:Image exists, not null, but I get an NullPointerException on it图像存在,不为空,但我得到一个 NullPointerException
【发布时间】:2017-09-04 15:38:15
【问题描述】:

简介

我目前正在开发的应用程序从 JSON 中获取图像,如果正确,它将使用它并将其保存为下次使用时的加载图像。

问题

突然之间,应用程序在加载和进一步检查时开始崩溃,我进行的file.isFile && file.canRead() 检查返回正值,但它仍然在BitmapFactory.decodeStream 上崩溃。 该文件的字节数为 8k,与我使用的其他设备相比,同一张图像实际上有 43k 字节。

图像 json 是更大的 json 消息(大约 500kb)的一部分,它不在开头或结尾。在此之前的最后一次使用没有加载问题或显示下载可能已中途停止的迹象。即便如此,图像仍然有 8kb,所以我想它应该只用它拥有的部分创建一些东西,而不是抛出 NullPointerException

我使用的是 Android Studio 3.0 Beta 4,代码在 Kotlin 中。我必须在这台设备上运行它 100 次,即使发生这种情况,它在其他测试设备上运行得非常好,加上启动时获得完全相同 json 的 iOS 应用程序

我在寻找什么

有关如何处理该问题的建议,或有关它是否是 Android 或 Kotlin 中的已知错误的信息。我可能可以在设备上重新安装该应用程序,它会再次正常,但一旦应用程序发布,我不希望这种情况发生,如果我能阻止它。

LaterEdit:在 Xaviers 的建议下,我已将文件复制到桌面上,但它肯定是格式错误的,当它加载时,它实际上显示了在 Mac 上运行的一些严重格式错误的图像。我试图上传它,但它只是显示为一个空白图像。它仍然有 8kb,所以它包含一些数据。 这怎么可能?可以预防吗?

代码

加载应用程序,我检查图像是否存在并将其加载到 imageView

try {
     if (DesignSupport().imageExists("logo", this)) {
         if (DesignSupport().loadImage("logo", this) != null) {
             imageView.setImageBitmap(DesignSupport().loadImage("logo", this))
         }
     }
 } catch (error: Error) {
     Log.i(tag, error.stackTrace.toString())
 }

检查图片是否存在

fun imageExists(string: String, context: Context) : Boolean {
        val path = android.os.Environment.getExternalStorageDirectory().toString() + "/" + context.applicationInfo.name + "/" + string + ".png"
        val file = File(path)
        return (file.isFile && file.canRead())
    }

加载图片

    fun loadImage(string: String, context: Context) : Bitmap {
            val path = android.os.Environment.getExternalStorageDirectory().toString() + "/" + context.applicationInfo.name + "/" + string + ".png"
            val fis = FileInputStream(path)
// it crashes at the next line, but when I print fis.available() it returns 8200
            return BitmapFactory.decodeStream(fis)
        }

崩溃日志

 java.lang.RuntimeException: Unable to start activity ComponentInfo{.GeneralAccessScreens.startupScreen}: java.lang.IllegalStateException: BitmapFactory.decodeStream(fis) must not be null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2412)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2470)
at android.app.ActivityThread.access$900(ActivityThread.java:174)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: BitmapFactory.decodeStream(fis) must not be null
at SupportMethods.DesignSupport.loadImage(DesignSupport.kt:45)
at .GeneralAccessScreens.startupScreen.onCreate(startupScreen.kt:34)
at android.app.Activity.performCreate(Activity.java:5458)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)

导入语句

import android.app.Activity
import android.content.Context
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Base64
import android.util.Log
import android.view.inputmethod.InputMethodManager
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream

【问题讨论】:

    标签: android kotlin bitmapfactory


    【解决方案1】:

    抛出特定异常是因为BitmapFactory.decodeStream(fis) 返回null 而函数被指定返回一个不可为空的对象。如果返回 null,则将返回值设为可空或定义适当的替换。

    Kotlin 在后台生成以下“java”代码:

    Bitmap tmp = BitmapFactory.decodeStream(fis);
    Intrinsics.checkExpressionValueIsNotNull(tmp, "BitmapFactory.decodeStream(fis)");
    return tmp;
    

    异常的来源是Intrinsics.checkExpressionValueIsNotNull调用。

    【讨论】:

    • 但这就是问题所在,它不是 null 并且它通过了我对它是否为 null 所做的任何检查。解码时发生崩溃,尽管流不为空。
    • 解码后发生崩溃,检查函数返回值时产生特定异常,本例为BitmapFactory.decodeStream
    【解决方案2】:

    您确定崩溃是在同一个loadImage() 方法中,而不是在另一个方法中吗?在错误日志中它说崩溃发生在BitmapFactory.decodeReso…ystem(), R.drawable.logo),这似乎是一个不同的。

    另外,您是否尝试过先进行重建?我已经看到 AS 3.0 测试版中的许多问题都通过这样做得到解决。

    来自documentation,即使fis 为空,它也不应该因此错误而崩溃,只需返回null(重点是我的)。

    将输入流解码为位图。 如果输入流为空,或者不能用于解码位图,则函数返回空。流的位置将是读取编码数据后的位置。

    只是为了丢弃东西,您可以为BitmapFactory添加import语句吗?应该是import android.graphics.BitmapFactory

    【讨论】:

    • 谢谢,我刚刚意识到日志来自之前的崩溃,同时尝试了不同的解决方案,所以不是干净的,我已经更新了崩溃日志
    • @AlexIoja-Yang 我仍然看到相同的崩溃日志。
    • 并且重建没有做任何事情,我试图在不同的设备上运行它并且它没有任何问题,然后重新连接这个同样的东西。我想在某些时候它一定已经损坏了数据,但它仍然应该加载一个看起来很奇怪的图像
    • java.lang.IllegalStateException: BitmapFactory.decodeStream(fis) must not be null 这是顶行的区别,而不是 BitmapFactory.decodeResource(Resources.getSystem(), R.drawable。标识)。如果大小小于 x kb,那是一种替代方案,但后来我意识到我不应该只是通过设置任意限制来避免这个问题。
    • @AlexIoja-Yang 我认为你所说的似乎更合理的解释。这或某种文件损坏。我试图进入该方法,但是是本地的,所以那里没有运气。我会尝试将文件下载到您的计算机并在那里检查。
    猜你喜欢
    • 2023-01-07
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    • 2016-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    相关资源
    最近更新 更多