I am working on a articles application like techcrunch I am parsing data from json. I am parsing title,author and image from json. Articles are displayed in list-view. I want to do offline caching means when there is no internet user can read the articles.
Here is my code-
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;
}
}
}
You must save the json offline. It can be Db or file system. I will prefer to go with Db part.
The approach is ,every time you get data from server save first in you db then from db you can show it to your UI.
Inserting in Db can be slow but you can use beginTransaction and other methods which will make it lighting fast.
Now How can you save data in Db. You have two ways
You can parse json first and create the table structure for name,url and other fields then run the query
Or store the whole json in Db without parsing .By using GSON or other json parsers this approch will be quite helpful.
I saw you are using
Volley
. Volley has built-inHTTP Cache
mechanism.So the easiest way is to support HTTP cache headers in your backend. It is very easy and it is transparent to the client side.
Volley
does the hard work. You can find information hereIf you don't have access to the URL you use, you must use internal database to support your application.
ContentProvider
API is the best way to do that. And the following library is a great library to construct a database and write to it. https://github.com/TimotheeJeannin/ProviGenBasically you need to write every item that you pull from the internet to the database and the
ListView
should show the items from the database usingContentProvider
you have just created. When the user opens the app, show the data from the database and then immediately try to pull the new data from your backend.This probably isn't the best way to do it, but it worked for me.
You might find this helpful: http://www.vogella.com/tutorials/JavaSerialization/article.html
I had to do the same in some project. This is what I did:
To write to file:
To read from file:
You have to have your Movie class
implements Serializable