Хранение токена доступа в SharedPreferences возвращает ошибку ссылки на нулевой объект

#java #android #sharedpreferences

#java #Android #sharedpreferences

Вопрос:

Я пытаюсь сохранить токен доступа, который я получаю с моего сервера OAuth2 после входа в систему, но когда я пытаюсь сохранить его, я получаю ошибку 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 , и я не уверен, почему.

Вот мои классы: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 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 = "mypref";
    public static final String email = "emailKey";
    public static final String access = "accessKey";

    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 -> 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());
            }
        });

    }

    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("Permission Required!")
                        .setMessage("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 > Apps > Apps > Dent Devils > Permissions > Camera, then press Allow.")
                        .setPositiveButton("", 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;
        }
    }

}
  

Есть ли что-нибудь явно очевидное относительно того, почему это не работает, и он не сохраняет мой токен доступа в SharedPreferences? Я знаю, что токен доступа возвращается, поскольку я могу зарегистрировать его, и он появляется.

Полный вывод logcat можно увидеть ниже:

 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)
  

Ответ №1:

Вы никогда не присваиваете значение preferenceClass в MainActivity .

Добавьте что-то подобное в свой onCreate :

 preferenceClass = new PreferenceClass(this);