2015-01-14 51 views
5

Tôi đã phân tích cú pháp JSON thành công nhưng bây giờ tôi muốn Cache nó để sử dụng ngoại tuyến, thậm chí internet không khả dụng và nếu có bất kỳ mục nhập mới nào, tôi cũng muốn lưu vào bộ nhớ cache.Cách phân tích cú pháp JSON được phân tích cú pháp để sử dụng ngoại tuyến

Và tùy chọn nào tốt nhất để lưu vào bộ nhớ cache? SharedPreferences hoặc SQLite database

Đây là mã của tôi, mà tôi đang sử dụng để phân tích 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

Lưu tệp vào một tệp? – Skynet

Trả lời

7

Tại sao không chỉ cần lưu nó vào thư mục bộ nhớ cache của ứng dụng của bạn sử dụng một cái gì đó như thế này:

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

Và sau đó, bạn có thể đọc nó ở bất cứ lúc nào sử dụng:

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: Được rồi, tạo lớp có tên là ObjectToFileUtil, dán mã này vào lớp được tạo

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

Thay đổi < yourpackagehere> thành tên gói của bạn và đừng quên thêm WRITE_EXTERNAL_STORAGE cho phép AndroidManifest.xml. Năm MainActivity bạn bổ sung lĩnh vực

private String dataPath; 

và thay phương pháp onPostExecute bạn của lớp JSONAsyncTask tới

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

Bây giờ bạn có thể truy cập được actorsList từ tập tin bất cứ lúc nào khi bạn muốn, bằng cách sử dụng

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

Nếu bạn muốn lưu đường dẫn tệp sau khi đóng ứng dụng, bạn phải lưu chuỗi dataPath (và tải khi khởi động ứng dụng), ví dụ, sử dụng SharedPreferences.

+0

Tôi đã đọc câu trả lời của bạn và hiểu việc sử dụng tập tin, bạn có thể kết hợp mã của bạn với một của tôi? .. vì vậy tôi sẽ có thể thử nó hoặc làm bạn có bất kỳ mã mẫu trên github? – Sun

+0

Thật buồn cười. Trước tiên, bạn chỉ cần yêu cầu một OPNION. Sau đó, @doubledeath đã viết tất cả mã đúng bạn cần, theo cách tổng quát để bạn có thể sử dụng nó theo cách bạn thích trong ứng dụng CỦA BẠN và bây giờ bạn vẫn than phiền về câu trả lời ... ¬¬ – PFROLIM

+0

@Sun kiểm tra cập nhật ở trên và nếu sẽ có câu hỏi, hãy cho tôi biết ở đây. – doubledeath

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

Đó là hoàn toàn dựa trên các dữ liệu mà bạn nhận được.

  1. Nếu dữ liệu nhỏ, dữ liệu phi cấu trúc sau đó sử dụng Shared Pref.
  2. Nếu dữ liệu lớn, dữ liệu có cấu trúc sau đó sử dụng SQLite.

Nhưng để lưu trữ dữ liệu đầy đủ, bạn có thể sử dụng file concept. Lưu trữ dữ liệu chuỗi trong mã của bạn String data = EntityUtils.toString(entity);data bạn phải lưu vào tệp.Nếu có bất kỳ thay đổi nào trong dữ liệu từ máy chủ, hãy thêm dữ liệu đó vào tệp. Và truy xuất dữ liệu nếu không có internet. Lấy mã ví dụ cho các hoạt động tập tin từ liên kết ở trên.

Các vấn đề liên quan