尝试调用虚拟方法 'android.content.SharedPreferences android.content.Context.getSharedPreferences [英] Attempt to invoke virtual method 'android.content.SharedPreferences android.content.Context.getSharedPreferences
问题描述
我正在尝试使用 SharedPreferences 将我从 Json URL 获得的 Json 对象保存到收藏夹列表,但是每次当我尝试保存 Json Array 时应用程序崩溃并出现下一个错误:
I'm trying to save Json object which I got from Json URL to favorite list using SharedPreferences but The app crashes every time when I try to save Json Array with next error:
06-27 18:36:03.224 933-933/? E/EGL_emulation﹕ tid 933: eglCreateSyncKHR(1237): error 0x3004 (EGL_BAD_ATTRIBUTE)
06-27 18:36:27.496 2778-2778/? E/memtrack﹕ Couldn't load memtrack module (No such file or directory)
06-27 18:36:27.496 2778-2778/? E/android.os.Debug﹕ failed to load memtrack module: -2
06-27 18:36:27.943 2793-2793/? E/memtrack﹕ Couldn't load memtrack module (No such file or directory)
06-27 18:36:27.943 2793-2793/? E/android.os.Debug﹕ failed to load memtrack module: -2
06-27 18:36:53.230 2807-2807/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.boom.kayakapp, PID: 2807
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 com.boom.kayakapp.util.SharedPreference.getFavorites(SharedPreference.java:60)
at com.boom.kayakapp.util.SharedPreference.addFavorite(SharedPreference.java:41)
at com.boom.kayakapp.activities.MainActivity$2.onItemLongClick(MainActivity.java:124)
at android.widget.AbsListView.performLongPress(AbsListView.java:3121)
at android.widget.AbsListView$CheckForLongPress.run(AbsListView.java:3070)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
06-27 18:36:53.264 933-933/? E/EGL_emulation﹕ tid 933: eglCreateSyncKHR(1237): error 0x3004 (EGL_BAD_ATTRIBUTE)
我如何理解错误意味着当我尝试将 Json 对象保存到共享首选项时,方法调用空对象引用,但我无法理解代码有什么问题...
How I could understand the error means that when I try to save Json object to shared preferences, method calls null object reference, but I can't understand what's wrong with code...
这是我的主要活动:
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.StrictMode;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.JsonArrayRequest;
import com.boom.kayakapp.R;
import com.boom.kayakapp.adapters.AirlinesAdapter;
import com.boom.kayakapp.controllers.AppController;
import com.boom.kayakapp.fragment.AirlinesFragment;
import com.boom.kayakapp.fragment.FavoriteFragment;
import com.boom.kayakapp.model.Airlines;
import com.boom.kayakapp.util.SharedPreference;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends ActionBarActivity {
private Fragment contentFragment;
AirlinesFragment airlinesFragment;
FavoriteFragment favoriteFragment;
// JSON Node names
public static final String TAG_NAME = "name";
public static final String TAG_PHONE = "phone";
public static final String TAG_SITE = "site";
public static final String TAG_LOGO = "logoURL";
public static final String TAG_CODE = "code";
// Log tag
private static final String TAG = MainActivity.class.getSimpleName();
// Airlines json url
private static final String url = "https://www.kayak.com/h/mobileapis/directory/airlines";
public ProgressDialog pDialog;
public List<Airlines> airlinesList = new ArrayList<Airlines>();
public ListView listView;
public AirlinesAdapter adapter;
Activity activity;
SharedPreference sharedPreference;
@Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
sharedPreference = new SharedPreference();
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
listView = (ListView) findViewById(R.id.list);
adapter = new AirlinesAdapter(this, airlinesList);
listView.setAdapter(adapter);
pDialog = new ProgressDialog(this);
// Showing progress dialog before making http request
pDialog.setMessage("Loading...");
pDialog.show();
// Listview on item click listener
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String name = ((TextView) view.findViewById(R.id.name))
.getText().toString();
String phone = ((TextView) view.findViewById(R.id.phone))
.getText().toString();
String site = ((TextView) view.findViewById(R.id.site))
.getText().toString();
String logoURL = String.valueOf(((ImageView) view.findViewById(R.id.logoURL)));
// Starting single contact activity
Intent in = new Intent(getApplicationContext(),
SingleContactActivity.class);
in.putExtra(TAG_NAME, name);
in.putExtra(TAG_PHONE, phone);
in.putExtra(TAG_SITE, site);
in.putExtra(TAG_LOGO, logoURL);
startActivity(in);
}
});
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
ImageView button = (ImageView) view.findViewById(R.id.favorite_button);
String tag = button.getTag().toString();
if (tag.equalsIgnoreCase("grey")) {
sharedPreference.addFavorite(activity, airlinesList.get(position));
Toast.makeText(activity,
activity.getResources().getString(R.string.add_favr),
Toast.LENGTH_SHORT).show();
button.setTag("red");
button.setImageResource(R.drawable.heart_red);
} else {
sharedPreference.removeFavorite(activity, airlinesList.get(position));
button.setTag("grey");
button.setImageResource(R.drawable.heart_grey);
Toast.makeText(activity,
activity.getResources().getString(R.string.remove_favr),
Toast.LENGTH_SHORT).show();
}
return true;
}
});
// changing action bar color
getSupportActionBar().setBackgroundDrawable(
new ColorDrawable(Color.parseColor("#1b1b1b")));
// Creating volley request obj
JsonArrayRequest airlinesReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Airlines airlines = new Airlines();
airlines.setName(obj.getString("name"));
airlines.setLogoURL(obj.getString("logoURL"));
airlines.setPhone(obj.getString("phone"));
airlines.setCode(obj.getInt("code"));
airlines.setSite(obj.getString("site"));
// adding airlines to array
airlinesList.add(airlines);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(airlinesReq);
FragmentManager fragmentManager = getSupportFragmentManager();
/*
* This is called when orientation is changed.
*/
if (savedInstanceState != null) {
if (savedInstanceState.containsKey("content")) {
String content = savedInstanceState.getString("content");
if (content.equals(FavoriteFragment.ARG_ITEM_ID)) {
if (fragmentManager.findFragmentByTag(FavoriteFragment.ARG_ITEM_ID) != null) {
setFragmentTitle(R.string.favorites);
contentFragment = fragmentManager
.findFragmentByTag(FavoriteFragment.ARG_ITEM_ID);
}
}
}
if (fragmentManager.findFragmentByTag(AirlinesFragment.ARG_ITEM_ID) != null) {
airlinesFragment = (AirlinesFragment) fragmentManager
.findFragmentByTag(AirlinesFragment.ARG_ITEM_ID);
contentFragment = airlinesFragment;
}
} else {
airlinesFragment = new AirlinesFragment();
switchContent(airlinesFragment, AirlinesFragment.ARG_ITEM_ID);
}
}
@Override
public void onDestroy () {
super.onDestroy();
hidePDialog();
}
private void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
if (contentFragment instanceof FavoriteFragment) {
outState.putString("content", FavoriteFragment.ARG_ITEM_ID);
} else {
outState.putString("content", AirlinesFragment.ARG_ITEM_ID);
}
super.onSaveInstanceState(outState);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_favorites:
setFragmentTitle(R.string.favorites);
favoriteFragment = new FavoriteFragment();
switchContent(favoriteFragment, FavoriteFragment.ARG_ITEM_ID);
return true;
}
return super.onOptionsItemSelected(item);
}
public void switchContent(Fragment fragment, String tag) {
FragmentManager fragmentManager = getSupportFragmentManager();
while (fragmentManager.popBackStackImmediate()) ;
if (fragment != null) {
FragmentTransaction transaction = fragmentManager
.beginTransaction();
transaction.replace(R.id.content_frame, fragment, tag);
//Only FavoriteFragment is added to the back stack.
if (!(fragment instanceof AirlinesFragment)) {
transaction.addToBackStack(tag);
}
transaction.commit();
contentFragment = fragment;
}
}
protected void setFragmentTitle(int resourseId) {
setTitle(resourseId);
getSupportActionBar().setTitle(resourseId);
}
/*
* We call super.onBackPressed(); when the stack entry count is > 0. if it
* is instanceof ProductListFragment or if the stack entry count is == 0, then
* we finish the activity.
* In other words, from ProductListFragment on back press it quits the app.
*/
@Override
public void onBackPressed() {
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
super.onBackPressed();
} else if (contentFragment instanceof AirlinesFragment
|| fm.getBackStackEntryCount() == 0) {
finish();
}
}
@Override
public void onResume() {
super.onResume();
}
}
这是我的 SharedPref:
This is my SharedPref:
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import com.boom.kayakapp.model.Airlines;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SharedPreference {
public static final String PREFS_NAME = "KAYAK_APP";
public static final String FAVORITES = "Airlines_Favorite";
public SharedPreference() {
super();
}
// This four methods are used for maintaining favorites.
public void saveFavorites(Context context, List<Airlines> favorites) {
// SharedPreferences settings;
// Editor editor;
SharedPreferences settings = context.getSharedPreferences(PREFS_NAME,
Context.MODE_PRIVATE);
Editor editor = settings.edit();
Gson gson = new Gson();
String jsonFavorites = gson.toJson(favorites);
editor.putString(FAVORITES, jsonFavorites);
editor.commit();
}
public void addFavorite(Context context, Airlines airlines) {
List<Airlines> favorites = getFavorites(context);
if (favorites == null)
favorites = new ArrayList<>();
favorites.add(airlines);
saveFavorites(context, favorites);
}
public void removeFavorite(Context context, Airlines airlines) {
ArrayList<Airlines> favorites = getFavorites(context);
if (favorites != null) {
favorites.remove(airlines);
saveFavorites(context, favorites);
}
}
public ArrayList<Airlines> getFavorites(Context context) {
SharedPreferences settings;
List<Airlines> favorites;
settings = context.getSharedPreferences(PREFS_NAME,
Context.MODE_PRIVATE);
if (settings.contains(FAVORITES)) {
String jsonFavorites = settings.getString(FAVORITES, null);
Gson gson = new Gson();
Airlines[] favoriteItems = gson.fromJson(jsonFavorites,
Airlines[].class);
favorites = Arrays.asList(favoriteItems);
favorites = new ArrayList<>(favorites);
} else
return null;
return (ArrayList<Airlines>) favorites;
}
}
推荐答案
你从来没有初始化你的成员变量 activity
,所以你最终为 传递了一个
到 null
值>ContextaddFavorite()
- 完全删除 activity
并使用 MainActivity.this
(这是对 您当前所在的活动
).
You never initialize your member variable activity
, so you end up passing a null
value for Context
to addFavorite()
- remove activity
entirely and use MainActivity.this
(which is a reference to the Activity
you are currently in).
这篇关于尝试调用虚拟方法 'android.content.SharedPreferences android.content.Context.getSharedPreferences的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!