![](/img/trans.png)
[英]Java Why am I getting a NullPointerException while instantiating my array
[英]Why am I getting this NullPointerException while trying to assign images to my GridView?
我有一个 GridView 应用与 object 实例相关的不同图像。 我正在使用 RealPathUtil object 来处理文件路径的检索以解码和显示位图。
当我打开将这些图像分配给网格的活动时,我的应用程序会自动崩溃并显示一个 NullPointerException,指向声明此 if 子句的行:
else if ("content".equals(uri.scheme!!, ignoreCase = true)) {
// Return the remote address
return if (isGooglePhotosUri(uri)) uri.lastPathSegment else getDataColumn(context, uri, null, null)
}
我熟悉 NullPointerExceptions 以及它们通常被抛出的原因,但我真的不明白为什么会给出这个。 由于我将图像显示方法从 URI 切换到 Bitmap,因此我尝试分配的图像都没有正确显示。 当我使用 URI 将图像分配给 ImageViews 时,没有出现这个问题,但我不得不切换,因为这会在其他设备上产生问题。
这是处理 GridView 的适配器的代码,它导致出现此错误。 从 tempUri 的值设置到末尾时发生错误:
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val view: View = View.inflate(activity,R.layout.layout_adapter,null)
// Get view data from UI elements - image, name, and count
val tv_lang = view.findViewById(R.id.itemName) as TextView
val imageView = view.findViewById<ImageView>(R.id.itemImage)
val itemCount = view.findViewById(R.id.itemCount) as TextView
// Assign data to UI elements
tv_lang.text = itemList[position].itemNote
itemCount.text = itemList[position].itemCount.toString()
val itemImage = itemList[position].itemImage
// Assign each item image to corresponding grid ImageView
tempUri = Uri.parse(itemImage)
realPathUri = RealPathUtil.getRealPath(parent!!.context, tempUri).toString()
val myBitmap = BitmapFactory.decodeFile(realPathUri)
imageView.setImageBitmap(myBitmap)
return view
}
RealPathUtil
object RealPathUtil {
// SDK <= 11 && SDK < 19
/* Calls either getRealPathFromURIAPI11to19 or getRealPathFromURIAPI19, depending upon which API the software detects the user running the app through. */
@SuppressLint("ObsoleteSdkInt")
fun getRealPath(context: Context, fileUri: Uri): String? {
return if (Build.VERSION.SDK_INT < 19) {
getRealPathFromURIAPI11to18(context, fileUri)
} else {
getRealPathFromURIAPI19(context, fileUri)
}
}
/* Uses other methods within the RealPathUtil object to determine
* location list file path based upon the user's phone's active API (11-18). */
@SuppressLint("NewApi")
fun getRealPathFromURIAPI11to18(context: Context, contentUri: Uri): String? {
val project = arrayOf(MediaStore.Images.Media.DATA)
var result: String? = ""
val cursorLoader = CursorLoader(context, contentUri, project, null, null, null)
val cursor = cursorLoader.loadInBackground()
if (cursor != null) {
val columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
cursor.moveToFirst()
result = cursor.getString(columnIndex)
cursor.close()
}
return result
}
/* Uses other methods within the RealPathUtil object to determine location list file
path based upon the user's phone's active API (19). */
@SuppressLint("NewApi")
fun getRealPathFromURIAPI19(context: Context, uri: Uri): String? {
val isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
// Create the DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// Safe cast the ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val type = split[0]
if ("primary".equals(type, ignoreCase = true)) {
return Environment.getExternalStorageDirectory().toString() + "/" + split[1]
}
} else if (isDownloadsDocument(uri)) {
var cursor: Cursor? = null
try {
cursor = context.contentResolver.query(uri, arrayOf(MediaStore.MediaColumns.DISPLAY_NAME), null, null, null)
cursor!!.moveToNext()
val fileName = cursor.getString(0)
val path = Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName
if (!TextUtils.isEmpty(path)) {
return path
}
} finally {
cursor?.close()
}
val id = DocumentsContract.getDocumentId(uri)
if (id.startsWith("raw:")) {
return id.replaceFirst("raw:".toRegex(), "")
}
val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads"), java.lang.Long.valueOf(id))
return getDataColumn(context, contentUri, null, null)
} else if (isMediaDocument(uri)) {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val type = split[0]
var contentUri: Uri? = null
when (type) {
"image" -> contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
"video" -> contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
"audio" -> contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
}
val selection = "_id=?"
val selectionArgs = arrayOf(split[1])
return getDataColumn(context, contentUri, selection, selectionArgs)
} // Media Provider
// Downloads Provider
} else if ("content".equals(uri.scheme!!, ignoreCase = true)) {
// Return the remote address
return if (isGooglePhotosUri(uri))
uri.lastPathSegment
else
getDataColumn(context, uri, null, null) /** Collapse this if-else block into one line if any new, unexplained I/O issues arise. */
} else if ("file".equals(uri.scheme!!, ignoreCase = true)) {
return uri.path
} // File
// MediaStore
return null
}
private fun getDataColumn(context: Context, uri: Uri?, selection: String?, selectionArgs: Array<String>?): String? {
var cursor: Cursor? = null
val column = "_data"
val projection = arrayOf(column)
try {
cursor = context.contentResolver.query(uri!!, projection, selection, selectionArgs, null)
if (cursor != null && cursor.moveToFirst()) {
val index = cursor.getColumnIndexOrThrow(column)
return cursor.getString(index)
}
} finally {
cursor?.close()
}
return null
}
/* Takes the URI being analyzed and determines whether the URI authority is ExternalFileProvider or not. */
private fun isExternalStorageDocument(uri: Uri): Boolean {
return "com.android.externalstorage.documents" == uri.authority
}
/* Takes the URI being analyzed and determines whether the URI authority is DownloadsProvider or not. */
private fun isDownloadsDocument(uri: Uri): Boolean {
return "com.android.providers.downloads.documents" == uri.authority
}
/* Takes the URI being analyzed and determines whether the URI authority is MediaProvider or not. */
private fun isMediaDocument(uri: Uri): Boolean {
return "com.android.providers.media.documents" == uri.authority
}
/* Takes the URI being analyzed and determines whether the URI authority is Google Photos or not. */
private fun isGooglePhotosUri(uri: Uri): Boolean {
return "com.google.android.apps.photos.content" == uri.authority
}
}
我知道这与如何检索路径有关,但我真的不知道如何。 我已经使用这个 object 很长时间了,我从来没有遇到过这样的问题,所以我真的不知道从哪里开始调试。 我并不是要解决我的问题,但如果某个比我更有经验的精明人士可以告诉我这个问题来自哪里,我也许能够弄清楚。 再次感谢!
假设您所指的if
子句是这个:
else if ("content".equals(uri.scheme,!, ignoreCase = true)) {
NullPointerException 的明显位置是uri.scheme!!
. 双键运算符用于断言具有可空类型的变量实际上不是null
,并检索其值。 当我们作为人类比编译器知道的更多时,这有时很有用......但人类也有可能是错误的!
如果uri.scheme
是null,那么uri.scheme!!
将抛出 NullPointerException。
如何解决这个取决于你程序的 rest。 也许您不希望uri.scheme
永远是 null,在这种情况下,您需要找出更深层次的根本原因。 但是,如果您确实希望uri.scheme
有时可能是 null,您可以重写您的if
条件:
else if (uri.scheme?.equals("content", ignoreCase = true) == true) {
使用 String.equals 时不需要检查 Null。 检查代码
public actual fun String?.equals(other: String?, ignoreCase: Boolean = false): Boolean {
if (this === null)
return other === null
return if (!ignoreCase) (this as java.lang.String).equals(other)
else (this as java.lang.String).equalsIgnoreCase(other)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.