- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我已将我的设备更新到 Android ICS (4.0.3)我有一个 Activity ,其中包含一个 ListView ,其中填充了从数据库读取的数据。使用 ResourceCursorAdapter 的扩展在 ListView 中排列数据。
列表加载并显示在屏幕上后,我按下主屏幕以调出主屏幕。然后我从最近恢复我的应用程序(长按主屏幕),突然我得到以下异常:
05-10 15:49:17.925: E/AndroidRuntime(10721): Caused by: android.database.StaleDataException: Attempted to access a cursor after it has been closed.
05-10 15:49:17.925: E/AndroidRuntime(10721): at android.database.BulkCursorToCursorAdaptor.throwIfCursorIsClosed(BulkCursorToCursorAdaptor.java:75)
05-10 15:49:17.925: E/AndroidRuntime(10721): at android.database.BulkCursorToCursorAdaptor.requery(BulkCursorToCursorAdaptor.java:144)
05-10 15:49:17.925: E/AndroidRuntime(10721): at android.database.CursorWrapper.requery(CursorWrapper.java:186)
05-10 15:49:17.925: E/AndroidRuntime(10721): at android.app.Activity.performRestart(Activity.java:4505)
05-10 15:49:17.925: E/AndroidRuntime(10721): at android.app.Activity.performResume(Activity.java:4531)
05-10 15:49:17.925: E/AndroidRuntime(10721): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2446)
我已经阅读了我的操作系统的行为,并且光标似乎无效。问题是,尽管我已经注册了一个 DataSetObserver,但从未调用过 onInvalidated 方法,并且在崩溃之前也没有调用任何 Activity 的方法(如 onResume、onRestart)。代码甚至没有到达 Adapter 中的 bindView。
你能帮我解决这个问题吗?如果您需要,我可以提供更多信息和相关代码。
提前致谢
这是代码,抱歉,如果它一团糟,但我只是在微调之前让它工作:
public class CallLogsList extends Activity implements Runnable,
OnItemClickListener {
// ... various declaration here
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case CALLLOGS_LOAD_DONE:
loadCurrCallLogsList(true);
break;
case SHOW_ALL_LOG:
case SHOW_MISSED_LOG:
case SHOW_OUTGOING_LOG:
case SHOW_INCOMING_LOG:
// - set the adapter
if (null == mCad) {
// the first time the adapter need to be called
mCad = new CallLogsCursorAdapter(mContext, mDataCursor);
mCallLogsListView.setAdapter(mCad);
} else {
mCad.changeCursor(mDataCursor);
mCad.notifyDataSetChanged();
}
break;
} // end of switch ctrl structure
return;
} // end of method handleMessage
}; // end of Handler object
/**
* The following inner class implements the custom adapter to contain the
* call log entries as read from the database
*
*/
class CallLogsCursorAdapter extends ResourceCursorAdapter {
Cursor mCallLogCursor = null;
CallLogDataSetObserver mLogDataObserver = null;
/**
* Class constructor
*
* @param context
* @param c
*/
public CallLogsCursorAdapter(Context context, Cursor c) {
super(context, R.layout.recent_calls_list_item, c);
mLogDataObserver = new CallLogDataSetObserver();
mCallLogCursor = c;
mCallLogCursor.registerDataSetObserver(mLogDataObserver);
return;
} // end of class constructor
/**
* This method binds an existing view to the data pointed to by the
* cursor
*/
@Override
public void bindView(View view, Context context, Cursor cursor) {
// ... bind data to the view here
} // end of method bindView
/**
* This method inflates the new view from the specified resource Such
* resource has been passed to the super class in the call at the parent
* class constructor we did in this derived class
*/
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = super.newView(context, cursor, parent);
// ... create the view
return view;
} // end of method newView
/**
/**
* The data set observer for the data used by this adapter
*/
private class CallLogDataSetObserver extends DataSetObserver {
@Override
public void onChanged() {
return;
} // end of method onChanged
@Override
public void onInvalidated() {
if( null != mCallLogCursor ) {
// TODO: Remove this call coz the UI can get stuck
// if the call log is too long. Just ask for a new
// cursor asynchronously
mCallLogCursor.requery();
}
return;
} // end of method onInvalidated
} // end of class inner class CallLogDataSetObserver
} // end of class CallLogsCursorAdapter
/**
* This method is called the first time the activity is created
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(THIS_FILE, "Enter onCreate");
super.onCreate(savedInstanceState);
// ... initialization code here
loadCurrCallLogsList(false);
return;
} // end of method onCreate
/**
* This method loads the current communication list
*/
private synchronized void loadCurrCallLogsList(final boolean fromPullDown) {
if (false == fromPullDown) {
showLoadingView(true);
}
// start the loader thread
Thread loader = new Thread(this);
loader.start();
return;
} // end of method loadCurrCommunicationsList
/**
* This method is called when the activity is going to be destroyed
*/
@Override
protected void onDestroy() {
if (null != database) database.close();
database = null;
if (mDataCursor != null) mDataCursor.close();
mDataCursor = null;
// call the super class onDestroy method
super.onDestroy();
}
/**
* This method create the menu for the activity
*
* @param menu
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.in_call_log_list_menu, menu);
return super.onCreateOptionsMenu(menu);
} // end of method onCreateOptionsMenu
/**
* This method is called when the menu is going to be shown
*/
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (false == CordlessApplication.getInstance().canUseJungoApi()) {
menu.findItem(R.id.menu_item_edit).setEnabled(false);
} else {
// enable the edit item in the menu if the list is not empty
menu.findItem(R.id.menu_item_edit).setEnabled(
null != mCad && !mCad.isEmpty());
}
return super.onPrepareOptionsMenu(menu);
} // end of method onPrepareOptionsMenu
/**
* This method is called when the user click on an item in the menu
*
* @param item
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
item.setChecked(true);
// Handle item selection
switch (item.getItemId()) {
case R.id.sub_menu_item_all:
mCurrentLogView = CURR_LIST_ALL_LOG;
mListHeader.setText(R.string.all_calls_log_header_txt);
loadCurrCallLogsList(false);
break;
case R.id.sub_menu_item_in_only:
mCurrentLogView = CURR_LIST_INCOMING_LOG;
mListHeader.setText(R.string.received_calls_log_header_txt);
loadCurrCallLogsList(false);
break;
case R.id.sub_menu_item_out_only:
mCurrentLogView = CURR_LIST_OUTGOING_LOG;
mListHeader.setText(R.string.dialled_calls_log_header_txt);
loadCurrCallLogsList(false);
break;
case R.id.sub_menu_item_miss_only:
mCurrentLogView = CURR_LIST_MISSED_LOG;
mListHeader.setText(R.string.missed_calls_log_header_txt);
loadCurrCallLogsList(false);
break;
case R.id.menu_item_edit:
startModifyActivity();
break;
default:
return super.onOptionsItemSelected(item);
}
return (true);
} // end of method onOptionsItemSelected
/**
* This method is called when the user comes back to this activity from a
* sub activity
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (Activity.RESULT_OK != resultCode)
return;
switch (requestCode) {
case DialingUtils.REQ_CODE_ADD_NEW_CONTACT: // pass through
case DialingUtils.REQ_CODE_UPDATE_EXISTING_CONTACT:
// refresh the call log list
mCad.getCursor().requery();
mCad.notifyDataSetChanged();
break;
case DialingUtils.REQ_CODE_PICK_CONTACT:
DialingUtils.updateExistingContact(this, data.getData(),
mCallerInfo.mPhoneNumber, true);
break;
}
} // end of method onActivityResult
/**
/**
* This method load a filter version of the call logs
*
* @param filter
*/
private void loadFilteredData(final int filter) {
if( null != mDataCursor ) mDataCursor.close();
mDataCursor = null;
// see whether it is needed to recover the database
if (null == database) {
database = new DBAdapter(mContext);
database.open();
}
// read all the call logs from the database
mDataCursor = database.getFilteredCallLogs(filter);
return;
} // end of method loadFilterData
/**
* This method is called when the user press a key on the device We use this
* method to handle the press on the back key
*/
@Override
/**
* This method is called in order to load the data from the
* local database in a separated thread
*/
@Override
public synchronized void run() {
Looper.prepare();
synchronized (MyConstants.mCallLogsMutex) {
switch (mCurrentLogView) {
case CURR_LIST_ALL_LOG:
loadFilteredData(0);
mHandler.sendEmptyMessage(SHOW_ALL_LOG);
break;
case CURR_LIST_MISSED_LOG:
loadFilteredData(CallLog.Calls.MISSED_TYPE);
mHandler.sendEmptyMessage(SHOW_MISSED_LOG);
break;
case CURR_LIST_OUTGOING_LOG:
loadFilteredData(CallLog.Calls.OUTGOING_TYPE);
mHandler.sendEmptyMessage(SHOW_OUTGOING_LOG);
break;
case CURR_LIST_INCOMING_LOG:
loadFilteredData(CallLog.Calls.INCOMING_TYPE);
mHandler.sendEmptyMessage(SHOW_INCOMING_LOG);
break;
}
} // end of synch block
} // end of method run
} // end of class CallLogsList
最佳答案
我已经找到原因,解决方法如下:当您必须处理游标或数据库时,只需避免使用 Activity.managedQuery(...) 和 Activity.startManagingCursor(...)。文档说它们确实已被弃用。
关于安卓 android.database.StaleDataException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10552780/
我们使用 Azure 弹性池,生成多个客户端数据库和一个引用客户端数据库的主数据库。 我们已经拥有多个数据库,并且正在开发新版本的代码。我们使用 EF6 代码优先。当我们对模型进行更改(添加属性)时,
我们使用 Azure 弹性池,生成多个客户端数据库和一个引用客户端数据库的主数据库。 我们已经拥有多个数据库,并且正在开发新版本的代码。我们使用 EF6 代码优先。当我们对模型进行更改(添加属性)时,
我希望将一些信息分发到不同的机器上,以便在没有任何网络开销的情况下实现高效和极快的访问。数据存在于关系模式中,实体之间的关系是“加入”的要求,但根本不是写入数据库的要求(它会离线生成)。 我非常相信
我使用 GrapheneDB 来托管我的 neo4j 数据库 (db)。 问题 我有 N客户并且正在寻找自动分离他们的内容(他们独特的数据库)的方法,以便: 它不重叠数据 操作速度不受影响。 选项 1
当服务器开始工作(Tomcat)时,日志显示此错误: org.springframework.beans.factory.BeanDefinitionStoreException: Invalid b
我在 Oracle 数据库实例中按以下方式创建了一个触发器。 CREATE OR REPLACE TRIGGER after_logon_on_database AFTER LOGON ON DATA
原谅我的无知,我是数据库约定的初学者。 这是我的 SQLite 代码:(由我的数据库浏览器自动生成) CREATE TABLE `ResearchItems` ( `ID` INTEGER NO
是的是的是的,我已经在整个互联网上搜索过这个问题。一些结果发现,甚至来自 Stackoverflow。但是他们中的大多数人说“你应该自动加载数据库”,或者“parent::__construct();
我正在创建一个 Mac 应用程序,它将一些数据保存到 SQLite 数据库中。问题是:当我关闭数据库并再次打开时,数据不存在了。这是我的代码: NSString *sql = [NSString st
我正在建立一个网站,我打算发布各种帖子,比如教程、文章等。我打算用 php 来管理它,但是当涉及到存储每个帖子的内容时,将要显示的文本,更好的选择是:使用单独的文本文件还是将其添加为数据库中的每个条目
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 3 年前。 Improve this qu
对不起,这个关键字对我来说没有任何意义...有人可以给我一个定义吗? 提前致谢... 最佳答案 这是一个品牌。 http://pervasive.com/这是他们的数据库产品的链接 http://ww
我已经在 docker 版本 1.10.1 的 docker 镜像中安装了 PostgreSQL 9.4.6。根据这张官方图片: https://github.com/docker-library/p
当我的 android 应用程序尝试读取 android 短信数据库时,我遇到了这个崩溃。读取android短信数据库的代码类似于下面的代码 fragment : String SMS_URI = "
我有一个 public kit repo,我推送了 v1.0.3 并具有以下结构 go -database --database.go --go.mod --go.sum 我需要它 require g
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 9 年前。 Improve this qu
我们正在使用MySQL数据库在Go中创建一个Web应用程序。我们的用户一次只能拥有一个活跃的客户端。就像Spotify一样,您一次只能在一台设备上听音乐。为此,我制作了一个映射,将用户ID和作为其值的
我已经尝试在 PostgreSQL 中创建数据库好几天了,遇到了几个问题,但似乎卡住了。 我在 PostgreSQL 中手动创建了一个名为 postgres_development 的数据库,因为 b
我正在创建一个 iMessage 应用程序,它需要连接到与我的常规应用程序相同的数据库。 我调用 FirebaseApp.configure() 并对用户进行身份验证,但出于某种原因,在所有 Data
就像std::unordered_map但所有数据都应存储在磁盘上而不是内存中。 按照我的理解,应该做两部分:索引和存储。我已经学习了一些关于索引的数据结构,比如 Linear-Hash 或 B-Tr
我是一名优秀的程序员,十分优秀!