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,导致触发空指针异常。
核心修复步骤:
修正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); } }修改Kotlin中SPUtil的调用方式
在注册按钮的点击事件中,传入当前Activity的Context获取SPUtil实例:// 替换原有的SPUtil.putString(idText, json) SPUtil.getInstance(this).putString(idText, json) // 存储完成后记得调用finish()回到首页 finish()修正首页的用户数据解析逻辑
原代码直接用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
相关产品推荐
相关产品推荐

