【问题标题】:Null content Shared Preferences in KotlinKotlin 中的空内容共享首选项
【发布时间】:2020-06-03 12:59:55
【问题描述】:

我正在开发一个使用 Shared Preferences 的应用程序,因此我只为此创建了一个类,但是当我启动该应用程序时出现此错误:

2020-06-03 14:51:50.124 32656-32656/com.go.experimental E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.go.experimental, PID: 32656
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.go.experimental/com.go.experimental.AccesoActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.SharedPreferences android.content.Context.getSharedPreferences(java.lang.String, int)' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2914)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3119)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1839)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:201)
    at android.app.ActivityThread.main(ActivityThread.java:6864)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.SharedPreferences android.content.Context.getSharedPreferences(java.lang.String, int)' on a null object reference
    at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:184)
    at com.go.experimental.tools.Preferences.<init>(Preferences.kt:39)
    at com.go.experimental.AccesoActivity.<init>(AccesoActivity.kt:26)
    at java.lang.Class.newInstance(Native Method)
    at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69)
    at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
    at android.app.Instrumentation.newActivity(Instrumentation.java:1216)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2902)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3119) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1839) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:201) 
    at android.app.ActivityThread.main(ActivityThread.java:6864) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873) 

我不知道自己做错了什么,这是我的第一个 Kotlin 应用,所以希望你能帮我看看我的错误。

这是我的共享偏好类:

class Preferences(context: Context) {

  private val SHARED_PREFS = "GO_SHARED_PREFS"
  private val ID = "id"
  private val NAME = "name"
  private val PHONE = "phone"

  private var prefs = context.getSharedPreferences(SHARED_PREFS, 0)

  var id: Int
    get() = prefs!!.getInt(ID.toString(), 0)
    set(value) = prefs!!.edit().putInt(ID, value).apply()

  var name: String?
    get() = prefs!!.getString(NAME, "")
    set(value) = prefs!!.edit().putString(NAME, value).apply()

  var phone: Int
    get() = prefs!!.getInt(PHONE, 0)
    set(value) = prefs!!.edit().putInt(PHONE, value).apply()

这是我在我的活动中使用它的方式:

var prefs = Preferences(this@AccesoActivity)

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_acceso)

    tvTipoCodigo = findViewById(R.id.tv_tipo_acceso)
    tvNumeroTelefono = findViewById(R.id.tv_guest_number)
    tvCodigoNumerico = findViewById(R.id.tv_numeric_code)
    tvFecha = findViewById(R.id.et_activation_code)
    imCodigoQR = findViewById(R.id.iv_qr_code)

    codigoNumerico = generateNumericalNumber()

    saveCode()
}

private fun saveCode(){
    var name: String? = prefs.name
    var phone: Long? = prefs.phone
}

【问题讨论】:

  • 我建议您编辑您的问题以包含完整的堆栈跟踪和您使用 Preferences 的完整函数。
  • 我编辑了这个问题。 :)
  • OK...我们仍然可以使用堆栈跟踪。如果generateCode() 是您使用Preferences 的唯一地方,并且onCreate() 是您使用generateCode() 的唯一地方,那么您所拥有的似乎应该没问题。我希望(?)完整的堆栈跟踪会指出其他内容。
  • @CommonsWare 是的,这是我使用这两种方法的唯一地方。 onCreate()是Activity方法
  • @CommonsWare 我添加了堆栈跟踪的图像 AccesoActiviy = MainActivity

标签: android kotlin sharedpreferences


【解决方案1】:
var prefs = Preferences(this@AccesoActivity)

这是行不通的。在super.onCreate() 之后,切勿尝试使用Activity 对象,除非在非常特殊的情况下。

切换到:

lateinit var prefs: Preferences

并将其添加到onCreate() super.onCreate() 之后:

prefs = Preferences(this)

【讨论】:

    【解决方案2】:

    CommonsWare 完全正确。您也可以使用lazy 委托。它增加了一点开销,但至少从我的角度来看它更容易阅读

    val prefs by lazy { Preferences(this) }
    

    【讨论】:

      猜你喜欢
      • 2023-03-04
      • 1970-01-01
      • 2015-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      相关资源
      最近更新 更多