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里-1和3位置是虚拟存在的,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位,正直向前移动(向下),负值向后移动(向上)。移动到-1或getCount()后就移动不了了(如果继续超出界限),始终“移动”在原地
*
* 如果移动的偏移量会超出界限,Cursor就会固定在-1或getCount()位置上,并返回false
* 问题:如果刚好移动到-1或getCount()位置返回false还是true?答案是:false。
* 所有的move方法,移动到-1和getCount()都是返回false,位置是虚拟存在的,实际不可抵达。意思是可以移动到此处,但是返回false告诉我们越界了。
* */
boolean move(int offset);
/**
* Move the cursor to an absolute position. Thevalid range of values is-1
* <= position <= 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到-1和getCount()返回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);
}