Android使用SQLiteOpenHelper实现离线浏览
来源:互联网 发布:mac arp 嗅探工具dmg 编辑:程序博客网 时间:2024/05/01 09:40
相信在Android开发中,很多APP都会用到数据库来保存数据,今天我们来讨论一下它其中用法,用数据库实现离线浏览。数据库类型很多,Android默认是使用SQLite。
首先我们来看一下界面
很简单,经典的图文混排。
要想实现APP离线浏览,我们需要:
- 创建一个类继承SQLiteOpenHelper(该类帮我们封装好了很多数据库操作)
- 将功能抽象出来
- 创建数据库管理类
- 使用我们创建的数据库来实现离线浏览。
首先我们根据模型类来创建SQLiteOpenHelper
模型类
public class News { private int id; private String title; private String postdate; private String editor; private String icon; public News(int id, String title, String postdate, String editor, String icon) { this.id = id; this.title = title; this.postdate = postdate; this.editor = editor; this.icon = icon; } // getter and setter ...}
public class NewsSQLiteOpenHelper extends SQLiteOpenHelper { // 数据库名 private static final String NAME = "learn.db"; // 数据库版本 private static final int VERSION = 1; // 建表语句 private static final String CREATE_NEWS = "create table if not exists news(" + "_id integer primary key," + "title text," + // 这个时间字段只是单纯的为了后面查询时好排序 "time integer," + "icon text," + "editor text," + "postdate text)"; public NewsSQLiteOpenHelper(Context context) { super(context, NAME, null, VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_NEWS); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }}
这里主要要实现的方法是onCreate,在里面完成我们的初始化建表工作,构造函数需要传入的四个参数分别为:上下文、数据库名、游标工厂(默认为null)、版本号。onUpgrade方法 只会在数据库更新才会调用。这里我们不会用到。
将功能抽象出来
public interface INewsDB { List<News> getAllNews(); void deleteAllNews(); News getNewsById(int id); void insertAllNews(List<News> newsList); void insertNews(News news);}
这里首先说一下为什么要创建这么一个接口,很简单,解耦合,以后维护修改的时候方便。抽象出来的这些功能都是我们后面将用到的,都是基本的增删改查操作。
创建数据库管理类(重点)
public class NewsDBManager implements INewsDB { private static NewsDBManager sManager; private NewsSQLiteOpenHelper mHelper; private NewsDBManager(Context context) { mHelper = new NewsSQLiteOpenHelper(context); } public static NewsDBManager getInstance(Context context) { if (sManager == null) { synchronized (NewsDBManager.class) { if (sManager == null) { sManager = new NewsDBManager(context); } } } return sManager; } /** * 查询所有新闻 * * @return */ @Override public List<News> getAllNews() { SQLiteDatabase db = mHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("select * from news order by time ASC", null); List<News> newsList = new ArrayList<>(); while (cursor.moveToNext()) { int id = cursor.getInt(cursor.getColumnIndex("_id")); String title = cursor.getString(cursor.getColumnIndex("title")); String icon = cursor.getString(cursor.getColumnIndex("icon")); String editor = cursor.getString(cursor.getColumnIndex("editor")); String postdate = cursor.getString(cursor.getColumnIndex("postdate")); News news = new News(id, title, postdate, editor, icon); newsList.add(news); } mHelper.close(); return newsList; } /** * 删除所有新闻 */ @Override public void deleteAllNews() { SQLiteDatabase db = mHelper.getWritableDatabase(); db.execSQL("delete from news"); mHelper.close(); } /** * 通过给定的id获取新闻 * * @param id * @return */ @Override public News getNewsById(int id) { SQLiteDatabase db = mHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("select * from news where _id = ?", new String[]{String.valueOf(id)}); cursor.moveToNext(); String title = cursor.getString(cursor.getColumnIndex("title")); String icon = cursor.getString(cursor.getColumnIndex("icon")); String editor = cursor.getString(cursor.getColumnIndex("editor")); String postdate = cursor.getString(cursor.getColumnIndex("postdate")); News news = new News(id, title, postdate, editor, icon); mHelper.close(); return news; } @Override public void insertAllNews(List<News> newsList) { for (News news : newsList) { insertNews(news); } } @Override public void insertNews(News news) { SQLiteDatabase db = mHelper.getWritableDatabase(); db.execSQL("insert into news(_id,title,time,icon,editor,postdate) values(?,?,?,?,?,?)", new Object[]{news.getId(), news.getTitle(), System.currentTimeMillis(), news.getIcon(), news.getEditor(), news.getPostdate()}); }}
解析一下代码:这里我们创建一个News数据库管理类,专门进行数据库的增删改查操作,实现INewsDB抽象的功能。增删改查的代码就不多解释了,这里注意一下delete操作,Android的delete有一个蜜汁bug,本来数据库的删除操作应该是delete * from table,但是这个 * 无法通过编译,所以只能delete from table。
实际运用
好了,终于到最后一步了,有木有很激动。
private void initView() { mNewsRv = ((RecyclerView) findViewById(R.id.rv_news)); mLoading = findViewById(R.id.pb_loading); LinearLayoutManager layout = new LinearLayoutManager(this); mNewsRv.setLayoutManager(layout); mAdapter = new NewsAdapter(this, null); mNewsRv.setAdapter(mAdapter); mLoading.setVisibility(View.VISIBLE); // 加载数据的时候先检测网络 if (NetworkUtils.checkNetworkState(this)) { Log.d(TAG, "initView: 从网络获取数据"); getDataFromInternet(); } else { Log.d(TAG, "initView: 从数据库获取数据"); getDataFromDB(); } } private void getDataFromInternet() { HttpUtils.getAsynString(Urls.URL_NEWS_ITEM_SOFTWARE, new HttpUtils.ResultCallback() { @Override public void onFailure(Exception e) { Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show(); } @Override public void onFinish(String result) { Gson gson = new Gson(); List<News> data = gson.fromJson(result, new TypeToken<List<News>>() { }.getType()); mAdapter.update(data); NewsDBManager manager = NewsDBManager.getInstance(MainActivity.this); // 删除旧数据,保存最新数据 manager.deleteAllNews(); manager.insertAllNews(data); mLoading.setVisibility(View.GONE); } }); } private void getDataFromDB() { NewsDBManager manager = NewsDBManager.getInstance(this); List<News> data = manager.getAllNews(); if (data.size() > 0) { mAdapter.update(data); } mLoading.setVisibility(View.GONE); }
最后再来看看调试结果
根据log可知,没网时,最后走了getDataFromDB(),界面数据也与有网时一样正常显示出来。
项目源码
1 0
- Android使用SQLiteOpenHelper实现离线浏览
- UIWebView实现离线浏览
- UIWebView实现离线浏览
- UIWebView实现离线浏览
- UIWEBView实现离线浏览
- Android SQLiteOpenHelper使用示例
- Android如何使用SQLiteOpenHelper
- android SQLiteOpenHelper使用示例
- android SQLiteOpenHelper使用示例
- android SQLiteOpenHelper使用示例
- android SQLiteOpenHelper使用示例
- android SQLiteOpenHelper使用示例
- android SQLiteOpenHelper使用示例
- android SQLiteOpenHelper使用示例
- android SQLiteOpenHelper使用示例
- Android-SQLiteOpenHelper使用示例
- android SQLiteOpenHelper使用示例
- Android SQLiteOpenHelper使用
- Windows下Dos命令和Linux下基本命令集合收藏<以及各种操作奇淫技巧>
- windows下node/npm安装失败
- java异常的写法 及一些常见的异常问题
- node-webkit制作桌面应用
- 继承与多态 --- 下 --- 重载与重写、多态实现原理、纯虚函数
- Android使用SQLiteOpenHelper实现离线浏览
- Oracle之利用iscsi构建RAC共享存储测试
- <spark>RDD初识
- nginx proxy_cache 批量清理脚本
- BZOJ 1022 Anti-SG游戏
- gson简单教程(一)
- Política de Privacidade
- 1050. 螺旋矩阵(25)
- 关于studio 代码管理(svn or git)