2015-01-14 17 views
5

Ho analizzato JSON correttamente, ma ora voglio memorizzarlo nella cache per l'utilizzo offline, anche Internet non è disponibile e, se è presente una nuova voce, desidero memorizzare anche quella.Come cache JSON analizzato per uso offline

E quale sarebbe l'opzione migliore per memorizzare i dati nella cache? SharedPreferences o SQLite database

Ecco il mio codice, che sto usando per analizzare JSON:

public class MainActivity extends Activity { 

    ArrayList<Actors> actorsList; 
    ActorAdapter adapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     actorsList = new ArrayList<Actors>(); 
     new JSONAsyncTask().execute("http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors"); 

     ListView listview = (ListView)findViewById(R.id.list); 
     adapter = new ActorAdapter(getApplicationContext(), R.layout.row, actorsList); 

     listview.setAdapter(adapter); 

     listview.setOnItemClickListener(new OnItemClickListener() { 

      @Override 
      public void onItemClick(AdapterView<?> arg0, View arg1, int position, 
        long id) { 
       // TODO Auto-generated method stub 
       Toast.makeText(getApplicationContext(), actorsList.get(position).getName(), Toast.LENGTH_LONG).show();    
      } 
     }); 
    } 


    class JSONAsyncTask extends AsyncTask<String, Void, Boolean> { 

     ProgressDialog dialog; 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      dialog = new ProgressDialog(MainActivity.this); 
      dialog.setMessage("Loading, please wait"); 
      dialog.setTitle("Connecting server"); 
      dialog.show(); 
      dialog.setCancelable(false); 
     } 

     @Override 
     protected Boolean doInBackground(String... urls) { 
      try { 

       //------------------>> 
       HttpGet httppost = new HttpGet(urls[0]); 
       HttpClient httpclient = new DefaultHttpClient(); 
       HttpResponse response = httpclient.execute(httppost); 

       // StatusLine stat = response.getStatusLine(); 
       int status = response.getStatusLine().getStatusCode(); 

       if (status == 200) { 
        HttpEntity entity = response.getEntity(); 
        String data = EntityUtils.toString(entity); 


        JSONObject jsono = new JSONObject(data); 
        JSONArray jarray = jsono.getJSONArray("actors"); 

        for (int i = 0; i < jarray.length(); i++) { 
         JSONObject object = jarray.getJSONObject(i); 

         Actors actor = new Actors(); 

         actor.setName(object.getString("name")); 
         actor.setDescription(object.getString("description")); 

         actorsList.add(actor); 
        } 
        return true; 
       } 

       //------------------>> 

      } catch (ParseException e1) { 
       e1.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
      return false; 
     } 

     protected void onPostExecute(Boolean result) { 
      dialog.cancel(); 
      adapter.notifyDataSetChanged(); 
      if(result == false) 
       Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show(); 

     } 
    } 

} 
+1

Salvarlo in un file? – Skynet

risposta

7

Perché non basta salvarlo nella cartella della cache del vostro applicazione utilizzando qualcosa di simile:

String path = Environment.getExternalStorageDirectory() + File.separator + "cache" + File.separator; 
File dir = new File(path); 
if (!dir.exists()) { 
    dir.mkdirs(); 
} 
path += "data"; 
File data = new File(path); 
if (!data.createNewFile()) { 
    data.delete(); 
    data.createNewFile(); 
} 
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(data)); 
objectOutputStream.writeObject(actorsList); 
objectOutputStream.close(); 

E dopo, si può leggere in qualsiasi momento tramite:

List<?> list = null; 
File data = new File(path); 
try { 
    if(data.exists()) { 
     ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(data)); 
     list = (List<Object>) objectInputStream.readObject(); 
     objectInputStream.close(); 
    } 
} catch (IOException e) { 
    e.printStackTrace(); 
} catch (ClassNotFoundException e) { 
    e.printStackTrace(); 
} 

UPDATE: Ok, crea una classe chiamata ObjectToFileUtil, incolla questo codice nella classe creata

package <yourpackagehere>; 

import android.os.Environment; 

import java.io.*; 

public class ObjectToFileUtil { 

    public static String objectToFile(Object object) throws IOException { 
     String path = Environment.getExternalStorageDirectory() + File.separator + "cache" + File.separator; 
     File dir = new File(path); 
     if (!dir.exists()) { 
      dir.mkdirs(); 
     } 
     path += "data"; 
     File data = new File(path); 
     if (!data.createNewFile()) { 
      data.delete(); 
      data.createNewFile(); 
     } 
     ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(data)); 
     objectOutputStream.writeObject(object); 
     objectOutputStream.close(); 
     return path; 
    } 

    public static Object objectFromFile(String path) throws IOException, ClassNotFoundException { 
     Object object = null; 
     File data = new File(path); 
     if(data.exists()) { 
      ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(data)); 
      object = objectInputStream.readObject(); 
      objectInputStream.close(); 
     } 
     return object; 
    } 
} 

Modifica < yourpackagehere> al nome del pacchetto e non dimenticare di aggiungere WRITE_EXTERNAL_STORAGE autorizzazione a AndroidManifest.xml. Nel vostro MainActivity aggiungere campo

private String dataPath; 

e sostituire il metodo OnPostExecute di classe JSONAsyncTask per

protected void onPostExecute(Boolean result) { 
    dialog.cancel(); 
    adapter.notifyDataSetChanged(); 
    if(result) { 
     try { 
      dataPath = objectToFile(arrayList); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } else { 
     Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show(); 
    } 
} 

Ora è possibile accedere ottenere actorsList dalle ore file quando si desidera, utilizzando

try { 
    actorsList = (ArrayList<Actors>)objectFromFile(dataPath); 
} catch (IOException e) { 
    e.printStackTrace(); 
} catch (ClassNotFoundException e) { 
    e.printStackTrace(); 
} 

Se si desidera salvare il percorso del file dopo aver chiuso l'applicazione, è necessario salvare la stringa dataPath (e caricare all'avvio dell'applicazione), ad esempio utilizzando SharedPreferences.

+0

Ho letto la tua risposta e ho compreso l'utilizzo del file, puoi combinare il tuo codice con quello mio? .. così potrò provarlo o hai qualche codice di esempio su github? – Sun

+0

È divertente. Prima hai appena chiesto un OPNION. Quindi @doubledeath ha scritto tutto il codice corretto di cui hai bisogno, in un modo generale in modo che tu possa usarlo come preferisci nella TUA app e ora ti lamenti ancora della risposta ... ¬¬ – PFROLIM

+0

@Sun controlla l'aggiornamento sopra e se avrò domande, fammi sapere qui – doubledeath

0
And what would be the best option to cache data ? SharedPreferences or SQLite database 

che è puramente basata sui dati che hai ricevuto.

  1. Se i dati sono piccoli, i dati non strutturati utilizzano Shared Pref.
  2. Se i dati sono grandi, i dati strutturati utilizzano SQLite.

Ma per memorizzare i dati completi meglio è possibile utilizzare file concept. Memorizza i dati di stringa nel tuo codice String data = EntityUtils.toString(entity); il data devi salvare nel file.Se eventuali modifiche nei dati dal server lo aggiungono a file.E recuperare i dati se Internet non è presente. Ottieni il codice di esempio per le operazioni sui file dal link sopra.

Problemi correlati