Android权限申请遇NullPointerException:空数组长度获取异常
解决Android权限申请中的NullPointerException问题
问题场景
使用以下PermissionActivity代码实现Android权限申请功能时,运行触发致命异常:
java.lang.NullPointerException: Attempt to get length of null array
报错位置为PermissionActivity.kt的onCreate方法第42行。
原代码
import android.app.Activity import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle import android.util.Log import androidx.core.app.ActivityCompat import androidx.fragment.app.FragmentActivity import java.util.* class PermissionActivity : FragmentActivity() { private var mPermissions: ArrayList<String?>? = null override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) finish() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mPermissions = if (savedInstanceState != null) { savedInstanceState.getStringArrayList(PERMISSION_KEY) } else { ArrayList(Arrays.asList(*intent.getStringArrayExtra(PERMISSION_KEY))) } Log.i(TAG, "onCreate()") requestPermission() } private fun requestPermission() { val it = mPermissions?.iterator() if (it != null) { while (it.hasNext()) { if (ActivityCompat.checkSelfPermission( this, it.next()!! ) == PackageManager.PERMISSION_GRANTED ) { it.remove() } } } if (mPermissions?.isEmpty() == true) { // all allowed setResult(RESULT_OK) Log.i(TAG, "finished") finish() } else { var permissions: Array<String?>? = mPermissions?.size?.let { it1 -> arrayOfNulls( it1 ) } permissions = mPermissions?.toArray(permissions) if (permissions != null) { ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQ_TAG) } Log.i(TAG, "requestPermissions") } } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putStringArrayList(PERMISSION_KEY, mPermissions) } override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) Log.i(TAG, "onRequestPermissionsResult() requestCode = " + "requestCode") if (requestCode == PERMISSION_REQ_TAG) { if (permissions.isEmpty()) { Log.i(TAG, "onRequestPermissionsResult : permission is 0") return } for (p in grantResults) { if (p == PackageManager.PERMISSION_DENIED) { Log.i(TAG, "onRequestPermissionsResult : permission denied") finish() return } } setResult(RESULT_OK) finish() } } companion object { private val TAG = PermissionActivity::class.java.simpleName private const val PERMISSION_KEY = "permissions" private const val PERMISSION_REQ_TAG = 1 fun checkPermission(context: Context?, permissions: Array<String>): Boolean { for (permission in permissions) { if (context == null || ActivityCompat.checkSelfPermission( context, permission ) == PackageManager.PERMISSION_DENIED ) { Log.i(TAG, "checkPermission : PERMISSION_DENIED : " + "permission") return false } else { Log.i(TAG, "checkPermission : PERMISSION_GRANTED : " + "permission") } } return true } fun showPermissionPrompt( callingActivity: Activity, requestCode: Int, permissions: Array<String> ) { val intent = Intent(callingActivity, PermissionActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION) intent.putExtra(PERMISSION_KEY, permissions) callingActivity.startActivityForResult(intent, requestCode) } } }
报错日志
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.watch, PID: 32569 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.watch/com.example.watch.PermissionActivity}: java.lang.NullPointerException: Attempt to get length of null array at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3456) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3612) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2073) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:246) at android.app.ActivityThread.main(ActivityThread.java:7690) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995) Caused by: java.lang.NullPointerException: Attempt to get length of null array at com.example.watch.PermissionActivity.onCreate(PermissionActivity.kt:42) at android.app.Activity.performCreate(Activity.java:8033) at android.app.Activity.performCreate(Activity.java:8013) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3429) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3612) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2073) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:246) at android.app.ActivityThread.main(ActivityThread.java:7690) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995) I/Process: Sending signal. PID: 32569 SIG: 9
问题分析
报错根源是intent.getStringArrayExtra(PERMISSION_KEY)返回null时,使用*展开null数组触发NPE,因为Arrays.asList()无法处理null的可变参数。此外,savedInstanceState.getStringArrayList(PERMISSION_KEY)也可能返回null,导致mPermissions为null,后续迭代和数组转换操作都会引发空指针。
修改后的完整代码
import android.app.Activity import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle import android.util.Log import androidx.core.app.ActivityCompat import androidx.fragment.app.FragmentActivity import java.util.* class PermissionActivity : FragmentActivity() { // 初始化空列表,避免后续空指针 private var mPermissions: ArrayList<String?> = arrayListOf() override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) finish() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mPermissions = when { savedInstanceState != null -> { // 从savedInstanceState获取,为空则初始化空列表 savedInstanceState.getStringArrayList(PERMISSION_KEY) ?: arrayListOf() } else -> { // 从intent获取数组,为空则初始化空列表 val permissionArray = intent.getStringArrayExtra(PERMISSION_KEY) if (permissionArray != null) { ArrayList(Arrays.asList(*permissionArray)) } else { arrayListOf() } } } Log.i(TAG, "onCreate()") requestPermission() } private fun requestPermission() { // 过滤已授权的权限 mPermissions.removeAll { permission -> permission != null && ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED } if (mPermissions.isEmpty()) { // 所有权限已授权 setResult(RESULT_OK) Log.i(TAG, "finished") finish() } else { // 转换为非空数组(过滤null元素) val permissions = mPermissions.filterNotNull().toTypedArray() if (permissions.isNotEmpty()) { ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQ_TAG) } else { // 无有效权限需要申请,直接返回成功 setResult(RESULT_OK) finish() } Log.i(TAG, "requestPermissions") } } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putStringArrayList(PERMISSION_KEY, mPermissions) } override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) Log.i(TAG, "onRequestPermissionsResult() requestCode = $requestCode") if (requestCode == PERMISSION_REQ_TAG) { if (permissions.isEmpty()) { Log.i(TAG, "onRequestPermissionsResult : permission is 0") setResult(RESULT_OK) finish() return } // 检查是否有被拒绝的权限 val hasDenied = grantResults.any { it == PackageManager.PERMISSION_DENIED } if (hasDenied) { Log.i(TAG, "onRequestPermissionsResult : permission denied") finish() } else { setResult(RESULT_OK) finish() } } } companion object { private val TAG = PermissionActivity::class.java.simpleName private const val PERMISSION_KEY = "permissions" private const val PERMISSION_REQ_TAG = 1 fun checkPermission(context: Context?, permissions: Array<String>): Boolean { if (context == null) return false return permissions.all { ActivityCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED }.also { result -> permissions.forEach { permission -> val status = if (result) "PERMISSION_GRANTED" else "PERMISSION_DENIED" Log.i(TAG, "checkPermission : $status : $permission") } } } fun showPermissionPrompt( callingActivity: Activity, requestCode: Int, permissions: Array<String> ) { val intent = Intent(callingActivity, PermissionActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION) intent.putExtra(PERMISSION_KEY, permissions) callingActivity.startActivityForResult(intent, requestCode) } } }
关键修改说明
- 初始化优化:将
mPermissions初始化为空列表,避免后续空指针 - 空安全处理:在onCreate中对intent和savedInstanceState的返回值做非空判断,确保mPermissions始终不为null
- 权限过滤优化:使用更简洁的
removeAll过滤已授权权限,同时过滤null权限元素 - 数组转换优化:将权限列表转换为非空数组,避免传递null给
requestPermissions - 结果处理优化:简化权限结果判断逻辑,同时处理空权限数组的情况
内容的提问来源于stack exchange,提问作者Pranay
相关产品推荐
相关产品推荐

