Cursor详解---之源码中的注释

本文档详细介绍了Cursor接口的源码,包括Cursor的基本概念、功能及常用方法。Cursor作为数据库查询结果的载体,提供了随机读取数据的能力。文中列举了如getCount(), moveToFirst(), moveToNext()等方法的用法和注意事项,同时强调了Cursor在多线程环境下的同步问题。此外,还解释了字段类型常量,如FIELD_TYPE_NULL, FIELD_TYPE_INTEGER等的含义。" 93335745,8644888,前端通信:Node.js net模块与WebSocket实践,"['前端开发', 'WebSocket', 'Node.js', 'web服务器', '应用服务器']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 http://blog.youkuaiyun.com/wcs542882916

/*

 *Cursor详解---之源码中的注释

 */

 

//query()查询数据库结束后会返回Cursor对象,Cursor对象里封装了一张由查询结果组成的数据表(该数据表独立于数据库,互不影响)

//Cursor的结构好比游标卡尺,Cursor里放着一张数据表好比游标里放着刻度尺,移动之后读出数据

 

//源码注释常用方法说明——本人菜鸟中的菜鸟,不对请多多包涵和指正

 

package android.database;

 

import android.content.ContentResolver;

import android.net.Uri;

import android.os.Bundle;

 

import java.io.Closeable;

 

/**

 * This interface provides random read-write access to theresult set returned

 * by a database query.

 *

 * <p>

 * Cursor implementations are not required tobe synchronized so code using a

 * Cursor from multiple threads should performits own synchronization when

 * using the Cursor.

 * </p>

 * <p>

 * Implementations should subclass {@link AbstractCursor}.

 * </p>

 */

/*

 * Cursor接口提供对结果集合的随机存取,由数据库查询返回(只要不通过api更新这张表,就算数据库已发生变化它依然不变)。

 * Cursor的实现没有要求同步(相对异步),所以在多线程中使用Cursor时应该注意Cursor同步化。多线程就不说了。

 * 实现子类 AbstractCursor

 */

public interfaceCursor extendsCloseable {

   /*

    * Values returned by {@link #getType(int)}.These should be consistent with

    * the corresponding types defined inCursorWindow.h

    */

  

   /** Value returned by {@link #getType(int)} if the specifiedcolumn is null */

   static final int FIELD_TYPE_NULL= 0;

 

   /**

    * Value returned by {@link #getType(int)} if the specifiedcolumn type is

    * integer

    */

   static final int FIELD_TYPE_INTEGER= 1;

 

   /**

    * Value returned by {@link #getType(int)} if the specifiedcolumn type is

    * float

    */

   static final int FIELD_TYPE_FLOAT= 2;

 

   /**

    * Value returned by {@link #getType(int)} if the specifiedcolumn type is

    * string

    */

   static final int FIELD_TYPE_STRING= 3;

 

   /**

    * Value returned by {@link #getType(int)} if the specifiedcolumn type is

    * blob

    */

   static final int FIELD_TYPE_BLOB= 4;

 

   /**

    * Returns the numbers of rows in the cursor.

    *

    * @return the number of rows in the cursor.

    */

   //返回结果集的行数,每一行的位置从0开始编号,比如有3行,编号0,1,2

   int getCount();

 

   /**

    * Returns the current position of the cursorin the row set. The value is

    * zero-based. When the row set is first returnedthe cursor will be at

    * positon -1, which is before the first row. After thelast row is returned

    * another call to next() will leave the cursorpast the last entry, at a

    * position of count().

    *

    * @return the current cursor position.

    */

   //返回Cursor所在结果集上的当前位置(这个结果集以行为数据单位,相当于一张不变的数据表)

   //结果集的位置编号从0位置开始递增。Cursor-13位置是虚拟存在的,move方法都可以将Cursor移动到此处,但是都返回false

   //假设返回的结果集为3条数据getCount()的值为3,那么Cursor里包裹的实际数据表结构如下,至于-1位置的时候获取值不知道会返回什么。

   /*   Cursor    |    位置      |    _id\coloumName    |   PersonName    |    ...   |

    *          -->           -1(虚拟位置,move方法使用)

    *                           0                          0                            LiLei(第一行)

    *                           1                          1                            LiLi

    *                           2                          2                            HanMei(最后行)

    *                           3 (虚拟位置)

    */

   //当获取Cursor时指在-1位置,当Cursor移动到最后行,再移动一行则会指在3位置,返回3 == getCount();

   int getPosition();

 

   /**

    * Move the cursor by a relative amount,forward or backward, from the

    * current position. Positive offsets moveforwards, negative offsets move

    * backwards. If the final position is outsideof the bounds of the result

    * set then the resultant position will bepinned to-1 or count()depending

    * on whether the value is off the front or endof the set, respectively.

    *

    * <p>

    * This method will return true if therequested destination was reachable,

    * otherwise, it returns false. For example, ifthe cursor is at currently

    * on the second entry in the result set andmove(-5) is called,the

    * position will be pinned at -1, and false will bereturned.

    *

    * @param offset

    *           the offset to be applied from the current position.

    * @return whether the requested move fully succeeded.

    */

   /*

    * 从当前位置移动offset位,正直向前移动(向下),负值向后移动(向上)。移动到-1getCount()后就移动不了了(如果继续超出界限),始终移动在原地

    *

    * 如果移动的偏移量会超出界限,Cursor就会固定在-1getCount()位置上,并返回false

    * 问题:如果刚好移动到-1getCount()位置返回false还是true?答案是:false

    * 所有的move方法,移动到-1getCount()都是返回false,位置是虚拟存在的,实际不可抵达。意思是可以移动到此处,但是返回false告诉我们越界了。

    * */

   boolean move(int offset);

 

   /**

    * Move the cursor to an absolute position. Thevalid range of values is-1

    * &lt;= position &lt;= count.

    *

    * <p>

    * This method will return true if the requestdestination was reachable,

    * otherwise, it returns false.

    *

    * @param position

    *           the zero-based position to move to.

    * @return whether the requested move fully succeeded.

    */

   /*

    * Cursor移动到绝对位置,范围-1 <= position<= getCount();

    * 如果move-1getCount()返回false

    * */

   boolean moveToPosition(int position);

 

   /**

    * Move the cursor to the first row.

    *

    * <p>

    * This method will return false if the cursoris empty.

    *

    * @return whether the move succeeded.

    */

   //移动到第一行,0位置

   boolean moveToFirst();

 

   /**

    * Move the cursor to the last row.

    *

    * <p>

    * This method will return false if the cursoris empty.

    *

    * @return whether the move succeeded.

    */

   //移动到最后行getCount()-1位置

   boolean moveToLast();

 

   /**

    * Move the cursor to the next row.

    *

    * <p>

    * This method will return false if the cursoris already past the last

    * entry in the result set.

    *

    * @return whether the move succeeded.

    */

   //向下移动一行,超过最后行返回false

   boolean moveToNext();

 

   /**

    * Move the cursor to the previous row.

    *

    * <p>

    * This method will return false if the cursoris already before the first

    * entry in the result set.

    *

    * @return whether the move succeeded.

    */

   //向上移动一行,超过第一行返回false

   boolean moveToPrevious();

 

   /**

    * Returns whether the cursor is pointing tothe first row.

    *

    * @return whether the cursor is pointing at the first entry.

    */

   //是否是第一行

   boolean isFirst();

 

   /**

    * Returns whether the cursor is pointing tothe last row.

    *

    * @return whether the cursor is pointing at the last entry.

    */

   //是否是最后行

   boolean isLast();

 

   /**

    * Returns whether the cursor is pointing tothe position before the first

    * row.

    *

    * @return whether the cursor is before the first result.

    */

   //是否在第一行之前,即-1位置

   boolean isBeforeFirst();

 

   /**

    * Returns whether the cursor is pointing tothe position after the last

    * row.

    *

    * @return whether the cursor is after the last result.

    */

   //是否在最后行之后,即getCount()位置

   boolean isAfterLast();

 

   /**

    * Returns the zero-based index for the given column name, or-1 if the

    * column doesn't exist. If you expect thecolumn to exist use

    * {@link#getColumnIndexOrThrow(String)} instead, which willmake the error

    * more clear.

    *

    * @param columnName

    *           the name of the target column.

    * @return the zero-based column index for the given column name, or -1 if

    *        the column name does not exist.

    * @see #getColumnIndexOrThrow(String)

    */

   //返回给定列名所在列的索引,若列不存在则返回-1,比getColumnIndexOrThrow(String)更有效率

   //列索引从0开始递增

   int getColumnIndex(StringcolumnName);

 

   /**

    * Returns the zero-based index for the given column name, orthrows

    * {@linkIllegalArgumentException} if the column doesn'texist. If you're

    * not sure if a column will exist or not use

    * {@link#getColumnIndex(String)} and check for-1, which is moreefficient

    * than catching the exceptions.

    *

    * @param columnName

    *           the name of the target column.

    * @return the zero-based column index for the given column name

    * @see #getColumnIndex(String)

    * @throws IllegalArgumentException

    *            if the column does not exist

    */

   //返回给定列名所在列的索引,若不存在则抛出异常

   intgetColumnIndexOrThrow(String columnName)

        throwsIllegalArgumentException;

 

   /**

    * Returns the column name at the given zero-based column index.

    *

    * @param columnIndex

    *           the zero-based index of the target column.

    * @return the column name for the given column index.

    */

   //根据列名得到列的索引

   StringgetColumnName(intcolumnIndex);

 

   /**

    * Returns a string array holding the names ofall of the columns in the

    * result set in the order in which they werelisted in the result.

    *

    * @return the names of the columns returned in this query.

    */

   //返回所有列名

   String[]getColumnNames();

 

   /**

    * Return total number of columns

    *

    * @return number of columns

    */

   //获得列的数量

   int getColumnCount();

 

   /**

    * Returns the value of the requested column asa byte array.

    *

    * <p>

    * The result and whether this method throws anexception when the column

    * value is null or the column type is not ablob type is

    * implementation-defined.

    *

    * @param columnIndex

    *           the zero-based index of the target column.

    * @return the value of that column as a byte array.

    */

   byte[] getBlob(int columnIndex);

 

   /**

    * Returns the value of the requested column asa String.

    *

    * <p>

    * The result and whether this method throws anexception when the column

    * value is null or the column type is not astring type is

    * implementation-defined.

    *

    * @param columnIndex

    *           the zero-based index of the target column.

    * @return the value of that column as a String.

    */

   //将目标列的值作为字符串返回

   StringgetString(intcolumnIndex);

 

   /**

    * Retrieves the requested column text andstores it in the buffer provided.

    * If the buffer size is not sufficient, a newchar buffer will be allocated

    * and assigned to CharArrayBuffer.data

    *

    * @param columnIndex

    *           the zero-based index of the target column. if the target

    *           column is null, return buffer

    * @param buffer

    *           the buffer to copy the text into.

    */

   void copyStringToBuffer(int columnIndex,CharArrayBufferbuffer);

 

   /**

    * Returns the value of the requested column asa short.

    *

    * <p>

    * The result and whether this method throws anexception when the column

    * value is null, the column type is not anintegral type, or the integer

    * value is outside the range [<code>Short.MIN_VALUE</code>,

    * <code>Short.MAX_VALUE</code>] is implementation-defined.

    *

    * @param columnIndex

    *           the zero-based index of the target column.

    * @return the value of that column as a short.

    */

   short getShort(int columnIndex);

 

   /**

    * Returns the value of the requested column asanint.

    *

    * <p>

    * The result and whether this method throws anexception when the column

    * value is null, the column type is not anintegral type, or the integer

    * value is outside the range [<code>Integer.MIN_VALUE</code>,

    * <code>Integer.MAX_VALUE</code>] is implementation-defined.

    *

    * @param columnIndex

    *           the zero-based index of the target column.

    * @return the value of that column as anint.

    */

   int getInt(int columnIndex);

 

   /**

    * Returns the value of the requested column asa long.

    *

    * <p>

    * The result and whether this method throws anexception when the column

    * value is null, the column type is not anintegral type, or the integer

    * value is outside the range [<code>Long.MIN_VALUE</code>,

    * <code>Long.MAX_VALUE</code>] is implementation-defined.

    *

    * @param columnIndex

    *           the zero-based index of the target column.

    * @return the value of that column as a long.

    */

   long getLong(int columnIndex);

 

   /**

    * Returns the value of the requested column asa float.

    *

    * <p>

    * The result and whether this method throws anexception when the column

    * value is null, the column type is not afloating-point type, orthe

    * floating-point value is not representable as a<code>float</code> value

    * is implementation-defined.

    *

    * @param columnIndex

    *           the zero-based index of the target column.

    * @return the value of that column as a float.

    */

   float getFloat(int columnIndex);

 

   /**

    * Returns the value of the requested column asa double.

    *

    * <p>

    * The result and whether this method throws anexception when the column

    * value is null, the column type is not afloating-point type, orthe

    * floating-point value is not representable as a<code>double</code> value

    * is implementation-defined.

    *

    * @param columnIndex

    *           the zero-based index of the target column.

    * @return the value of that column as a double.

    */

   double getDouble(int columnIndex);

 

   /**

    * Returns data type of the given column'svalue. The preferred type of the

    * column is returned but the data may beconverted to other types as

    * documented in the get-type methods such as{@link #getInt(int)},

    * {@link#getFloat(int)} etc.

    * <p>

    * Returned column types are

    * <ul>

    * <li>{@link #FIELD_TYPE_NULL}</li>

    * <li>{@link #FIELD_TYPE_INTEGER}</li>

    * <li>{@link #FIELD_TYPE_FLOAT}</li>

    * <li>{@link #FIELD_TYPE_STRING}</li>

    * <li>{@link #FIELD_TYPE_BLOB}</li>

    * </ul>

    * </p>

    *

    * @param columnIndex

    *           the zero-based index of the target column.

    * @return column value type

    */

   int getType(int columnIndex);

 

   /**

    * Returns <code>true</code> if the value in the indicatedcolumn is null.

    *

    * @param columnIndex

    *           the zero-based index of the target column.

    * @return whether the column value is null.

    */

   //判断值为null

   boolean isNull(int columnIndex);

 

   /**

    * Deactivates the Cursor, making all calls onit fail until

    * {@link #requery} is called. Inactive Cursors use fewer resources than

    * active Cursors. Calling {@link #requery} will make the cursor active

    * again.

    *

    * @deprecated Since{@link #requery()} is deprecated, so too is this.

    */

   void deactivate();

 

   /**

    * Performs the query that created the cursoragain, refreshing its

    * contents. This may be done at any time,including after a call to

    * {@link#deactivate}.

    *

    * Since this method could execute a query onthe database and potentially

    * take a while, it could cause ANR if it iscalled on Main (UI) thread. A

    * warning is printed if this method is beingexecuted on Main thread.

    *

    * @return true if therequery succeeded, false if not, inwhich case the

    *        cursor becomes invalid.

    * @deprecated Don't use this. Just request a new cursor, so you can dothis

    *            asynchronously and update your list view once the new cursor

    *            comes back.

    */

   @Deprecated

   boolean requery();

 

   /**

    * Closes the Cursor, releasing all of itsresources and making it

    * completely invalid. Unlike {@link #deactivate()} a call to

    * {@link #requery()} will not make the Cursor valid again.

    */

   //关闭Cursor,释放所有跟Cursor有关的资源,是它完全无效

   void close();

 

   /**

    * return true if the cursor is closed

    *

    * @return true if the cursor is closed.

    */

   boolean isClosed();

 

   /**

    * Register an observer that is called whenchanges happen to the content

    * backing this cursor. Typically the data setwon't change until

    * {@link #requery()} is called.

    *

    * @param observer

    *           the object that gets notified when the content backing the

    *           cursor changes.

    * @see #unregisterContentObserver(ContentObserver)

    */

   //注册监听器,当支持这个Cursor的内容发生变化时将被调用,一般数据集不会变化除了调用requery()方法

   voidregisterContentObserver(ContentObserver observer);

 

   /**

    * Unregister an observer that has previouslybeen registered with this

    * cursor via {@link #registerContentObserver}.

    *

    * @param observer

    *           the object to unregister.

    * @see #registerContentObserver(ContentObserver)

    */

   voidunregisterContentObserver(ContentObserver observer);

 

   /**

    * Register an observer that is called whenchanges happen to the contents

    * of the this cursors data set, for example,when the data set is changed

    * via {@link #requery()},{@link #deactivate()}, or{@link #close()}.

    *

    * @param observer

    *           the object that gets notified when the cursors data set

    *           changes.

    * @see #unregisterDataSetObserver(DataSetObserver)

    */

   //注册监听器,当这个Cursor包裹的数据集内容发生变化时调用,比如requery(),deactivate(),close()

   //Cursor调用close()方法后,所有资源被释放,数据集发生变化,所以此监听器将被触发

   voidregisterDataSetObserver(DataSetObserver observer);

 

   /**

    * Unregister an observer that has previouslybeen registered with this

    * cursor via {@link #registerContentObserver}.

    *

    * @param observer

    *           the object to unregister.

    * @see #registerDataSetObserver(DataSetObserver)

    */

   voidunregisterDataSetObserver(DataSetObserver observer);

 

   /**

    * Register to watch a content URI for changes.This can be the URI of a

    * specific data row (for example,"content://my_provider_type/23"), or a a

    * generic URI for a content type.

    *

    * @param cr

    *           The content resolver from the caller's context. The listener

    *           attached to this resolver will be notified.

    * @param uri

    *           The content URI to watch.

    */

   voidsetNotificationUri(ContentResolver cr, Uri uri);

 

   /**

    * Return the URI at which notifications ofchanges in this Cursor's data

    * will be delivered, as previously set by{@link #setNotificationUri}.

    *

    * @return Returns a URI that can be used with

    *        {@linkContentResolver#registerContentObserver(android.net.Uri, boolean,ContentObserver)

    *        ContentResolver.registerContentObserver} to find out about

    *        changes to this Cursor's data. May be null if no notification URI

    *        has been set.

    */

   UrigetNotificationUri();

 

   /**

    * onMove() will only be called acrossprocesses if this method returns

    * true.

    *

    * @return whether all cursor movement should result in a call toonMove().

    */

   booleangetWantsAllOnMoveCalls();

 

   /**

    * Returns a bundle of extra values. This is anoptional way for cursors to

    * provide out-of-bandmetadata to their users. One use of this isfor

    * reporting on the progress of networkrequests that are required to fetch

    * data for the cursor.

    *

    * <p>

    * These values may only change whenrequeryis called.

    *

    * @return cursor-defined values, or{@link android.os.Bundle#EMPTY

    *        Bundle.EMPTY} if there are no values. Never<code>null</code>.

    */

   BundlegetExtras();

 

   /**

    * This is an out-of-band way for the the user of a cursor to communicate

    * with the cursor. The structure of eachbundle is entirely defined by the

    * cursor.

    *

    * <p>

    * One use of this is to tell a cursor that itshould retry its network

    * request after it reported an error.

    *

    * @param extras

    *           extra values, or {@linkandroid.os.Bundle#EMPTY Bundle.EMPTY}.

    *           Never <code>null</code>.

    * @return extra values, or{@link android.os.Bundle#EMPTY Bundle.EMPTY}.

    *        Never <code>null</code>.

    */

   Bundlerespond(Bundle extras);

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值