如何使用存储在 sharedPreference 中的字符串?

How to use a String stored in sharedPreference?

我在 class“PlayersActivity”中有这两个方法“saveCurrentPlayer”和“loadCurrentPlayer”来保存和加载字符串。

public void saveCurrentPlayer(){
        SharedPreferences preferences = getSharedPreferences("currentPlayer", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putString("currentPlayer",jugadorEliminar);
        editor.apply();
    }

    public String loadCurrentPlayer(){
        SharedPreferences preferences = getSharedPreferences("currentPlayer",Context.MODE_PRIVATE);
        String currentPlayer = preferences.getString("currentPlayer","");
        return currentPlayer;
    }

我尝试从另一个 class“QuestionAnswerManagerActivity”获取字符串“currentPlayer”,但我强制关闭。

Toast.makeText(QuestionAnswerManagerActivity.this,playersActivity.loadCurrentPlayer(),Toast.LENGTH_SHORT).show();

这里是logcat:

2021-06-29 19:00:25.584 12936-12936/? I/actual.pregres: type=1400 audit(0.0:9796): avc: denied { sendto } for path="/dev/socket/logdw" scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:init:s0 tclass=unix_dgram_socket permissive=1
2021-06-29 19:00:25.668 12936-12936/? I/zygote: Late-enabling -Xcheck:jni
2021-06-29 19:00:28.285 12936-12936/? W/zygote: Unexpected CPU variant for X86 using defaults: x86
2021-06-29 19:00:28.696 12936-12936/? I/JDWP: type=1400 audit(0.0:9801): avc: denied { connectto } for path=006A6477702D636F6E74726F6C scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:init:s0 tclass=unix_stream_socket permissive=1
2021-06-29 19:00:28.840 12936-12936/? I/JDWP: type=1400 audit(0.0:9802): avc: denied { read write } for path="socket:[145879]" dev="sockfs" ino=145879 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:init:s0 tclass=unix_stream_socket permissive=1
2021-06-29 19:00:31.308 12936-12936/? I/re-initialized>: type=1400 audit(0.0:9807): avc: denied { write } for path="socket:[145879]" dev="sockfs" ino=145879 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:init:s0 tclass=unix_stream_socket permissive=1
2021-06-29 19:00:34.828 12936-12936/com.doctoractual.pregresp I/com.doctoractual.pregresp: type=1400 audit(0.0:9828): avc: denied { write } for comm=45474C20496E6974 name="property_service" dev="tmpfs" ino=174 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:property_socket:s0 tclass=sock_file permissive=1
2021-06-29 19:00:34.844 12936-12936/com.doctoractual.pregresp I/com.doctoractual.pregresp: type=1400 audit(0.0:9830): avc: denied { connectto } for comm=45474C20496E6974 path="/dev/socket/property_service" scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:init:s0 tclass=unix_stream_socket permissive=1
2021-06-29 19:00:35.071 12936-12962/com.doctoractual.pregresp I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib/egl/libGLES_emulation.so from the current namespace instead.
2021-06-29 19:00:35.231 12936-12962/com.doctoractual.pregresp I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib/egl/libEGL_emulation.so from the current namespace instead.
2021-06-29 19:00:35.639 12936-12962/com.doctoractual.pregresp I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib/egl/libGLESv1_CM_emulation.so from the current namespace instead.
2021-06-29 19:00:35.672 12936-12962/com.doctoractual.pregresp I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib/egl/libGLESv2_emulation.so from the current namespace instead.
2021-06-29 19:00:36.080 12936-12936/com.doctoractual.pregresp I/actual.pregresp: type=1400 audit(0.0:9835): avc: denied { write } for name="BASE_DATOS" dev="sdb3" ino=81843 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:system_data_file:s0:c512,c768 tclass=file permissive=1
2021-06-29 19:00:36.080 12936-12936/com.doctoractual.pregresp I/actual.pregresp: type=1400 audit(0.0:9836): avc: denied { open } for path="/data/data/com.doctoractual.pregresp/databases/BASE_DATOS" dev="sdb3" ino=81843 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:system_data_file:s0:c512,c768 tclass=file permissive=1
2021-06-29 19:00:36.120 12936-12936/com.doctoractual.pregresp I/actual.pregresp: type=1400 audit(0.0:9837): avc: denied { lock } for path="/data/data/com.doctoractual.pregresp/databases/BASE_DATOS" dev="sdb3" ino=81843 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:system_data_file:s0:c512,c768 tclass=file permissive=1
2021-06-29 19:00:36.173 12936-12970/com.doctoractual.pregresp D/OpenGLRenderer: HWUI GL Pipeline
2021-06-29 19:00:36.222 12936-12947/com.doctoractual.pregresp I/zygote: Background concurrent copying GC freed 4602(981KB) AllocSpace objects, 0(0B) LOS objects, 66% free, 780KB/2MB, paused 8.318ms total 54.936ms
2021-06-29 19:00:36.492 12936-12936/com.doctoractual.pregresp I/RenderThread: type=1400 audit(0.0:9844): avc: denied { write } for name="local_opengl" dev="tmpfs" ino=14777 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:socket_device:s0 tclass=sock_file permissive=1
2021-06-29 19:00:36.643 12936-12970/com.doctoractual.pregresp I/OpenGLRenderer: Initialized EGL, version 1.4
2021-06-29 19:00:36.643 12936-12970/com.doctoractual.pregresp D/OpenGLRenderer: Swap behavior 1
2021-06-29 19:00:36.647 12936-12970/com.doctoractual.pregresp W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
2021-06-29 19:00:36.647 12936-12970/com.doctoractual.pregresp D/OpenGLRenderer: Swap behavior 0
2021-06-29 19:00:36.677 12936-12970/com.doctoractual.pregresp D/EGL_emulation: eglCreateContext: 0xe7a051e0: maj 3 min 1 rcv 4
2021-06-29 19:00:36.760 12936-12970/com.doctoractual.pregresp I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib/hw/gralloc.vbox86.so from the current namespace instead.
2021-06-29 19:00:36.778 12936-12970/com.doctoractual.pregresp E/eglCodecCommon: goldfish_dma_create_region: could not obtain fd to device! fd -1 errno=2
2021-06-29 19:00:37.177 12936-12936/com.doctoractual.pregresp I/Choreographer: Skipped 37 frames!  The application may be doing too much work on its main thread.
2021-06-29 19:00:38.704 12936-12936/com.doctoractual.pregresp I/actual.pregresp: type=1400 audit(0.0:9870): avc: denied { open } for path="/dev/__properties__/u:object_r:serialno_prop:s0" dev="tmpfs" ino=136 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:serialno_prop:s0 tclass=file permissive=1
2021-06-29 19:00:38.704 12936-12936/com.doctoractual.pregresp I/actual.pregresp: type=1400 audit(0.0:9871): avc: denied { getattr } for path="/dev/__properties__/u:object_r:serialno_prop:s0" dev="tmpfs" ino=136 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:serialno_prop:s0 tclass=file permissive=1
2021-06-29 19:00:41.640 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/os/PowerManager
2021-06-29 19:00:41.642 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/app/IntentService
2021-06-29 19:00:41.643 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/os/PowerManager$WakeLock
2021-06-29 19:00:41.649 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/app/Instrumentation
2021-06-29 19:00:41.650 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/app/JobSchedulerImpl
2021-06-29 19:00:41.651 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/app/job/JobServiceEngine$JobHandler
2021-06-29 19:00:41.663 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/app/ActivityThread
2021-06-29 19:00:41.666 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/os/Debug
2021-06-29 19:00:41.667 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/app/AlarmManager
2021-06-29 19:00:41.668 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/app/job/JobService
2021-06-29 19:00:41.669 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/app/PendingIntent
2021-06-29 19:00:41.673 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/location/LocationManager
2021-06-29 19:00:41.675 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: java/net/URL
2021-06-29 19:00:41.684 12936-12936/com.doctoractual.pregresp W/com.doctoractual.pregresp: Current dex file has more than one class in it. Calling RetransformClasses on this class might fail if no transformations are applied to it!
2021-06-29 19:00:41.687 12936-12936/com.doctoractual.pregresp I/chatty: uid=10071(u0_a71) com.doctoractual.pregresp identical 11 lines
2021-06-29 19:00:41.688 12936-12936/com.doctoractual.pregresp W/com.doctoractual.pregresp: Current dex file has more than one class in it. Calling RetransformClasses on this class might fail if no transformations are applied to it!
2021-06-29 19:00:42.597 12936-12936/com.doctoractual.pregresp W/zygote: Verification of void android.app.ActivityThread.handleStopBinderTrackingAndDump(android.os.ParcelFileDescriptor) took 108.552ms
2021-06-29 19:00:42.911 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/app/AlarmManager$ListenerWrapper
2021-06-29 19:00:42.912 12936-12936/com.doctoractual.pregresp W/com.doctoractual.pregresp: Changing class Landroid/app/AlarmManager$ListenerWrapper;
2021-06-29 19:00:42.914 12936-12936/com.doctoractual.pregresp W/com.doctoractual.pregresp: Dex file created by class-definition time transformation of Landroid/app/AlarmManager$ListenerWrapper; is not checked for all retransformation invariants.
2021-06-29 19:00:43.072 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/app/AlarmManager$ListenerWrapper
2021-06-29 19:00:43.074 12936-12936/com.doctoractual.pregresp W/zygote: Verification of void android.app.AlarmManager.setImpl(int, long, long, long, int, android.app.PendingIntent, android.app.AlarmManager$OnAlarmListener, java.lang.String, android.os.Handler, android.os.WorkSource, android.app.AlarmManager$AlarmClockInfo) took 321.983ms
2021-06-29 19:00:43.118 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Transformed class: android/location/LocationManager$ListenerTransport
2021-06-29 19:00:43.119 12936-12936/com.doctoractual.pregresp W/com.doctoractual.pregresp: Current dex file has more than one class in it. Calling RetransformClasses on this class might fail if no transformations are applied to it!
2021-06-29 19:00:43.202 12936-12936/com.doctoractual.pregresp W/zygote: Verification of void android.location.LocationManager.requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper, android.app.PendingIntent) took 123.589ms
2021-06-29 19:00:43.234 12936-12936/com.doctoractual.pregresp V/StudioProfiler: Profiler initialization complete on agent.
2021-06-29 19:00:43.250 12936-13005/com.doctoractual.pregresp V/StudioProfiler: Acquiring Application for Events
2021-06-29 19:00:43.535 12936-12941/com.doctoractual.pregresp I/zygote: Do partial code cache collection, code=29KB, data=26KB
2021-06-29 19:00:43.536 12936-12941/com.doctoractual.pregresp I/zygote: After code cache collection, code=29KB, data=26KB
2021-06-29 19:00:43.536 12936-12941/com.doctoractual.pregresp I/zygote: Increasing code cache capacity to 128KB
2021-06-29 19:00:45.193 12936-12941/com.doctoractual.pregresp I/zygote: Do partial code cache collection, code=45KB, data=44KB
2021-06-29 19:00:45.195 12936-12941/com.doctoractual.pregresp I/zygote: After code cache collection, code=45KB, data=44KB
2021-06-29 19:00:45.205 12936-12941/com.doctoractual.pregresp I/zygote: Increasing code cache capacity to 256KB
2021-06-29 19:00:45.238 12936-12941/com.doctoractual.pregresp I/zygote: JIT allocated 71KB for compiled code of void android.widget.TextView.<init>(android.content.Context, android.util.AttributeSet, int, int)
2021-06-29 19:00:45.238 12936-12941/com.doctoractual.pregresp I/zygote: Compiler allocated 4MB to compile void android.widget.TextView.<init>(android.content.Context, android.util.AttributeSet, int, int)
2021-06-29 19:00:45.582 12936-12941/com.doctoractual.pregresp I/zygote: Do full code cache collection, code=124KB, data=66KB
2021-06-29 19:00:45.588 12936-12941/com.doctoractual.pregresp I/zygote: After code cache collection, code=107KB, data=42KB
2021-06-29 19:00:50.239 12936-12941/com.doctoractual.pregresp I/zygote: Do partial code cache collection, code=124KB, data=76KB
2021-06-29 19:00:50.236 12936-12936/com.doctoractual.pregresp I/com.doctoractual.pregresp: type=1400 audit(0.0:9879): avc: denied { sendto } for comm=4A69742074687265616420706F6F6C path="/dev/socket/logdw" scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:init:s0 tclass=unix_dgram_socket permissive=1
2021-06-29 19:00:50.250 12936-12941/com.doctoractual.pregresp I/zygote: After code cache collection, code=124KB, data=76KB
2021-06-29 19:00:50.250 12936-12941/com.doctoractual.pregresp I/zygote: Increasing code cache capacity to 512KB
2021-06-29 19:00:50.340 12936-12936/com.doctoractual.pregresp I/Choreographer: Skipped 52 frames!  The application may be doing too much work on its main thread.
2021-06-29 19:00:50.733 12936-12941/com.doctoractual.pregresp I/zygote: JIT allocated 56KB for compiled code of void android.view.View.<init>(android.content.Context, android.util.AttributeSet, int, int)
2021-06-29 19:00:50.932 12936-12941/com.doctoractual.pregresp I/zygote: Do full code cache collection, code=244KB, data=143KB
2021-06-29 19:00:50.933 12936-12941/com.doctoractual.pregresp I/zygote: After code cache collection, code=238KB, data=98KB
2021-06-29 19:00:52.121 12936-12941/com.doctoractual.pregresp I/zygote: Do partial code cache collection, code=243KB, data=108KB
2021-06-29 19:00:52.123 12936-12941/com.doctoractual.pregresp I/zygote: After code cache collection, code=243KB, data=108KB
2021-06-29 19:00:52.130 12936-12941/com.doctoractual.pregresp I/zygote: Increasing code cache capacity to 1024KB
2021-06-29 19:01:01.116 12936-12936/com.doctoractual.pregresp I/actual.pregresp: type=1400 audit(0.0:9884): avc: denied { read } for name="databases" dev="sdb3" ino=81729 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:system_data_file:s0:c512,c768 tclass=dir permissive=1
2021-06-29 19:01:01.116 12936-12936/com.doctoractual.pregresp I/actual.pregresp: type=1400 audit(0.0:9885): avc: denied { open } for path="/data/data/com.doctoractual.pregresp/databases" dev="sdb3" ino=81729 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:system_data_file:s0:c512,c768 tclass=dir permissive=1
2021-06-29 19:01:01.142 12936-12936/com.doctoractual.pregresp D/AndroidRuntime: Shutting down VM
2021-06-29 19:01:01.144 12936-12936/com.doctoractual.pregresp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.doctoractual.pregresp, PID: 12936
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.doctoractual.pregresp.PlayersActivity.loadCurrentPlayer()' on a null object reference
        at com.doctoractual.pregresp.QuestionAnswerManagerActivity.onClick(QuestionAnswerManagerActivity.java:216)
        at android.view.View.performClick(View.java:6256)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
        at android.view.View$PerformClick.run(View.java:24697)
        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)

但是直接写文字没有问题,一切正常。

Toast.makeText(QuestionAnswerManagerActivity.this,"Jugador Luis",Toast.LENGTH_SHORT).show();

有人能看出我做错了什么吗?提前致谢。

在你的两种方法中删除这一行,

SharedPreferences preferences = getSharedPreferences("currentPlayer", Context.MODE_PRIVATE);

将此添加到您的 MainActivity class(外部方法)

public static SharedPreferences preferences ;

现在将其添加到您的 MainActivity OnCreate 方法中:

preferences = getSharedPreferences("currentPlayer", Context.MODE_PRIVATE); 
 

这解决了我的问题...

依赖其他activity才能使用SharedPreferences。在这种情况下,当您尝试使用它时,playersActivitynull。这是一个非常糟糕的 Android 开发设计,因为你不需要 SharedPreferences 有任何依赖,它可以完全独立。

解决方案:3个选项

  1. 将您的 SharedPreferences 转化为 Static 方法。 (例如 playersActivity 中的 loadCurrentPlayer 应该是 Static

  2. 最佳实践:创建一个新的管理器class负责应用程序的整个SharedPreferences使用(例如SharedPreferenceManager).这个 class 是一个 Singleton Class,用 ApplicationContext 实例化,并且在 SharedPreferences 中具有与 CRUD 操作相关的所有方法,在你的例子中 saveCurrentPlayerloadCurrentPlayer。由于经理 class 是独立的,因此不应导致任何 Lifecycle 错误或 NullPointer 错误。

    由于附上示例代码会使我的答案变得混乱,我决定引用 someone else's code here, this will teach you how to implement it.

  3. 如果您懒得遵循#2:您可以使用已经为您完成此操作的库:Pixplicity/EasyPrefs.

    • Manager一样易于使用Class✅
    • 没有更多与 SharedPreferences 相关的错误 ✅
    • 您可以随时改造任何现有项目 ✅

如果您有任何问题,请告诉我。谢谢