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

Java转Kotlin后调用SPUtil.putString触发空指针异常求助

问题排查:SPUtil调用时触发NullPointerException异常

原始Java代码

findViewById(R.id.registerButton).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                User user = new User(
                        idText.getText().toString(),
                        passwordText.getText().toString(),
                        emailText.getText().toString(),
                        sex,
                        organization);
                Gson gson = new Gson();
                String json = gson.toJson(user);
                SPUtil.putString(idText.getText().toString(), json);
                finish();
            }
        });

改写后的Kotlin代码

binding.registerButton.setOnClickListener {

            // spinner

            val genderGroup = findViewById<RadioGroup>(R.id.genderGroup)
            val genderGroupID = genderGroup.checkedRadioButtonId
            sex = findViewById<RadioButton>(genderGroupID).text.toString()
            val organization = spinner.selectedItem.toString()

            println("run this")

            var isGoToJoin = true

            val email = binding.idText.text.toString()
            val password1 = binding.passwordText.text.toString()
            val password2 = binding.passwordText2.text.toString()
            val sex = sex

//            println(email)
//            println(password1)
//            println(sex)
//            println(organization)


            // user 여기가 도저히 안된당
            val idText = email
            val passwordText = password1

            val user = User(
                idText,
                passwordText,
                sex,
                organization
            )

            val gson = Gson()
            val json = gson.toJson(user)

            println(json)
            SPUtil.putString(idText, json)

期望解析存储数据的代码

val user = Gson().fromJson(
            intent.getStringExtra("id"),
            User::class.java // User추가
        )
        println("homescreen")
        println(user)
        if (user!=null){
            findViewById<TextView>(R.id.user_id).text = user.id
            findViewById<TextView>(R.id.sex_id).text = user.sex
            findViewById<TextView>(R.id.organization_id).text = user.organization
            println(user)
        }

异常信息

FATAL EXCEPTION: main
Process: com.example.schoolboard, PID: 9955
java.lang.ExceptionInInitializerError
at com.example.schoolboard.utils.SPUtil.getInstance(SPUtil.java:25)
at com.example.schoolboard.utils.SPUtil.putString(SPUtil.java:33)
at com.example.schoolboard.auth.JoinActivity.onCreate$lambda$2(JoinActivity.kt:127)
at com.example.schoolboard.auth.JoinActivity.$r8$lambda$DLVZYaVRDjPwwdYMhAYrW_DySaA(Unknown Source:0)
at com.example.schoolboard.auth.JoinActivity$$ExternalSyntheticLambda0.onClick(Unknown Source:4)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.preference.PreferenceManager.getDefaultSharedPreferencesName(PreferenceManager.java:537)
at android.preference.PreferenceManager.getDefaultSharedPreferences(PreferenceManager.java:526)
at com.example.schoolboard.utils.SPUtil.<init>(SPUtil.java:17)
at com.example.schoolboard.utils.SPUtil$SingletonHolder.<init>(SPUtil.java:21)
at com.example.schoolboard.utils.SPUtil.getInstance(SPUtil.java:25) 
at com.example.schoolboard.utils.SPUtil.putString(SPUtil.java:33) 
at com.example.schoolboard.auth.JoinActivity.onCreate$lambda$2(JoinActivity.kt:127) 
at com.example.schoolboard.auth.JoinActivity.$r8$lambda$DLVZYaVRDjPwwdYMhAYrW_DySaA(Unknown Source:0) 
at com.example.schoolboard.auth.JoinActivity$$ExternalSyntheticLambda0.onClick(Unknown Source:4) 
at android.view.View.performClick(View.java:6256) 
at android.view.View$PerformClick.run(View.java:24701) 
at android.os.Handler.handleCallback(Handler.java:789) 
at android.os.Handler.dispatchMessage(Handler.java:98) 
at android.os.Looper.loop(Looper.java:164) 
at android.app.ActivityThread.main(ActivityThread.java:6541) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 

问题分析与解决方案

从异常栈可以明确,问题根源是SPUtil初始化时调用PreferenceManager.getDefaultSharedPreferences()传入的Context为null,导致触发空指针异常。

核心修复步骤:

  1. 修正SPUtil的单例初始化逻辑
    确保SPUtil在获取单例时接收有效的Context,并使用Application Context避免内存泄漏:

    public class SPUtil {
        private static SPUtil instance;
        private SharedPreferences sp;
    
        private SPUtil(Context context) {
            // 使用Application Context确保生命周期安全
            sp = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
        }
    
        public static synchronized SPUtil getInstance(Context context) {
            if (instance == null) {
                instance = new SPUtil(context);
            }
            return instance;
        }
    
        public void putString(String key, String value) {
            sp.edit().putString(key, value).apply();
        }
    
        // 新增getString方法用于后续解析
        public String getString(String key, String defaultValue) {
            return sp.getString(key, defaultValue);
        }
    }
    
  2. 修改Kotlin中SPUtil的调用方式
    在注册按钮的点击事件中,传入当前Activity的Context获取SPUtil实例:

    // 替换原有的SPUtil.putString(idText, json)
    SPUtil.getInstance(this).putString(idText, json)
    // 存储完成后记得调用finish()回到首页
    finish()
    
  3. 修正首页的用户数据解析逻辑
    原代码直接用intent传参解析是错误的,需要从SP中取出对应key的JSON字符串再解析:

    val userId = intent.getStringExtra("id")
    val userJson = SPUtil.getInstance(this).getString(userId, null)
    val user = Gson().fromJson(userJson, User::class.java)
    
    println("homescreen")
    println(user)
    if (user != null){
        findViewById<TextView>(R.id.user_id).text = user.id
        findViewById<TextView>(R.id.sex_id).text = user.sex
        findViewById<TextView>(R.id.organization_id).text = user.organization
        println(user)
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:10:17