2015-06-27 68 views
1

我試圖保存Json對象,我從Json URL使用SharedPreferences從收藏列表中獲取,但是每當我嘗試使用SharedPreferences時,應用程序崩潰保存JSON數組與下一個錯誤:嘗試調用虛擬方法'android.content.SharedPreferences android.content.Context.getSharedPreferences

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對象保存到共享偏好,方法調用空對象引用,但我不明白這有什麼錯碼。 ..

這是我的主要活動:

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:

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

回答

2

你從來沒有初始化的成員變量activity,所以你最終傳遞nullContextaddFavorite() - 刪除activity完全和使用MainActivity.this(這是一個參考您目前使用的Activity)。

+0

所以它應該是這樣的: sharedPreference.addFavorite(MainActivity.this,airlinesList.get(position)); Toast.makeText(MainActivity.this, 是不是? – Anton

相關問題