cursor过滤android
Ⅰ 在移动前端中,android设备如何去除cursor-pointer的点击高亮
ead>
<script type="text/javascript">
function mOver(object)
{
object.color="red";
}
function mOut(object)
{
object.color="blue";
}
</script>
<body>
<font style="cursor: pointer"
onclick="window.location.href='http://www..com'" onmouseover="mOver(this)" onmouseout="mOut(this)">欢迎访问!</font>
</body>
</html>
cursor:hand 与 cursor:pointer 的效果是一样,都像手形光标。但用FireFox浏览时才注意到使用cursor:hand在FireFox里并被支持。
cursor:hand :IE完全支持。但是在firefox是不支持的,没有效果。
Ⅱ android中用cursor游标取数据库数据
把读取的数据存起来就可以了~
ArrayList<HashMap<String,Object>>temp=newArrayList<HashMap<String,Object>>();
if(cursor.moveToFirst()){
do{
HashMap<String,Object>map=newHashMap<String,Object>();
Stringname=cursor.getString(cursor.getColumnIndex("fromuser"));
Stringtoname=cursor.getString(cursor.getColumnIndex("touser"));
Stringcontent=cursor.getString(cursor.getColumnIndex("content"));
Stringdate=cursor.getString(cursor.getColumnIndex("date"));
Stringtype=cursor.getString(cursor.getColumnIndex("type"));
map.put("fromuser",name);
//其他数据同
temp.add(map);
}while(cursor.moveToNext());
}
//读取数据
Stringname1=temp.get(1).get("name").toString();
Ⅲ Android如何检测 Cursor 泄漏
有一些泄漏在代码中难以察觉,但程序长时间运行后必然会出现异常。同时该方法同样适合于其他需要检测资源泄露的情况。最近发现某蔬菜手机连接程序在查询媒体存储(MEdiaProvider)数据库时出现严重 Cursor 泄漏现象,运行一段时间后会导致系统中所有使用到该数据库的程序无法使用。另外在工作中也常发现有些应用有 Cursor 泄漏现象,由于需要长时间运行才会出现异常,所以有的此类 bug 很长时间都没被发现。但是一旦 Cursor 泄漏累计到一定数目(通常为数百个)必然会出现无法查询数据库的情况,只有等数据库服务所在进程死掉重启才能恢复正常。通常的出错信息如下,指出某 pid 的程序打开了 866 个 Cursor 没有关闭,导致了 exception:3634 3644 E JavaBinder: *** Uncaught remote exception! (Exceptions are not yet supported across processes.) 3634 3644 E JavaBinder: android.database.: Cursor window allocation of 2048 kb failed. # Open Cursors=866 (# cursors opened by pid 1565=866) 3634 3644 E JavaBinder: at android.database.CursorWindow.(CursorWindow.java:104) 3634 3644 E JavaBinder: at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198) 3634 3644 E JavaBinder: at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:147) 3634 3644 E JavaBinder: at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:141) 3634 3644 E JavaBinder: at android.database.CursorToBulkCursorAdaptor.getBulkCursorDescriptor(CursorToBulkCursorAdaptor.java:143) 3634 3644 E JavaBinder: at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:118) 3634 3644 E JavaBinder: at android.os.Binder.execTransact(Binder.java:367) 3634 3644 E JavaBinder: at dalvik.system.NativeStart.run(Native Method)1. Cursor 检测原理在Cursor 对象被 JVM 回收运行到 finalize() 方法的时候,检测 close() 方法有没有被调用,此办法在 ContentResolver 里面也得到应用。简化后的示例代码如下:import android.database.Cursor; import android.database.CursorWrapper; import android.util.Log; public class TestCursor extends CursorWrapper { private static final String TAG = "TestCursor"; private boolean mIsClosed = false; private Throwable mTrace; public TestCursor(Cursor c) { super(c); mTrace = new Throwable("Explicit termination method 'close()' not called"); } @Override public void close() { mIsClosed = true; } @Override public void finalize() throws Throwable { try { if (mIsClosed != true) { Log.e(TAG, "Cursor leaks", mTrace); } } finally { super.finalize(); } } }然后查询的时候,把 TestCursor 作为查询结果返回给 APP:return new TestCursor(cursor); // cursor 是普通查询得到的结果,例如从 ContentProvider.query()该方法同样适合于所有需要检测显式释放资源方法没有被调用的情形,是一种通用方法。但在 finalize() 方法里检测需要注意。优点:准确。因为该资源在 Cursor 对象被回收时仍没被释放,肯定是发生了资源泄露。缺点:依赖于 finalize() 方法,也就依赖于 JVM 的垃圾回收策略。例如某 APP 现在有 10 个 Cursor 对象泄露,并且这 10 个对象已经不再被任何引用指向处于可回收状态,但是 JVM 可能并不会马上回收(时间不可预测),如果你现在检查不能够发现问题。另外,在某些情况下就算对象被回收 finalize() 可能也不会执行,也就是不能保证检测出所有问题。关于 finalize() 更多信息可以参考《Effective Java 2nd Edition》的 Item 7: Avoid Finalizers2. 使用方法对于APP 开发人员从GINGERBREAD 开始 Android 就提供了 StrictMode 工具协助开发人员检查是否不小心地做了一些不该有的操作。使用方法是在 Activity 里面设置 StrictMode,下面的例子是打开了检查泄漏的 SQLite 对象以及 Closeable 对象(普通 Cursor/FileInputStream 等)的功能,发现有违规情况则记录 log 并使程序强行退出。import android.os.StrictMode; public class TestActivity extends Activity { private static final boolean DEVELOPER_MODE = true; public void onCreate() { if (DEVELOPER_MODE) { StrictMode.setVMPolicy(new StrictMode.VMPolicy.Builder() .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .penaltyDeath() .build()); } super.onCreate(); } }对于framework 开发人员如果是通过 ContentProvider 提供数据库数据,在 ContentResolver 里面已有 CloseGuard 类实行类似检测,但需要自行打开(上例也是打开 CloseGuard):CloseGuard.setEnabled(true);更值得推荐的办法是按照本文第一节中的检测原理,在 ContentResolver 内部类 CursorWrapperInner 里面加入。其他需要检测类似于资源泄漏的,同样可以使用该检测原理。3. 容易出错的地方忘记调用 close() 这种低级错误没什么好说的,这种应该也占不小的比例。下面说说不太明显的例子。提前返回有时候粗心会犯这种错误,在 close() 调用之前就 return 了,特别是函数比较大逻辑比较复杂时更容易犯错。这种情况可以通过把 close() 放在 finally 代码块解决。private void method() { Cursor cursor = query(); // 假设 query() 是一个查询数据库返回 Cursor 结果的函数 if (flag == false) { // !!提前返回 return; } cursor.close(); }类的成员变量假设类里面有一个在类全局有效的成员变量,在方法 A 获取了查询结果,后面在其他地方又获取了一次查询结果,那么第二次查询的时候就应该先把前面一个 Cursor 对象关闭。public class TestCursor { private Cursor mCursor; private void methodA() { mCursor = query(); } private void methodB() { // !!必须先关闭上一个 cursor 对象 mCursor = query(); } }注意:曾经遇到过有人对 mCursor 感到疑惑,明明是同一个变量为什么还需要先关闭?首先 mCursor 是一个 Cursor 对象的引用,在 methodA 时 mCursor 指向了 query() 返回的一个 Cursor 对象 1;在 methodB() 时它又指向了返回的另外一个 Cursor 对象 2。在指向 Cursor 对象 2 之前必须先关闭 Cursor 对象 1,否则就出现了 Cursor 对象 1 在 finalize() 之前没有调用 close() 的情况。异常处理打开和关闭 Cursor 之间的代码出现 exception,导致没有跑到关闭的地方:try { Cursor cursor = query(); // 中间省略某些出现异常的代码 cursor.close(); } catch (Exception e) { // !!出现异常没跑到 cursor.close() }这种情况应该把 close() 放到 finally 代码块里面:Cursor cursor = null; try { cursor = query(); // 中间省略某些出现异常的代码 } catch (Exception e) { // 出现异常 } finally { if (cursor != null) cursor.close(); }4. 总结思考在finalize() 里面检测是可行的,且基本可以满足需要。针对 finalize() 执行时间不确定以及可能不执行的问题,可以通过记录目前打开没关闭的 Cursor 数量来部分解决,超过一定数目发出警告,两种手段相结合。还有没有其他检测办法呢?有,在 Cursor 构造方法以及 close() 方法添加 log,运行一段时间后检查 log 看哪个地方没有关闭。简化代码如下:import android.database.Cursor; import android.database.CursorWrapper; import android.util.Log; public class TestCursor extends CursorWrapper { private static final String TAG = "TestCursor"; private Throwable mTrace; public TestCursor(Cursor c) { super(c); mTrace = new Throwable("cusor opened here"); Log.d(TAG, "Cursor " + this.hashCode() + " opened, stacktrace is: ", mTrace); } @Override public void close() { mIsClosed = true; Log.d(TAG, "Cursor " + this.hashCode() + " closed."); } }检查时看某个 hashCode() 的 Cursor 有没有调用过 close() 方法,没有的话说明资源有泄露。这种方法优点是同样准确,且更可靠。
Ⅳ 如何检测 Android Cursor 泄漏
有一些泄漏在代码中难以察觉,但程序长时间运行后必然会出现异常。同时该方法同样适合于其他需要检测资源泄露的情况。 最近发现某蔬菜手机连接程序在查询媒体存储(MediaProvider)数据库时出现严重 Cursor 泄漏现象,运行一段时间后会导致系统中所有使用到该数据库的程序无法使用。另外在工作中也常发现有些应用有 Cursor 泄漏现象,由于需要长时间运行才会出现异常,所以有的此类 bug 很长时间都没被发现。但是一旦 Cursor 泄漏累计到一定数目(通常为数百个)必然会出现无法查询数据库的情况,只有等数据库服务所在进程死掉重启才能恢复正常。通常的出错信息如下,指出某 pid 的程序打开了 866 个 Cursor 没有关闭,导致了 exception:3634 3644 E JavaBinder: *** Uncaught remote exception! (Exceptions are not yet supported across processes.) 3634 3644 E JavaBinder: android.database.: Cursor window allocation of 2048 kb failed. # Open Cursors=866 (# cursors opened by pid 1565=866) 3634 3644 E JavaBinder: at android.database.CursorWindow.(CursorWindow.java:104) 3634 3644 E JavaBinder: at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198) 3634 3644 E JavaBinder: at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:147) 3634 3644 E JavaBinder: at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:141) 3634 3644 E JavaBinder: at android.database.CursorToBulkCursorAdaptor.getBulkCursorDescriptor(CursorToBulkCursorAdaptor.java:143) 3634 3644 E JavaBinder: at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:118) 3634 3644 E JavaBinder: at android.os.Binder.execTransact(Binder.java:367) 3634 3644 E JavaBinder: at dalvik.system.NativeStart.run(Native Method) 1. Cursor 检测原理在Cursor 对象被 JVM 回收运行到 finalize() 方法的时候,检测 close() 方法有没有被调用,此办法在 ContentResolver 里面也得到应用。简化后的示例代码如下: 1import android.database.Cursor; 2import android.database.CursorWrapper; 3import android.util.Log; 4 5publicclass TestCursor extends CursorWrapper { 6privatestaticfinal String TAG = "TestCursor"; 7privateboolean mIsClosed = false; 8private Throwable mTrace; 910public TestCursor(Cursor c) { 11super(c); 12 mTrace = new Throwable("Explicit termination method 'close()' not called"); 13 } 1415 @Override 16publicvoid close() { 17 mIsClosed = true; 18 } 1920 @Override 21publicvoid finalize() throws Throwable { 22try { 23if (mIsClosed != true) { 24 Log.e(TAG, "Cursor leaks", mTrace); 25 } 26 } finally { 27super.finalize(); 28 } 29 } 30 }然后查询的时候,把 TestCursor 作为查询结果返回给 APP:1returnnew TestCursor(cursor); // cursor 是普通查询得到的结果,例如从 ContentProvider.query() 该方法同样适合于所有需要检测显式释放资源方法没有被调用的情形,是一种通用方法。但在 finalize() 方法里检测需要注意优点:准确。因为该资源在 Cursor 对象被回收时仍没被释放,肯定是发生了资源泄露。缺点:依赖于 finalize() 方法,也就依赖于 JVM 的垃圾回收策略。例如某 APP 现在有 10 个 Cursor 对象泄露,并且这 10 个对象已经不再被任何引用指向处于可回收状态,但是 JVM 可能并不会马上回收(时间不可预测),如果你现在检查不能够发现问题。另外,在某些情况下就算对象被回收 finalize() 可能也不会执行,也就是不能保证检测出所有问题。关于 finalize() 更多信息可以参考《Effective Java 2nd Edition》的 Item 7: Avoid Finalizers2. 使用方法对于APP 开发人员从GINGERBREAD 开始 Android 就提供了 StrictMode 工具协助开发人员检查是否不小心地做了一些不该有的操作。使用方法是在 Activity 里面设置 StrictMode,下面的例子是打开了检查泄漏的 SQLite 对象以及 Closeable 对象(普通 Cursor/FileInputStream 等)的功能,发现有违规情况则记录 log 并使程序强行退出。 1import android.os.StrictMode; 2 3publicclass TestActivity extends Activity { 4privatestaticfinalboolean DEVELOPER_MODE = true; 5publicvoid onCreate() { 6if (DEVELOPER_MODE) { 7 StrictMode.setVMPolicy(new StrictMode.VMPolicy.Builder() 8 .detectLeakedSqlLiteObjects() 9 .detectLeakedClosableObjects() 10 .penaltyLog() 11 .penaltyDeath() 12 .build()); 13 } 14super.onCreate(); 15 } 16 } 对于framework 开发人员如果是通过 ContentProvider 提供数据库数据,在 ContentResolver 里面已有 CloseGuard 类实行类似检测,但需要自行打开(上例也是打开 CloseGuard):1 CloseGuard.setEnabled(true);更值得推荐的办法是按照本文第一节中的检测原理,在 ContentResolver 内部类 CursorWrapperInner 里面加入。其他需要检测类似于资源泄漏的,同样可以使用该检测原理。3. 容易出错的地方忘记调用 close() 这种低级错误没什么好说的,这种应该也占不小的比例。下面说说不太明显的例子。提前返回有时候粗心会犯这种错误,在 close() 调用之前就 return 了,特别是函数比较大逻辑比较复杂时更容易犯错。这种情况可以通过把 close() 放在 finally 代码块解决1privatevoid method() { 2 Cursor cursor = query(); // 假设query() 是一个查询数据库返回 Cursor 结果的函数3if (flag == false) { //!!提前返回4return; 5 } 6 cursor.close(); 7 } 类的成员变量假设类里面有一个在类全局有效的成员变量,在方法 A 获取了查询结果,后面在其他地方又获取了一次查询结果,那么第二次查询的时候就应该先把前面一个 Cursor 对象关闭。 1publicclass TestCursor { 2private Cursor mCursor; 3 4privatevoid methodA() { 5 mCursor = query(); 6 } 7 8privatevoid methodB() { 9//!!必须先关闭上一个 cursor 对象10 mCursor = query(); 11 } 12 }注意:曾经遇到过有人对 mCursor 感到疑惑,明明是同一个变量为什么还需要先关闭?首先 mCursor 是一个 Cursor 对象的引用,在 methodA 时 mCursor 指向了 query() 返回的一个 Cursor 对象 1;在 methodB() 时它又指向了返回的另外一个 Cursor 对象 2。在指向 Cursor 对象 2 之前必须先关闭 Cursor 对象 1,否则就出现了 Cursor 对象 1 在 finalize() 之前没有调用 close() 的情况。异常处理打开和关闭 Cursor 之间的代码出现 exception,导致没有跑到关闭的地方:1try { 2 Cursor cursor = query(); 3// 中间省略某些出现异常的代码4 cursor.close(); 5 } catch (Exception e) { 6//!!出现异常没跑到 cursor.close()7 }这种情况应该把 close() 放到 finally 代码块里面: 1 Cursor cursor = null; 2try { 3 cursor = query(); 4// 中间省略某些出现异常的代码 5 } catch (Exception e) { 6// 出现异常 7 } finally { 8if (cursor != null) 9 cursor.close(); 10 }4. 总结思考在finalize() 里面检测是可行的,且基本可以满足需要。针对 finalize() 执行时间不确定以及可能不执行的问题,可以通过记录目前打开没关闭的 Cursor 数量来部分解决,超过一定数目发出警告,两种手段相结合。还有没有其他检测办法呢?有,在 Cursor 构造方法以及 close() 方法添加 log,运行一段时间后检查 log 看哪个地方没有关闭。简化代码如下: 1import android.database.Cursor; 2import android.database.CursorWrapper; 3import android.util.Log; 4 5publicclass TestCursor extends CursorWrapper { 6privatestaticfinal String TAG = "TestCursor"; 7private Throwable mTrace; 8 9public TestCursor(Cursor c) { 10super(c); 11 mTrace = new Throwable("cusor opened here"); 12 Log.d(TAG, "Cursor " + this.hashCode() + " opened, stacktrace is: ", mTrace); 13 } 1415 @Override 16publicvoid close() { 17 mIsClosed = true; 18 Log.d(TAG, "Cursor " + this.hashCode() + " closed."); 19 } 20 }检查时看某个 hashCode() 的 Cursor 有没有调用过 close() 方法,没有的话说明资源有泄露。这种方法优点是同样准确,且更可靠。
Ⅳ 如何检测 Android Cursor 泄漏
在 Cursor 构造方法以及 close() 方法添加 log,运行一段时间后检查 log 看哪个地方没有关闭。简化代码如下:
1 import android.database.Cursor;
2 import android.database.CursorWrapper;
3 import android.util.Log;
4
5 public class TestCursor extends CursorWrapper {
6 private static final String TAG = "TestCursor";
7 private Throwable mTrace;
8
9 public TestCursor(Cursor c) {
10 super(c);
11 mTrace = new Throwable("cusor opened here");
12 Log.d(TAG, "Cursor " + this.hashCode() + " opened, stacktrace is: ", mTrace);
13 }
14
15 @Override
16 public void close() {
17 mIsClosed = true;
18 Log.d(TAG, "Cursor " + this.hashCode() + " closed.");
19 }
20 }
求采纳
Ⅵ 如何检测 Android Cursor 泄漏
Cursor 检测原理
在 Cursor 对象被 JVM 回收运行到 finalize() 方法的时候,检测 close() 方法有没有被调用,此办法在 ContentResolver 里面也得到应用。简化后的示例代码如下:
1 import android.database.Cursor;
2 import android.database.CursorWrapper;
3 import android.util.Log;
4
5 public class TestCursor extends CursorWrapper {
6 private static final String TAG = "TestCursor";
7 private boolean mIsClosed = false;
8 private Throwable mTrace;
9
10 public TestCursor(Cursor c) {
11 super(c);
12 mTrace = new Throwable("Explicit termination method 'close()' not called");
13 }
14
15 @Override
16 public void close() {
17 mIsClosed = true;
18 }
19
20 @Override
21 public void finalize() throws Throwable {
22 try {
23 if (mIsClosed != true) {
24 Log.e(TAG, "Cursor leaks", mTrace);
25 }
26 } finally {
27 super.finalize();
28 }
29 }
30 }
然后查询的时候,把 TestCursor 作为查询结果返回给 APP:
1 return new TestCursor(cursor); // cursor 是普通查询得到的结果,例如从 ContentProvider.query()
该方法同样适合于所有需要检测显式释放资源方法没有被调用的情形,是一种通用方法。但在 finalize() 方法里检测需要注意
优点:准确。因为该资源在 Cursor 对象被回收时仍没被释放,肯定是发生了资源泄露。
缺点:依赖于 finalize() 方法,也就依赖于 JVM 的垃圾回收策略。例如某 APP 现在有 10 个 Cursor 对象泄露,并且这 10 个对象已经不再被任何引用指向处于可回收状态,但是 JVM 可能并不会马上回收(时间不可预测),如果你现在检查不能够发现问题。另外,在某些情况下就算对象被回收 finalize() 可能也不会执行,也就是不能保证检测出所有问题。关于 finalize() 更多信息可以参考《Effective Java 2nd Edition》的 Item 7: Avoid Finalizers。
Ⅶ CursorAdapter如何实现关键字过滤
其中Filterable接口定义了getFilter()这个接口。 CursorFilterClient定义如下接口: convertToString(Cursor cursor); Cursor runQueryOnBackgroundThread(CharSequence constraint); Cursor getCursor(); void changeCursor(Cursor cursor); 注意:CursorFilter.CursorFilterClient是非public的,所以只有文档中看不到它,在源码中才能看到它。 CursorAdapter.java文件如下 package android.widget;-----------------------------------省略---------------------------------public abstract class CursorAdapter extends BaseAdapter implements Filterable, CursorFilter.CursorFilterClient { /** * This field should be made private, so it is hidden from the SDK. * {@hide}*/ protected boolean mDataValid; /** * This field should be made private, so it is hidden from the SDK. * {@hide}*/ protected boolean mAutoRequery; /** * This field should be made private, so it is hidden from the SDK. * {@hide}*/ protected Cursor mCursor;-----------------------------------省略--------------------------------- protected CursorFilter mCursorFilter; /** * This field should be made private, so it is hidden from the SDK. * {@hide}*/ protected FilterQueryProvider mFilterQueryProvider;-----------------------------------省略--------------------------------- public Cursor getCursor() { return mCursor; }-----------------------------------省略--------------------------------- public void changeCursor(Cursor cursor) {-----------------------------------省略--------------------------------- }-----------------------------------省略--------------------------------- public CharSequence convertToString(Cursor cursor) { return cursor == null ? "" : cursor.toString(); }-----------------------------------省略--------------------------------- public Cursor runQueryOnBackgroundThread(CharSequence constraint) { if (mFilterQueryProvider != null) { return mFilterQueryProvider.runQuery(constraint); } return mCursor; } public Filter getFilter() { if (mCursorFilter == null) { mCursorFilter = new CursorFilter(this); } return mCursorFilter; }-----------------------------------省略--------------------------------- public FilterQueryProvider getFilterQueryProvider() { return mFilterQueryProvider; }-----------------------------------省略--------------------------------- public void setFilterQueryProvider(FilterQueryProvider filterQueryProvider) { mFilterQueryProvider = filterQueryProvider; }-----------------------------------省略---------------------------------} CursorFilter文件如下: package android.widget;import android.database.Cursor;class CursorFilter extends Filter { CursorFilterClient mClient; interface CursorFilterClient { CharSequence convertToString(Cursor cursor); Cursor runQueryOnBackgroundThread(CharSequence constraint); Cursor getCursor(); void changeCursor(Cursor cursor); } CursorFilter(CursorFilterClient client) { mClient = client; } @Override public CharSequence convertResultToString(Object resultValue) { return mClient.convertToString((Cursor) resultValue); } @Override protected FilterResults performFiltering(CharSequence constraint) { Cursor cursor = mClient.runQueryOnBackgroundThread(constraint); FilterResults results = new FilterResults(); if (cursor != null) { results.count = cursor.getCount(); results.values = cursor; } else { results.count = 0; results.values = null; } return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { Cursor oldCursor = mClient.getCursor(); if (results.values != null && results.values != oldCursor) { mClient.changeCursor((Cursor) results.values); } }} 关于Filter的更多内容参见《关键字过滤器Filter》。 调用CursorAdapter的getFilter方法得到一个Filter,调用它的filter (CharSequence constraint)方法。其中constraint就是关键字。 注意1:如果不给CursorAdapter设置FilterQueryProvider(通过setFilterQueryProvider方法), 那么就需要重载Cursor runQueryOnBackgroundThread(CharSequence constraint)来实现对数据库的过滤查询。 当然FilterQueryProvider其实就是在它唯一的方法public abstract Cursor runQuery (CharSequence constraint)里面实现对数据库的过滤查询。
Ⅷ android 分离cursor
不太了解你的需求,一般从数据库拿到cursor,转换成列表list使用的,在转换列表的时候可以分2个列表,比如:
ArrayList<E> list1 = new ArrayList<E>();
ArrayList<E2> list2 = new ArrayList<E2>();
Cursor cursor = managedQuery(getIntent().getData(), list_column.PROJECTION,null,null ,null);
while(cursor.moveToNext()){
E e = new E();//这个是你第一个列表里面装的模型
E2 e2 = new E2();//这个是第二个列表里面的模型
e.item1 = cursor.getString(0);//具体按照自己的类型分,我以String类型为例
e.item2 = cursor.getString(1);
e.item3 = cursor.getString(2);
e.item4 = cursor.getString(3);
e.item5 = cursor.getString(4);
e2.item1 = cursor.getString(5);//第二的模型的数据
e2.item2 = cursor.getString(6);
e2.item3 = cursor.getString(7);
e2.item4 = cursor.getString(8);
e2.item5 = cursor.getString(9);
}
这样就分成2个列表了。你看看这样符合你的需求不
Ⅸ 如何检测 Android Cursor 泄漏
本文介绍如何在 Android 检测 Cursor 泄漏的原理以及使用方法,还指出几种常见的出错示例。有一些泄漏在代码中难以察觉,但程序长时间运行后必然会出现异常。同时该方法同样适合于其他需要检测资源泄露的情况。
最近发现某蔬菜手机连接程序在查询媒体存储(MediaProvider)数据库时出现严重
Cursor 泄漏现象,运行一段时间后会导致系统中所有使用到该数据库的程序无法使用。另外在工作中也常发现有些应用有 Cursor
泄漏现象,由于需要长时间运行才会出现异常,所以有的此类 bug 很长时间都没被发现。
但是一旦 Cursor 泄漏累计到一定数目(通常为数百个)必然会出现无法查询数据库的情况,只有等数据库服务所在进程死掉重启才能恢复正常。通常的出错信息如下,指出某 pid 的程序打开了 866 个 Cursor 没有关闭,导致了 exception:
3634 3644 E JavaBinder: *** Uncaught remote exception! (Exceptions are not yet supported across processes.)
3634
3644 E JavaBinder: android.database.:
Cursor window allocation of 2048 kb failed. # Open Cursors=866 (#
cursors opened by pid 1565=866)
3634 3644 E JavaBinder: at android.database.CursorWindow.(CursorWindow.java:104)
3634 3644 E JavaBinder: at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
3634 3644 E JavaBinder: at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:147)
3634 3644 E JavaBinder: at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:141)
3634
3644 E JavaBinder: at
android.database.CursorToBulkCursorAdaptor.getBulkCursorDescriptor(CursorToBulkCursorAdaptor.java:143)
3634 3644 E JavaBinder: at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:118)
3634 3644 E JavaBinder: at android.os.Binder.execTransact(Binder.java:367)
3634 3644 E JavaBinder: at dalvik.system.NativeStart.run(Native Method)
1. Cursor 检测原理
在 Cursor 对象被 JVM 回收运行到 finalize() 方法的时候,检测 close() 方法有没有被调用,此办法在 ContentResolver 里面也得到应用。简化后的示例代码如下:
import android.database.Cursor;
import android.database.CursorWrapper;
import android.util.Log;
public class TestCursor extends CursorWrapper {
private static final String TAG = "TestCursor";
private boolean mIsClosed = false;
private Throwable mTrace;
public TestCursor(Cursor c) {
super(c);
mTrace = new Throwable("Explicit termination method 'close()' not called");
}
@Override
public void close() {
mIsClosed = true;
}
@Override
public void finalize() throws Throwable {
try {
if (mIsClosed != true) {
Log.e(TAG, "Cursor leaks", mTrace);
}
} finally {
super.finalize();
}
}
}
然后查询的时候,把 TestCursor 作为查询结果返回给 APP:
1 return new TestCursor(cursor); // cursor 是普通查询得到的结果,例如从 ContentProvider.query()
该方法同样适合于所有需要检测显式释放资源方法没有被调用的情形,是一种通用方法。但在 finalize() 方法里检测需要注意
优点:准确。因为该资源在 Cursor 对象被回收时仍没被释放,肯定是发生了资源泄露。
缺点:依赖于 finalize() 方法,也就依赖于 JVM 的垃圾回收策略。例如某
APP 现在有 10 个 Cursor 对象泄露,并且这 10 个对象已经不再被任何引用指向处于可回收状态,但是 JVM
可能并不会马上回收(时间不可预测),如果你现在检查不能够发现问题。另外,在某些情况下就算对象被回收 finalize()
可能也不会执行,也就是不能保证检测出所有问题。关于 finalize() 更多信息可以参考《Effective Java 2nd
Edition》的 Item 7: Avoid Finalizers
Ⅹ 如何检测 Android Cursor 泄漏
在
Cursor
对象被
JVM
回收运行到
finalize()
方法的时候,检测
close()
方法有没有被调用,此办法在
ContentResolver
里面也得到应用。简化后的示例代码如下:
import
android.database.Cursor;
import
android.database.CursorWrapper;
import
android.util.Log;
public
class
TestCursor
extends
CursorWrapper
{
private
static
final
String
TAG
=
"TestCursor";
private
boolean
mIsClosed
=
false;
private
Throwable
mTrace;
public
TestCursor(Cursor
c)
{
super(c);
mTrace
=
new
Throwable("Explicit
termination
method
'close()'
not
called");
}
@Override
public
void
close()
{
mIsClosed
=
true;
}
@Override
public
void
finalize()
throws
Throwable
{
try
{
if
(mIsClosed
!=
true)
{
Log.e(TAG,
"Cursor
leaks",
mTrace);
}
}
finally
{
super.finalize();
}
}
}
然后查询的时候,把
TestCursor
作为查询结果返回给
APP:
1
return
new
TestCursor(cursor);
//
cursor
是普通查询得到的结果,例如从
ContentProvider.query()
该方法同样适合于所有需要检测显式释放资源方法没有被调用的情形,是一种通用方法。但在
finalize()
方法里检测需要注意
优点:准确。因为该资源在
Cursor
对象被回收时仍没被释放,肯定是发生了资源泄露。
缺点:依赖于
finalize()
方法,也就依赖于
JVM
的垃圾回收策略。例如某
APP
现在有
10
个
Cursor
对象泄露,并且这
10
个对象已经不再被任何引用指向处于可回收状态,但是
JVM
可能并不会马上回收(时间不可预测),如果你现在检查不能够发现问题。另外,在某些情况下就算对象被回收
finalize()
可能也不会执行,也就是不能保证检测出所有问题。