2017-02-19 1 views
-4

J'ai enregistré un objet (Account) dans SharedPreferences en utilisant gson, mais après avoir accédé à l'objet dans une nouvelle Activity, l'instance de l'objet (newAccount) provoque mon utilisation de newAccount.returnName() pour donner une exception NullPointerException. L'erreur est la suivante: Causée par: java.lang.NullPointerException: Tentative d'invocation de la méthode virtuelle 'java.lang.String com.cashtrack.kennethlee.cashtrack.Account.returnName()' sur une référence d'objet nul. Je comprends ce qu'est une erreur NullPointer, mais je ne vois pas pourquoi je pourrais l'obtenir depuis que je suis nouveau sur Android Studio. Le code pour la première activité est:Pourquoi est-ce que je reçois une exception NullPointerException après avoir accédé à un objet à partir de SharedPreferences?

package com.cashtrack.kennethlee.cashtrack; 

import android.content.Context; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.support.v4.view.MenuItemCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.widget.EditText; 
import android.widget.TextView; 

import com.google.gson.Gson; 
import com.google.gson.GsonBuilder; 

import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.util.ArrayList; 

public class CreateAccount extends AppCompatActivity { 

    SharedPreferences accountsPref; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_create_account); 
     setTitle("Create New Account"); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
     accountsPref = getPreferences(MODE_PRIVATE); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_create_account, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      //back button 
      case android.R.id.home: 
       // app icon in action bar clicked; go home 
       Intent intent = new Intent(this, MainScreen.class); 
       intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
       startActivity(intent); 
       return true; 

      //save button 
      case R.id.action_menu_save: 

       // get EditText by id 
       EditText inputTxt1 = (EditText) findViewById(R.id.AccountName); 
       // Store EditText in Variable 
       String name = inputTxt1.getText().toString(); 

       EditText inputTxt2 = (EditText) findViewById(R.id.StartingBalance); 
       double balance = Double.parseDouble(inputTxt2.getText().toString()); 

       Account newAccount = new Account(name, balance); 

       SharedPreferences.Editor editor = accountsPref.edit(); 
       Gson gson = new Gson(); 
       String json = gson.toJson(newAccount); 
       editor.putString("newAccount", json); 
       editor.commit(); 

       Intent intent2 = new Intent(this, MainScreen.class); 
       intent2.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
       startActivity(intent2); 
       return true; 
      default: 
       return super.onOptionsItemSelected(item); 
     } 
    } 
} 

Le code pour l'activité qui accède à l'objet et provoque l'erreur est:

package com.cashtrack.kennethlee.cashtrack; 

import android.content.Context; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.os.Bundle; 
import android.support.design.widget.FloatingActionButton; 
import android.support.design.widget.Snackbar; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.Toolbar; 
import android.view.View; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.widget.TextView; 

import com.google.gson.Gson; 

import java.io.FileInputStream; 
import java.io.StringWriter; 
import java.util.ArrayList; 

public class MainScreen extends AppCompatActivity { 
    //array list of accounts 
    ArrayList<Account> accounts = new ArrayList<>(); 

    SharedPreferences accountsPref; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main_screen); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       startActivity(new Intent(MainScreen.this, CreateAccount.class)); 
      } 
     }); 
     accountsPref = getPreferences(MODE_PRIVATE); 

     // PRINT TO A TEXT BOX 
     //setContentView(R.layout.activity_main_screen); 
     //TextView textView = (TextView) findViewById(R.id.textView4); 
     //textView.setText(hello.returnName()); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_main_screen, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 

     Gson gson = new Gson(); 
     String json = accountsPref.getString("newAccount", ""); 
     Account newAccount = gson.fromJson(json, Account.class); 
     accounts.add(newAccount); 


     setContentView(R.layout.activity_main_screen); 
     TextView textView1 = (TextView) findViewById(R.id.textView5); 
     textView1.setText(accounts.get(0).returnName()); 

     TextView textView2 = (TextView) findViewById(R.id.textView6); 
     textView2.setText(Double.toString(accounts.get(0).returnAvailableBalance())); 
    } 
} 

Répondre

0

Vous utilisez MODE_PRIVATE pour spécifier le nom de fichier pour stocker la valeur. La méthode recommandée est d'utiliser par le mode par défaut, sans spécifier le nom du fichier. Comme ceci:

valeur Put:

accountPref = PreferenceManager.getDefaultSharedPreferences(this); 
Gson gson = new Gson(); 
String json = gson.toJson(Account); 
accountPref.edit().putString("newAccount", json).apply(); 

Get Valeur:

SharedPreferences accountsPref = PreferenceManager.getDefaultSharedPreferences(this); 
if (accountsPref.contains("newAccount")) { 
    Gson gson = new Gson(); 
    String json = accountsPref.getString("newAccount", ""); 
    Account newAccount = gson.fromJson(json, Account.class); 
    accounts.add(newAccount); 
} 

espère que vous aimez ça. :)

+0

Après avoir obtenu la chaîne json (troisième ligne dans get value), comment puis-je obtenir l'objet lui-même? –

+0

Quel objet? N'avez-vous pas la valeur String que vous avez mise dans l'activité CreateAccount? Voulez-vous mettre une nouvelle valeur ou supprimer une valeur de cette SharedPreference particulière? – tahsinRupam

+0

Je veux être en mesure d'utiliser l'instance du compte de la classe appelée newAccount à partir de CreateAccount.J'ai un arraylist de compte dans MainScreen, et je veux ajouter un nouveau compte de CreateAccount dans cet arraylist. –

0

Je pense que vous devez initialiser votre classe de compte dans onCreate() .

Sans l'initialisation, il provoque une exception de pointeur nul.

Dans la classe Compte, vous avez créé un constructeur avec le paramètre Context?

+0

J'ai initialisé dans le cas parce que j'obtiens les variables de nom et d'équilibre pour l'objet dedans, donc je dois initialiser après avoir obtenu les deux variables. Je n'ai pas non plus de paramètre de contexte dans le constructeur de la classe de compte. Quel est le but de cela? –

0

Je pense que votre rencontrez ce problèmes parce que

getPreferences(int mode) 

retour un objet SharedPreferences pour l'activité en cours, de sorte que la chaîne « NewAccount » enregistré dans l'activité CreateAccount n'est pas récupéré dans l'activité MainScreen. Donc, lorsque vous utilisez Account newAccount = gson.fromJson(json, Account.class); newAccount est nul, car json est une chaîne vide.

Vous pouvez utiliser getSharedPreferences(String sharedPreferenceName, int mode) au lieu de getPreferences(int mode), en utilisant le même sharedPreferenceName lorsque vous appelez la méthode dans vos activités.

Désolé pour mon anglais. J'espère que c'est de l'aide.