图像存在,不为空,但我得到一个NullPointerException异常
简短的介绍
我目前正在使用的应用程序从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
- 如何用kotlin 1.1.0 kotlinx-coroutines-core lib的功能替换Anko的doAsync,uiThread?
- JobScheduler支持比Lolipop更旧的版本
- 我可以使用Kotlin在Android项目中整合和使用admob广告吗?
- Android随着日期时间的变化,但是又放了一次,Firebase只是返回过期的令牌
- 在条件符合的情况下更改可观察 – RxJava2
你确定崩溃是在相同的loadImage()
方法,而不是另一个? 在错误日志中,它表示崩溃在BitmapFactory.decodeReso…ystem(), R.drawable.logo)
,这看起来不一样。
另外,你有没有试图首先做一个重建? 我已经看到了AS 3.0 beta中的许多问题,通过这样做可以解决问题。
从文档 ,即使fis
为null,它不应该与这个错误崩溃,只是返回一个null
(重点是我的)。
将输入流解码为位图。 如果输入流为空,或者不能用于解码位图,则函数返回null。 流的位置将是编码数据读取后的位置。
只是放弃东西,你可以添加BitmapFactory
的import
语句吗? 应该import android.graphics.BitmapFactory
。
因为BitmapFactory.decodeStream(fis)
返回null
而函数被指定返回一个不可为空的对象,所以引发了特定的异常。 要么返回空值,要么定义一个适当的替换,如果它返回null
。
在后台Kotlin生成以下“java”代码:
Bitmap tmp = BitmapFactory.decodeStream(fis); Intrinsics.checkExpressionValueIsNotNull(tmp, "BitmapFactory.decodeStream(fis)"); return tmp;
异常的来源是Intrinsics.checkExpressionValueIsNotNull
调用。