在SharedPreferences中存储访问令牌会返回空对象引用错误。

huangapple go评论73阅读模式
英文:

Storing access token in SharedPreferences returns null object reference error

问题

I am trying to store the access token I recieve from my oAuth2 server after logging in, but when I try to store it I get an error "java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.dentdevils.helper.retrofit.oauth2.PreferenceClass.setToken(java.lang.String)' on a null object reference" and I'm unsure why.

Here are my classes:

PreferenceClass.java

package com.example.dentdevils.helper.retrofit.oauth2;

import android.content.Context;
import android.content.SharedPreferences;

public class PreferenceClass {

    public static final String PREFERENCE = "accessTokenPref";
    private SharedPreferences sharedPreferences;

    public PreferenceClass(Context context) {
        sharedPreferences = context.getSharedPreferences(PREFERENCE, Context.MODE_PRIVATE);
    }

    public String getToken() {
        String token = sharedPreferences.getString("token", "");
        return token;
    }

    public void setToken(String token) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString("token", token);
        editor.commit();
    }

    public void clearToken() {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.remove("token");
        editor.commit();
    }

}

MainActivity.java

package com.example.dentdevils;

import ...

public class MainActivity extends AppCompatActivity {

    ...

    private PreferenceClass preferenceClass;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        ...

        preferenceClass = new PreferenceClass(this);

        ...

        btnLogin.setOnClickListener(v -> getAccessToken());
    }

    public void getAccessToken() {
        progressDialog.show();
        AccessToken accessToken = new AccessToken();
        accessToken.setClient_id("client");
        accessToken.setClient_secret("client");
        accessToken.setGrant_type("client_credentials");

        OauthService oauthService = cOauthService.createService(OauthService.class, inputEmail.getText().toString(), inputPassword.getText().toString());
        Call<AccessTokenResponse> call = oauthService.fetchAccessToken(accessToken);
        call.enqueue(new Callback<AccessTokenResponse>() {
            @Override
            public void onResponse(Call<AccessTokenResponse> call, retrofit2.Response<AccessTokenResponse> response) {
                if (response.isSuccessful()) {
                    String a = response.body().getAccess_token();
                    preferenceClass.setToken(a);
                    progressDialog.dismiss();
                    Intent i = new Intent(getApplicationContext(), HomeActivity.class);
                    startActivity(i);
                } else {
                    progressDialog.dismiss();
                    Toast.makeText(MainActivity.this, "There was an error, please try again!", Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onFailure(Call<AccessTokenResponse> call, Throwable t) {
                Log.d("Error", t.getMessage());
            }
        });

    }

    ...
}

Is there anything blatantly obvious as to why this does not work and it does not store my access token in SharedPreferences? I know the access token gets returned as I can log it and it appears.

The full logcat output can be seen below:

2020-08-25 16:22:20.724 7197-7197/com.example.dentdevils E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.dentdevils, PID: 7197
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.dentdevils.helper.retrofit.oauth2.PreferenceClass.setToken(java.lang.String)' on a null object reference
at com.example.dentdevils.MainActivity$1.onResponse(MainActivity.java:76)
at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onResponse$0$DefaultCallAdapterFactory$ExecutorCallbackCall$1(DefaultCallAdapterFactory.java:89)
at retrofit2.-$$Lambda$DefaultCallAdapterFactory$ExecutorCallbackCall$1$3wC8FyV4pyjrzrYL5U0mlYiviZw.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:888)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:8178)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
英文:

I am trying to store the access token I recieve from my oAuth2 server after logging in, but when I try to store it I get an error java.lang.NullPointerException: Attempt to invoke virtual method &#39;void com.example.dentdevils.helper.retrofit.oauth2.PreferenceClass.setToken(java.lang.String)&#39; on a null object reference and I'm unsure why.

Here are my classes:
PreferenceClass.java

package com.example.dentdevils.helper.retrofit.oauth2;
import android.content.Context;
import android.content.SharedPreferences;
public class PreferenceClass {
public static final String PREFERENCE = &quot;accessTokenPref&quot;;
private SharedPreferences sharedPreferences;
public PreferenceClass(Context context) {
sharedPreferences = context.getSharedPreferences(PREFERENCE, Context.MODE_PRIVATE);
}
public String getToken() {
String token = sharedPreferences.getString(&quot;token&quot;, &quot;&quot;);
return token;
}
public void setToken(String token) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(&quot;token&quot;, token);
editor.commit();
}
public void clearToken() {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(&quot;token&quot;);
editor.commit();
}
}

MainActivity.Java

package com.example.dentdevils;
import android.Manifest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.dentdevils.helper.retrofit.oauth2.PreferenceClass;
import com.example.dentdevils.helper.retrofit.oauth2.client.cOauthService;
import com.example.dentdevils.helper.retrofit.oauth2.request.AccessToken;
import com.example.dentdevils.helper.retrofit.oauth2.response.AccessTokenResponse;
import com.example.dentdevils.helper.retrofit.oauth2.service.OauthService;
import com.example.dentdevils.ui.HomeActivity;
import retrofit2.Call;
import retrofit2.Callback;
public class MainActivity extends AppCompatActivity {
SharedPreferences sharedPreferences;
public static final String mypreference = &quot;mypref&quot;;
public static final String email = &quot;emailKey&quot;;
public static final String access = &quot;accessKey&quot;;
public static final int MY_PERMISSIONS_REQUEST_CAMERA = 99;
private static final String TAG = MainActivity.class.getSimpleName();
private Button btnLogin;
private EditText inputEmail;
private EditText inputPassword;
private ProgressDialog progressDialog;
private PreferenceClass preferenceClass;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
checkCameraPermission();
sharedPreferences = getSharedPreferences(mypreference,
Context.MODE_PRIVATE);
inputEmail = findViewById(R.id.email);
inputPassword = findViewById(R.id.txtEditPassword);
btnLogin = findViewById(R.id.btnLogin);
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
btnLogin.setOnClickListener(v -&gt; getAccessToken());
}
public void getAccessToken() {
progressDialog.show();
AccessToken accessToken = new AccessToken();
accessToken.setClient_id(&quot;client&quot;);
accessToken.setClient_secret(&quot;client&quot;);
accessToken.setGrant_type(&quot;client_credentials&quot;);
OauthService oauthService = cOauthService.createService(OauthService.class, inputEmail.getText().toString(), inputPassword.getText().toString());
Call&lt;AccessTokenResponse&gt; call = oauthService.fetchAccessToken(accessToken);
call.enqueue(new Callback&lt;AccessTokenResponse&gt;() {
@Override
public void onResponse(Call&lt;AccessTokenResponse&gt; call, retrofit2.Response&lt;AccessTokenResponse&gt; response) {
if (response.isSuccessful()) {
String a = response.body().getAccess_token();
preferenceClass.setToken(a);
progressDialog.dismiss();
Intent i = new Intent(getApplicationContext(), HomeActivity.class);
startActivity(i);
} else {
progressDialog.dismiss();
Toast.makeText(MainActivity.this, &quot;There was an error, please try again!&quot;, Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call&lt;AccessTokenResponse&gt; call, Throwable t) {
Log.d(&quot;Error&quot;, t.getMessage());
}
});
}
public boolean checkCameraPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
new AlertDialog.Builder(this)
.setTitle(&quot;Permission Required!&quot;)
.setMessage(&quot;This app requires the camera permission to be able to capture images of car damage. Please grant the app access to the camera by going into your Settings &gt; Apps &gt; Apps &gt; Dent Devils &gt; Permissions &gt; Camera, then press Allow.&quot;)
.setPositiveButton(&quot;&quot;, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, MY_PERMISSIONS_REQUEST_CAMERA);
}
})
.create()
.show();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, MY_PERMISSIONS_REQUEST_CAMERA);
}
return false;
} else {
return true;
}
}
}

Is there anything blatantly obvious as to why this does not work and it does not store my access token in SharedPreferences? I know the access token gets returned as I can log it and it appears.

The full logcat output can be seen below:

2020-08-25 16:22:20.724 7197-7197/com.example.dentdevils E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.dentdevils, PID: 7197
java.lang.NullPointerException: Attempt to invoke virtual method &#39;void com.example.dentdevils.helper.retrofit.oauth2.PreferenceClass.setToken(java.lang.String)&#39; on a null object reference
at com.example.dentdevils.MainActivity$1.onResponse(MainActivity.java:76)
at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onResponse$0$DefaultCallAdapterFactory$ExecutorCallbackCall$1(DefaultCallAdapterFactory.java:89)
at retrofit2.-$$Lambda$DefaultCallAdapterFactory$ExecutorCallbackCall$1$3wC8FyV4pyjrzrYL5U0mlYiviZw.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:888)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:8178)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)

答案1

得分: 0

MainActivity 中从未给 preferenceClass 赋值。

在你的 onCreate 中添加类似以下的代码:

preferenceClass = new PreferenceClass(this);
英文:

You never assign a value to preferenceClass in MainActivity.

Add something like this to your onCreate:

preferenceClass = new PreferenceClass(this);

huangapple
  • 本文由 发表于 2020年8月25日 23:23:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/63582104.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定