2014-10-01 42 views
1

我正在處理像techcrunch這樣的文章應用程序我從json解析數據。 我解析json的標題,作者和圖像。 文章以列表視圖顯示。 我想做離線緩存意味着沒有互聯網用戶可以閱讀文章。如何在Android中實現json的離線緩存?

這裏是我的代碼 -

public class OneFragment extends Fragment { 

public OneFragment(){} 
private static final String TAG = OneFragment.class.getSimpleName(); 

// Movies json url 
private static String URL = "http://url"; 
private ProgressDialog pDialog; 
private List<Movie> movieList = new ArrayList<Movie>(); 
private ListView listView; 
private CustomListAdapter adapter; 
int current_page = 0; 
int mPreLast; 
SwipeRefreshLayout swipeView; 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 

    final View rootView = inflater.inflate(R.layout.swip, container, false); 
    swipeView = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe); 
    swipeView.setColorScheme(android.R.color.holo_blue_dark, android.R.color.holo_blue_light, android.R.color.holo_green_light, android.R.color.holo_green_dark); 
    pDialog = new ProgressDialog(getActivity()); 
    pDialog.setMessage("Loading..."); 
    pDialog.show(); 
    pDialog.setCancelable(false); 

    swipeView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { 

     @Override 
     public void onRefresh() { 
      // TODO Auto-generated method stub 
      swipeView.setRefreshing(true); 
      Log.d("Swipe", "Refreshing Number"); 
      (new Handler()).postDelayed(new Runnable() { 

       @Override 
       public void run() { 
        // TODO Auto-generated method stub 
        swipeView.setRefreshing(false); 
        onStart(); 
       } 
      }, 3000); 
     } 
    }); 

    listView = (ListView) rootView.findViewById(R.id.list49); 
    listView.setOnScrollListener(new AbsListView.OnScrollListener() 
    { 
     @Override 
     public void onScrollStateChanged(AbsListView absListView, int i) 
     { 

     } 

     @Override 
     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) 
     { 
      int lastItem = firstVisibleItem + visibleItemCount; 
       if(lastItem == totalItemCount){ 
        if (mPreLast != lastItem) 
        { 
         mPreLast = lastItem;       
         pDialog = new ProgressDialog(getActivity()); 
         pDialog.setMessage("Loading more articles..."); 
         pDialog.show(); 
         //pDialog.setCancelable(false); 
         onStart(); 
        } 
      } 
     } 
    }); 

    listView.setOnItemClickListener(new OnItemClickListener() { 

     @Override 
     public void onItemClick(AdapterView<?> adapterView, View view, int Position, 
       long offset) { 
      // TODO Auto-generated method stub 
      Movie item = (Movie) adapter.getItem(Position);    
      Intent intent = new Intent(rootView.getContext(), SingleArticle.class); 
      single.title = item.getTitle(); 
      single.author = item.getAuthor(); 

      startActivity(intent); 


      }   
     }); 
    //pDialog = new ProgressDialog(this); 
    // Showing progress dialog before making http request 

    return rootView; 
} 

@Override 
public void onStart(){ 
    super.onStart(); 
    // calling adapter changes here, just 
    // to avoid getactivity()null 
    // increment current page 
    current_page += 1; 
    // Next page request 
    URL = "http://url" + current_page; 
    //adapter = new CustomListAdapter(this, movieList); 
    int currentPosition = listView.getFirstVisiblePosition(); 
    adapter = new CustomListAdapter(getActivity(), movieList); 
    listView.setAdapter(adapter); 
    listView.setSelectionFromTop(currentPosition + 1, 0); 
    // changing action bar color 
    //getActivity().getActionBar().setBackground(
      //new ColorDrawable(Color.parseColor("#1b1b1b"))); 

    // Creating volley request obj 
    JsonArrayRequest movieReq = 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); 
          Movie movie = new Movie(); 
          movie.setTitle(obj.getString("title")); 
          movie.setAuthor(obj.getString("author")); 
          // adding movie to movies array 
          movieList.add(movie); 




          adapter.notifyDataSetChanged(); 

         } catch (JSONException e) { 
          e.printStackTrace(); 
         } 
        }      
       } 
      },new Response.ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError error) { 
        VolleyLog.d(TAG, "Error: " + error.getMessage()); 
        new AlertDialog.Builder(getActivity()) 
        .setTitle("No Connectivity ") 
        .setMessage("Please check your internet connectivity!") 
        .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { 
         public void onClick(DialogInterface dialog, int which) { 
          // continue with delete 
         } 
        }) 
        //.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { 
         //public void onClick(DialogInterface dialog, int which) { 
          // do nothing 
         //} 
        //}) 
        .setIcon(android.R.drawable.ic_dialog_alert) 
        .show(); 
        hidePDialog(); 

       } 
      }); 
    AppController.getInstance().addToRequestQueue(movieReq);  
    //listView.setAdapter(adapter); 

} 

private View getActionBar() { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public void onDestroy() { 
super.onDestroy(); 
hidePDialog(); 
} 

private void hidePDialog() { 
if (pDialog != null) { 
    pDialog.dismiss(); 
    pDialog = null; 
} 
} 
} 
+0

人們普遍:

cacheThis.writeObject(YourActivity.this, fileName, movieList); 

從文件中讀取爲此而使用數據庫。那對你有用嗎?那麼你可能會得到很多例子。 – Darpan 2014-10-01 07:15:23

回答

3

這可能不是最好的辦法,但它對我有效。

你可能會有所幫助:http://www.vogella.com/tutorials/JavaSerialization/article.html

我不得不做相同的一些項目。這是我做過什麼:

public final class cacheThis { 
private cacheThis() {} 

public static void writeObject(Context context, String fileName, Object object) throws IOException { 
     FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE); 
     ObjectOutputStream oos = new ObjectOutputStream(fos); 
     oos.writeObject(object); 
     oos.flush(); 
     oos.close(); 

     fos.close(); 
    } 

    public static Object readObject(Context context, String fileName) throws IOException, 
     ClassNotFoundException { 
     FileInputStream fis = context.openFileInput(fileName); 
     ObjectInputStream ois = new ObjectInputStream(fis); 
     Object object = ois.readObject(); 
     fis.close(); 
     return object; 
    } 
} 

要寫入文件:

movieList.addAll((List<Movie>) cacheThis.readObject(
       VideoActivity.this, fileName)); 

你必須有你的電影類implements Serializable

+0

在哪裏寫入文件?我的意思是在json解析數據之後?你能指導我舉一個例子嗎? – Daljeet 2014-10-01 08:19:40

+0

我通常在解析整個響應後立即緩存。就像你可以在'public void onResponse(JSONArray response)'末尾寫入文件一樣: 'public void onResponse(JSONArray response){ Log.d(TAG,response.toString()); hidePDialog();對於(int i = 0; i SourApple 2014-10-01 08:37:13

+0

thnxs文件名我必須創建一個局部變量? – Daljeet 2014-10-01 09:08:29

1

必須將JSON離線保存。它可以是Db或文件系統。我會更喜歡與Db部分。

這種方法是,每次你從服務器獲取數據先保存在你的數據庫然後從數據庫你可以顯示它到你的用戶界面。

在Db中插入可能會很慢,但是您可以使用beginTransaction和其他方法來使其快速點亮。

現在您如何在Db中保存數據。有兩種方法

  • 你可以先解析JSON和創建名稱,網址等領域的表結構運行查詢

  • 或者以dB爲整個JSON存儲,而無需使用GSON。通過解析或者其他json解析器,這種方法將非常有用。

+0

thnxs !!我認爲文件系統比數據庫更好,因爲我的數據不多,但問題是我不知道如何在我的情況下實現文件系統。你能幫我解決它嗎! – Daljeet 2014-10-01 07:23:44

1

我看到您使用的是Volley。 Volley已經內置了HTTP Cache機制。

  • 所以最簡單的方法是在後端支持HTTP緩存頭。這非常簡單,對客戶端來說是透明的。 Volley努力工作。您可以找到信息here

  • 如果您無權訪問您使用的URL,則必須使用內部數據庫來支持您的應用程序。 ContentProvider API是做到這一點的最佳方式。下面的庫是構建數據庫並寫入數據庫的絕佳庫。 https://github.com/TimotheeJeannin/ProviGen

基本上你需要編寫每次您從互聯網上拉至數據庫項目和ListView應該使用您剛纔創建ContentProvider顯示從數據庫中的項目。當用戶打開應用程序時,顯示數據庫中的數據,然後立即嘗試從後端獲取新數據。