我做了简单的测试应用程序基于此示例。有一个按钮,插入到数据库和列表视图的数据。都是在 MainActivity 中。在原来的代码是restartLoader() 仅从调用 onResume() ,但它刷新列表视图时才 onResume() 被执行死刑。我把 restartLoader() 在结束了displayListView() 和现在它显示新行在列表视图中后我按下按钮。但我不认为它是正确的解决方案。

 public class MainActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor>{

      private SimpleCursorAdapter dataAdapter;

      @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); displayListView(); Button add = (Button) findViewById(R.id.add);
add.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { ContentValues values = new ContentValues();
values.put(SensorsDb.KEY_TYPE, "wld");
values.put(SensorsDb.KEY_TITLE, "Basement Water Detector");
values.put(SensorsDb.KEY_SERIAL, "");
values.put(SensorsDb.KEY_VALUE, "NO WATER"); getContentResolver().insert(MyContentProvider.CONTENT_URI,values); displayListView();
}
});
}
@Override
protected void onResume() {
super.onResume();
//Starts a new or restarts an existing Loader in this manager
getSupportLoaderManager().restartLoader(, null, MainActivity.this);
} private void displayListView() {
// The desired columns to be bound
String[] columns = new String[] {
SensorsDb.KEY_TITLE,
SensorsDb.KEY_VALUE
};
// the XML defined views which the data will be bound to
int[] to = new int[] {
R.id.sensorTitle,
R.id.sensorState
}; // create an adapter from the SimpleCursorAdapter
dataAdapter = new SimpleCursorAdapter(this, R.layout.custom_row_view, null, columns, to, );
//Ensures a loader is initialized and active.
getSupportLoaderManager().initLoader(, null, this);
// get reference to the ListView
ListView listView = (ListView) findViewById(R.id.sensorList);
// Assign adapter to ListView
listView.setAdapter(dataAdapter); getSupportLoaderManager().restartLoader(, null, MainActivity.this);
} // This is called when a new Loader needs to be created.
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection = {
SensorsDb.KEY_ROWID,
SensorsDb.KEY_TYPE,
SensorsDb.KEY_TITLE,
SensorsDb.KEY_SERIAL,
SensorsDb.KEY_VALUE};
CursorLoader cursorLoader = new CursorLoader(this,
MyContentProvider.CONTENT_URI, projection, null, null, null);
return cursorLoader;
} @Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { dataAdapter.swapCursor(data);
} @Override
public void onLoaderReset(Loader<Cursor> loader) { dataAdapter.swapCursor(null);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
有 MyContentProvider 类 public class MyContentProvider extends ContentProvider{ private MyDatabaseHelper dbHelper; private static final int ALL_SENSORS = ;
private static final int SINGLE_SENSOR = ; // authority is the symbolic name of your provider
// To avoid conflicts with other providers, you should use
// Internet domain ownership (in reverse) as the basis of your provider authority.
private static final String AUTHORITY = "com.example.contproctest.contentprovider"; // create content URIs from the authority by appending path to database table
public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/sensors"); // a content URI pattern matches content URIs using wildcard characters:
// *: Matches a string of any valid characters of any length.
// #: Matches a string of numeric characters of any length.
private static final UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, "sensors", ALL_SENSORS);
uriMatcher.addURI(AUTHORITY, "sensors/#", SINGLE_SENSOR);
} // system calls onCreate() when it starts up the provider.
@Override
public boolean onCreate() {
// get access to the database helper
dbHelper = new MyDatabaseHelper(getContext());
return false;
} //Return the MIME type corresponding to a content URI
@Override
public String getType(Uri uri) { switch (uriMatcher.match(uri)) {
case ALL_SENSORS:
return "vnd.android.cursor.dir/vnd.com.example.contproctest.contentprovider.sensors";
case SINGLE_SENSOR:
return "vnd.android.cursor.item/vnd.com.example.contproctest.contentprovider.sensors";
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
} // The insert() method adds a new row to the appropriate table, using the values
// in the ContentValues argument. If a column name is not in the ContentValues argument,
// you may want to provide a default value for it either in your provider code or in
// your database schema.
@Override
public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase db = dbHelper.getWritableDatabase();
switch (uriMatcher.match(uri)) {
case ALL_SENSORS:
//do nothing
break;
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
long id = db.insert(SensorsDb.SQLITE_TABLE, null, values);
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(CONTENT_URI + "/" + id);
} // The query() method must return a Cursor object, or if it fails,
// throw an Exception. If you are using an SQLite database as your data storage,
// you can simply return the Cursor returned by one of the query() methods of the
// SQLiteDatabase class. If the query does not match any rows, you should return a
// Cursor instance whose getCount() method returns 0. You should return null only
// if an internal error occurred during the query process.
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) { SQLiteDatabase db = dbHelper.getWritableDatabase();
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(SensorsDb.SQLITE_TABLE); switch (uriMatcher.match(uri)) {
case ALL_SENSORS:
//do nothing
break;
case SINGLE_SENSOR:
String id = uri.getPathSegments().get();
queryBuilder.appendWhere(SensorsDb.KEY_ROWID + "=" + id);
break;
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
} Cursor cursor = queryBuilder.query(db, projection, selection,
selectionArgs, null, null, sortOrder);
return cursor; } // The delete() method deletes rows based on the seletion or if an id is
// provided then it deleted a single row. The methods returns the numbers
// of records delete from the database. If you choose not to delete the data
// physically then just update a flag here.
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = dbHelper.getWritableDatabase();
switch (uriMatcher.match(uri)) {
case ALL_SENSORS:
//do nothing
break;
case SINGLE_SENSOR:
String id = uri.getPathSegments().get();
selection = SensorsDb.KEY_ROWID + "=" + id
+ (!TextUtils.isEmpty(selection) ?
" AND (" + selection + ')' : "");
break;
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
int deleteCount = db.delete(SensorsDb.SQLITE_TABLE, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return deleteCount;
} // The update method() is same as delete() which updates multiple rows
// based on the selection or a single row if the row id is provided. The
// update method returns the number of updated rows.
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
switch (uriMatcher.match(uri)) {
case ALL_SENSORS:
//do nothing
break;
case SINGLE_SENSOR:
String id = uri.getPathSegments().get();
selection = SensorsDb.KEY_ROWID + "=" + id
+ (!TextUtils.isEmpty(selection) ?
" AND (" + selection + ')' : "");
break;
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
int updateCount = db.update(SensorsDb.SQLITE_TABLE, values, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return updateCount;
} }
解决方法 :
你不需要调用 restartLoader 后在 CP 中插入新的数据,因为 CursorLoader 可以听您的数据和 (ContentProvider) 的数据源中发生更改时自动更新。尝试在调用 cursor.setNotificationUri() 之前返回 Cursor 从你 CP 的查询方法。 @Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) { SQLiteDatabase db = dbHelper.getWritableDatabase();
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(SensorsDb.SQLITE_TABLE); switch (uriMatcher.match(uri)) {
case ALL_SENSORS:
//do nothing
break;
case SINGLE_SENSOR:
String id = uri.getPathSegments().get();
queryBuilder.appendWhere(SensorsDb.KEY_ROWID + "=" + id);
break;
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
} Cursor cursor = queryBuilder.query(db, projection, selection,
selectionArgs, null, null, sortOrder); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor;
}

Android 用SQLite 使用 CursorLoader 中的数据填充列表视图的更多相关文章

  1. sqlite 删除表中重复数据(亲测可用)

    例子:表名  Paper .通过字段PaperID查找重复数据. 1 --查询某表中重复的数据       select * from Paper group by PaperID having co ...

  2. Android之读取 AndroidManifest.xml 中的数据

    转:http://www.2cto.com/kf/201208/151123.html 下来示例如何读取这些数据. 1 版本信息.应用名称 2 Appliction 的Meta-data 3 Acti ...

  3. Android之读取 AndroidManifest.xml 中的数据:版本号、应用名称、自定义K-V数据(meta-data)

    AndroidManifest.xml中的定义如下: <manifest xmlns:android="http://schemas.android.com/apk/res/andro ...

  4. android studio sqlite实际应用中存在的问题

    原项目已上传到github long f = dbdatabase.update("user", values, "id=?", new String[]{St ...

  5. 动态从数据库中获取数据填充Select

    JavaScript代码: $(document).ready(function () { getIntype(); });function getIntype(){ $.ajax({ type:&q ...

  6. JS数据交互:动态从数据库中获取数据填充Select

    JavaScript代码: $(document).ready(function () { getIntype(); });function getIntype(){ $.ajax({ type:&q ...

  7. 【Android Developers Training】 81. 解析XML数据

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  8. java向文件中添加数据---手动版日志添加

    核心代码为创建多级文件夹创建 //目标文件 File file=new File(filePath); //若不存在即创建文件 if(!file.exists()) { if (!file.getPa ...

  9. (转)SQLServer_十步优化SQL Server中的数据访问 三

    原文地址:http://tech.it168.com/a2009/1125/814/000000814758_all.shtml 第六步:应用高级索引 实施计算列并在这些列上创建索引 你可能曾经写过从 ...

随机推荐

  1. java使用默认线程池踩过的坑(二)

    云智慧(北京)科技有限公司 陈鑫 是的.一个线程不可以启动两次.那么它是怎么推断的呢? public synchronized void start() { /** * A zero status v ...

  2. Android 採用HTML设计界面

    由于Android软件开发分工眼下还没有细化,程序猿往往须要负责软件界面的开发,尽管软件的界面图片已经由美工设计好了.可是假设使用layout技术把软件做成美丽的界面确实非常困难,而是也比較耗时.An ...

  3. C/C++(共用体与枚举)

    共用(Union)与枚举(Enum) 共同体 c语言中,不同的成员使用共同的存储区域的数据结构类型称为共用体.(共用,联合体),共用体在定义,说明,适用形式上与结构体相似.两者本质上的不同在于使用内存 ...

  4. CTF编程题-三羊献瑞(实验吧)解题随记

    题目如下.解题步骤参考的是https://cloud.tencent.com/developer/news/373865中作者的思路. 1.首先,两个四位数相加等于一个五位数,那么这个五位数的第一位必 ...

  5. POJ 1426 Find The Multiple (DFS / BFS)

    题目链接:id=1426">Find The Multiple 解析:直接从前往后搜.设当前数为k用long long保存,则下一个数不是k*10就是k*10+1 AC代码: /* D ...

  6. Django加入JS,CSS,图片等外部文件的方法

    Django加入JS,CSS.图片等外部文件的方法 By 白熊花田(http://blog.csdn.net/whiterbear) 转载需注明出处,谢谢. 在使用Django搭建站点时,往往须要使用 ...

  7. [LuoguU41039]PION后缀自动机 树链剖分+动态开点线段树

    链接 刚开始看出题人题解都吓蒙掉了,还以为是什么难题,结果就一板子题 思路:对每一个文件名开一棵线段树,然后树剖即可 #include<bits/stdc++.h> #define REP ...

  8. 18.Node.js 事件循环

    转自:http://www.runoob.com/nodejs/nodejs-tutorial.html Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高. Node ...

  9. Objective-C基础笔记(1)基本概念和第一个程序

    一.基本概念 Objective-C(简称OC)是iOS开发的核心语言,苹果公司在维护,在开发过程中也会配合着使用C语言.C++,OC主要负责UI界面,C语言.C++可用于图形处理.C语言是面向过程的 ...

  10. POJ 1118 Lining Up 直线穿过最多的点数

    http://poj.org/problem?id=1118 直接枚举O(n^3) 1500ms能过...数据太水了...这个代码就不贴了... 斜率排序O(n^2logn)是更好的做法...枚举斜率 ...