我正在研究像techcrunch这样的文章应用程序我正在从json解析数据。 我正在从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 :(得分: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;
}
}
要写入文件:
cacheThis.writeObject(YourActivity.this, fileName, movieList);
从文件中读取:
movieList.addAll((List<Movie>) cacheThis.readObject(
VideoActivity.this, fileName));
您必须拥有电影课程implements Serializable
答案 1 :(得分:1)
您必须将json保存为脱机状态。它可以是Db或文件系统。我更愿意选择Db部分。
方法是,每次从服务器获取数据时,首先从db中获取数据,然后从db中获取数据,然后将其显示在UI中。
在Db中插入可能很慢,但您可以使用beginTransaction和其他方法来快速点亮。
现在如何在Db中保存数据。你有两种方式
您可以先解析json,然后为name,url和其他字段创建表结构,然后运行查询
或者将整个json存储在Db中而不进行解析。通过使用GSON或其他json解析器,这个approch将非常有用。
答案 2 :(得分:1)
我看到你正在使用Volley
。 Volley内置了HTTP Cache
机制。
所以最简单的方法是在后端支持HTTP缓存头。它非常简单,对客户端来说是透明的。 Volley
做了很多努力。您可以找到信息here
如果您无法访问所使用的URL,则必须使用内部数据库来支持您的应用程序。 ContentProvider
API是执行此操作的最佳方式。以下库是构建数据库并写入数据库的绝佳库。
https://github.com/TimotheeJeannin/ProviGen
基本上,您需要将从互联网上提取的每个项目写入数据库,ListView
应使用您刚刚创建的ContentProvider
显示数据库中的项目。当用户打开应用程序时,显示数据库中的数据,然后立即尝试从后端提取新数据。