You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)
        }
    }
}

关键修改说明

  1. 初始化优化:将mPermissions初始化为空列表,避免后续空指针
  2. 空安全处理:在onCreate中对intent和savedInstanceState的返回值做非空判断,确保mPermissions始终不为null
  3. 权限过滤优化:使用更简洁的removeAll过滤已授权权限,同时过滤null权限元素
  4. 数组转换优化:将权限列表转换为非空数组,避免传递null给requestPermissions
  5. 结果处理优化:简化权限结果判断逻辑,同时处理空权限数组的情况

内容的提问来源于stack exchange,提问作者Pranay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 22:45:33