FileDocCategorySizeDatePackage
CursorWindow.javaAPI DocAndroid 5.1 API27553Thu Mar 12 22:22:10 GMT 2015android.database

CursorWindow

public class CursorWindow extends android.database.sqlite.SQLiteClosable implements android.os.Parcelable
A buffer containing multiple cursor rows.

A {@link CursorWindow} is read-write when initially created and used locally. When sent to a remote process (by writing it to a {@link Parcel}), the remote process receives a read-only view of the cursor window. Typically the cursor window will be allocated by the producer, filled with data, and then sent to the consumer for reading.

Fields Summary
private static final String
STATS_TAG
private static int
sCursorWindowSize
public long
mWindowPtr
The native CursorWindow object pointer. (FOR INTERNAL USE ONLY)
private int
mStartPos
private final String
mName
private final dalvik.system.CloseGuard
mCloseGuard
public static final Parcelable.Creator
CREATOR
private static final android.util.LongSparseArray
sWindowToPidMap
Constructors Summary
public CursorWindow(String name)
Creates a new empty cursor window and gives it a name.

The cursor initially has no rows or columns. Call {@link #setNumColumns(int)} to set the number of columns before adding any rows to the cursor.

param
name The name of the cursor window, or null if none.


           
         
         
           

         

         
           
         
         

             
             
             
             
             
             
             

               
               
               
               
             

         

                                                           
       
        mStartPos = 0;
        mName = name != null && name.length() != 0 ? name : "<unnamed>";
        if (sCursorWindowSize < 0) {
            /** The cursor window size. resource xml file specifies the value in kB.
             * convert it to bytes here by multiplying with 1024.
             */
            sCursorWindowSize = Resources.getSystem().getInteger(
                com.android.internal.R.integer.config_cursorWindowSize) * 1024;
        }
        mWindowPtr = nativeCreate(mName, sCursorWindowSize);
        if (mWindowPtr == 0) {
            throw new CursorWindowAllocationException("Cursor window allocation of " +
                    (sCursorWindowSize / 1024) + " kb failed. " + printStats());
        }
        mCloseGuard.open("close");
        recordNewWindow(Binder.getCallingPid(), mWindowPtr);
    
public CursorWindow(boolean localWindow)
Creates a new empty cursor window.

The cursor initially has no rows or columns. Call {@link #setNumColumns(int)} to set the number of columns before adding any rows to the cursor.

param
localWindow True if this window will be used in this process only, false if it might be sent to another processes. This argument is ignored.
deprecated
There is no longer a distinction between local and remote cursor windows. Use the {@link #CursorWindow(String)} constructor instead.

        this((String)null);
    
private CursorWindow(android.os.Parcel source)

        mStartPos = source.readInt();
        mWindowPtr = nativeCreateFromParcel(source);
        if (mWindowPtr == 0) {
            throw new CursorWindowAllocationException("Cursor window could not be "
                    + "created from binder.");
        }
        mName = nativeGetName(mWindowPtr);
        mCloseGuard.open("close");
    
Methods Summary
public booleanallocRow()
Allocates a new row at the end of this cursor window.

return
True if successful, false if the cursor window is out of memory.

        acquireReference();
        try {
            return nativeAllocRow(mWindowPtr);
        } finally {
            releaseReference();
        }
    
public voidclear()
Clears out the existing contents of the window, making it safe to reuse for new data.

The start position ({@link #getStartPosition()}), number of rows ({@link #getNumRows()}), and number of columns in the cursor are all reset to zero.

        acquireReference();
        try {
            mStartPos = 0;
            nativeClear(mWindowPtr);
        } finally {
            releaseReference();
        }
    
public voidcopyStringToBuffer(int row, int column, CharArrayBuffer buffer)
Copies the text of the field at the specified row and column index into a {@link CharArrayBuffer}.

The buffer is populated as follows:

  • If the buffer is too small for the value to be copied, then it is automatically resized.
  • If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the buffer is set to an empty string.
  • If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the buffer is set to the contents of the string.
  • If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the buffer is set to a string representation of the integer in decimal, obtained by formatting the value with the printf family of functions using format specifier %lld.
  • If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the buffer is set to a string representation of the floating-point value in decimal, obtained by formatting the value with the printf family of functions using format specifier %g.
  • If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a {@link SQLiteException} is thrown.

param
row The zero-based row index.
param
column The zero-based column index.
param
buffer The {@link CharArrayBuffer} to hold the string. It is automatically resized if the requested string is larger than the buffer's current capacity.

        if (buffer == null) {
            throw new IllegalArgumentException("CharArrayBuffer should not be null");
        }
        acquireReference();
        try {
            nativeCopyStringToBuffer(mWindowPtr, row - mStartPos, column, buffer);
        } finally {
            releaseReference();
        }
    
public intdescribeContents()

        return 0;
    
private voiddispose()

        if (mCloseGuard != null) {
            mCloseGuard.close();
        }
        if (mWindowPtr != 0) {
            recordClosingOfWindow(mWindowPtr);
            nativeDispose(mWindowPtr);
            mWindowPtr = 0;
        }
    
protected voidfinalize()

        try {
            if (mCloseGuard != null) {
                mCloseGuard.warnIfOpen();
            }
            dispose();
        } finally {
            super.finalize();
        }
    
public voidfreeLastRow()
Frees the last row in this cursor window.

        acquireReference();
        try {
            nativeFreeLastRow(mWindowPtr);
        } finally {
            releaseReference();
        }
    
public byte[]getBlob(int row, int column)
Gets the value of the field at the specified row and column index as a byte array.

The result is determined as follows:

  • If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result is null.
  • If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then the result is the blob value.
  • If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result is the array of bytes that make up the internal representation of the string value.
  • If the field is of type {@link Cursor#FIELD_TYPE_INTEGER} or {@link Cursor#FIELD_TYPE_FLOAT}, then a {@link SQLiteException} is thrown.

param
row The zero-based row index.
param
column The zero-based column index.
return
The value of the field as a byte array.

        acquireReference();
        try {
            return nativeGetBlob(mWindowPtr, row - mStartPos, column);
        } finally {
            releaseReference();
        }
    
public doublegetDouble(int row, int column)
Gets the value of the field at the specified row and column index as a double.

The result is determined as follows:

  • If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result is 0.0.
  • If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result is the value obtained by parsing the string value with strtod.
  • If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the result is the integer value converted to a double.
  • If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the result is the double value.
  • If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a {@link SQLiteException} is thrown.

param
row The zero-based row index.
param
column The zero-based column index.
return
The value of the field as a double.

        acquireReference();
        try {
            return nativeGetDouble(mWindowPtr, row - mStartPos, column);
        } finally {
            releaseReference();
        }
    
public floatgetFloat(int row, int column)
Gets the value of the field at the specified row and column index as a float.

The result is determined by invoking {@link #getDouble} and converting the result to float.

param
row The zero-based row index.
param
column The zero-based column index.
return
The value of the field as an float.

        return (float) getDouble(row, column);
    
public intgetInt(int row, int column)
Gets the value of the field at the specified row and column index as an int.

The result is determined by invoking {@link #getLong} and converting the result to int.

param
row The zero-based row index.
param
column The zero-based column index.
return
The value of the field as an int.

        return (int) getLong(row, column);
    
public longgetLong(int row, int column)
Gets the value of the field at the specified row and column index as a long.

The result is determined as follows:

  • If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result is 0L.
  • If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result is the value obtained by parsing the string value with strtoll.
  • If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the result is the long value.
  • If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the result is the floating-point value converted to a long.
  • If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a {@link SQLiteException} is thrown.

param
row The zero-based row index.
param
column The zero-based column index.
return
The value of the field as a long.

        acquireReference();
        try {
            return nativeGetLong(mWindowPtr, row - mStartPos, column);
        } finally {
            releaseReference();
        }
    
public java.lang.StringgetName()
Gets the name of this cursor window, never null.

hide

        return mName;
    
public intgetNumRows()
Gets the number of rows in this window.

return
The number of rows in this cursor window.

        acquireReference();
        try {
            return nativeGetNumRows(mWindowPtr);
        } finally {
            releaseReference();
        }
    
public shortgetShort(int row, int column)
Gets the value of the field at the specified row and column index as a short.

The result is determined by invoking {@link #getLong} and converting the result to short.

param
row The zero-based row index.
param
column The zero-based column index.
return
The value of the field as a short.

        return (short) getLong(row, column);
    
public intgetStartPosition()
Gets the start position of this cursor window.

The start position is the zero-based index of the first row that this window contains relative to the entire result set of the {@link Cursor}.

return
The zero-based start position.

        return mStartPos;
    
public java.lang.StringgetString(int row, int column)
Gets the value of the field at the specified row and column index as a string.

The result is determined as follows:

  • If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result is null.
  • If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result is the string value.
  • If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the result is a string representation of the integer in decimal, obtained by formatting the value with the printf family of functions using format specifier %lld.
  • If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the result is a string representation of the floating-point value in decimal, obtained by formatting the value with the printf family of functions using format specifier %g.
  • If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a {@link SQLiteException} is thrown.

param
row The zero-based row index.
param
column The zero-based column index.
return
The value of the field as a string.

        acquireReference();
        try {
            return nativeGetString(mWindowPtr, row - mStartPos, column);
        } finally {
            releaseReference();
        }
    
public intgetType(int row, int column)
Returns the type of the field at the specified row and column index.

The returned field types are:

  • {@link Cursor#FIELD_TYPE_NULL}
  • {@link Cursor#FIELD_TYPE_INTEGER}
  • {@link Cursor#FIELD_TYPE_FLOAT}
  • {@link Cursor#FIELD_TYPE_STRING}
  • {@link Cursor#FIELD_TYPE_BLOB}

param
row The zero-based row index.
param
column The zero-based column index.
return
The field type.

        acquireReference();
        try {
            return nativeGetType(mWindowPtr, row - mStartPos, column);
        } finally {
            releaseReference();
        }
    
public booleanisBlob(int row, int column)
Returns true if the field at the specified row and column index has type {@link Cursor#FIELD_TYPE_BLOB} or {@link Cursor#FIELD_TYPE_NULL}.

param
row The zero-based row index.
param
column The zero-based column index.
return
True if the field has type {@link Cursor#FIELD_TYPE_BLOB} or {@link Cursor#FIELD_TYPE_NULL}.
deprecated
Use {@link #getType(int, int)} instead.

        int type = getType(row, column);
        return type == Cursor.FIELD_TYPE_BLOB || type == Cursor.FIELD_TYPE_NULL;
    
public booleanisFloat(int row, int column)
Returns true if the field at the specified row and column index has type {@link Cursor#FIELD_TYPE_FLOAT}.

param
row The zero-based row index.
param
column The zero-based column index.
return
True if the field has type {@link Cursor#FIELD_TYPE_FLOAT}.
deprecated
Use {@link #getType(int, int)} instead.

        return getType(row, column) == Cursor.FIELD_TYPE_FLOAT;
    
public booleanisLong(int row, int column)
Returns true if the field at the specified row and column index has type {@link Cursor#FIELD_TYPE_INTEGER}.

param
row The zero-based row index.
param
column The zero-based column index.
return
True if the field has type {@link Cursor#FIELD_TYPE_INTEGER}.
deprecated
Use {@link #getType(int, int)} instead.

        return getType(row, column) == Cursor.FIELD_TYPE_INTEGER;
    
public booleanisNull(int row, int column)
Returns true if the field at the specified row and column index has type {@link Cursor#FIELD_TYPE_NULL}.

param
row The zero-based row index.
param
column The zero-based column index.
return
True if the field has type {@link Cursor#FIELD_TYPE_NULL}.
deprecated
Use {@link #getType(int, int)} instead.

        return getType(row, column) == Cursor.FIELD_TYPE_NULL;
    
public booleanisString(int row, int column)
Returns true if the field at the specified row and column index has type {@link Cursor#FIELD_TYPE_STRING} or {@link Cursor#FIELD_TYPE_NULL}.

param
row The zero-based row index.
param
column The zero-based column index.
return
True if the field has type {@link Cursor#FIELD_TYPE_STRING} or {@link Cursor#FIELD_TYPE_NULL}.
deprecated
Use {@link #getType(int, int)} instead.

        int type = getType(row, column);
        return type == Cursor.FIELD_TYPE_STRING || type == Cursor.FIELD_TYPE_NULL;
    
private static native booleannativeAllocRow(long windowPtr)

private static native voidnativeClear(long windowPtr)

private static native voidnativeCopyStringToBuffer(long windowPtr, int row, int column, CharArrayBuffer buffer)

private static native longnativeCreate(java.lang.String name, int cursorWindowSize)

private static native longnativeCreateFromParcel(android.os.Parcel parcel)

private static native voidnativeDispose(long windowPtr)

private static native voidnativeFreeLastRow(long windowPtr)

private static native byte[]nativeGetBlob(long windowPtr, int row, int column)

private static native doublenativeGetDouble(long windowPtr, int row, int column)

private static native longnativeGetLong(long windowPtr, int row, int column)

private static native java.lang.StringnativeGetName(long windowPtr)

private static native intnativeGetNumRows(long windowPtr)

private static native java.lang.StringnativeGetString(long windowPtr, int row, int column)

private static native intnativeGetType(long windowPtr, int row, int column)

private static native booleannativePutBlob(long windowPtr, byte[] value, int row, int column)

private static native booleannativePutDouble(long windowPtr, double value, int row, int column)

private static native booleannativePutLong(long windowPtr, long value, int row, int column)

private static native booleannativePutNull(long windowPtr, int row, int column)

private static native booleannativePutString(long windowPtr, java.lang.String value, int row, int column)

private static native booleannativeSetNumColumns(long windowPtr, int columnNum)

private static native voidnativeWriteToParcel(long windowPtr, android.os.Parcel parcel)

public static android.database.CursorWindownewFromParcel(android.os.Parcel p)


         
        return CREATOR.createFromParcel(p);
    
protected voidonAllReferencesReleased()

        dispose();
    
private java.lang.StringprintStats()

        StringBuilder buff = new StringBuilder();
        int myPid = Process.myPid();
        int total = 0;
        SparseIntArray pidCounts = new SparseIntArray();
        synchronized (sWindowToPidMap) {
            int size = sWindowToPidMap.size();
            if (size == 0) {
                // this means we are not in the ContentProvider.
                return "";
            }
            for (int indx = 0; indx < size; indx++) {
                int pid = sWindowToPidMap.valueAt(indx);
                int value = pidCounts.get(pid);
                pidCounts.put(pid, ++value);
            }
        }
        int numPids = pidCounts.size();
        for (int i = 0; i < numPids;i++) {
            buff.append(" (# cursors opened by ");
            int pid = pidCounts.keyAt(i);
            if (pid == myPid) {
                buff.append("this proc=");
            } else {
                buff.append("pid " + pid + "=");
            }
            int num = pidCounts.get(pid);
            buff.append(num + ")");
            total += num;
        }
        // limit the returned string size to 1000
        String s = (buff.length() > 980) ? buff.substring(0, 980) : buff.toString();
        return "# Open Cursors=" + total + s;
    
public booleanputBlob(byte[] value, int row, int column)
Copies a byte array into the field at the specified row and column index.

param
value The value to store.
param
row The zero-based row index.
param
column The zero-based column index.
return
True if successful.

        acquireReference();
        try {
            return nativePutBlob(mWindowPtr, value, row - mStartPos, column);
        } finally {
            releaseReference();
        }
    
public booleanputDouble(double value, int row, int column)
Puts a double-precision floating point value into the field at the specified row and column index.

param
value The value to store.
param
row The zero-based row index.
param
column The zero-based column index.
return
True if successful.

        acquireReference();
        try {
            return nativePutDouble(mWindowPtr, value, row - mStartPos, column);
        } finally {
            releaseReference();
        }
    
public booleanputLong(long value, int row, int column)
Puts a long integer into the field at the specified row and column index.

param
value The value to store.
param
row The zero-based row index.
param
column The zero-based column index.
return
True if successful.

        acquireReference();
        try {
            return nativePutLong(mWindowPtr, value, row - mStartPos, column);
        } finally {
            releaseReference();
        }
    
public booleanputNull(int row, int column)
Puts a null value into the field at the specified row and column index.

param
row The zero-based row index.
param
column The zero-based column index.
return
True if successful.

        acquireReference();
        try {
            return nativePutNull(mWindowPtr, row - mStartPos, column);
        } finally {
            releaseReference();
        }
    
public booleanputString(java.lang.String value, int row, int column)
Copies a string into the field at the specified row and column index.

param
value The value to store.
param
row The zero-based row index.
param
column The zero-based column index.
return
True if successful.

        acquireReference();
        try {
            return nativePutString(mWindowPtr, value, row - mStartPos, column);
        } finally {
            releaseReference();
        }
    
private voidrecordClosingOfWindow(long window)

        synchronized (sWindowToPidMap) {
            if (sWindowToPidMap.size() == 0) {
                // this means we are not in the ContentProvider.
                return;
            }
            sWindowToPidMap.delete(window);
        }
    
private voidrecordNewWindow(int pid, long window)


          
        synchronized (sWindowToPidMap) {
            sWindowToPidMap.put(window, pid);
            if (Log.isLoggable(STATS_TAG, Log.VERBOSE)) {
                Log.i(STATS_TAG, "Created a new Cursor. " + printStats());
            }
        }
    
public booleansetNumColumns(int columnNum)
Sets the number of columns in this window.

This method must be called before any rows are added to the window, otherwise it will fail to set the number of columns if it differs from the current number of columns.

param
columnNum The new number of columns.
return
True if successful.

        acquireReference();
        try {
            return nativeSetNumColumns(mWindowPtr, columnNum);
        } finally {
            releaseReference();
        }
    
public voidsetStartPosition(int pos)
Sets the start position of this cursor window.

The start position is the zero-based index of the first row that this window contains relative to the entire result set of the {@link Cursor}.

param
pos The new zero-based start position.

        mStartPos = pos;
    
public java.lang.StringtoString()

        return getName() + " {" + Long.toHexString(mWindowPtr) + "}";
    
public voidwriteToParcel(android.os.Parcel dest, int flags)

        acquireReference();
        try {
            dest.writeInt(mStartPos);
            nativeWriteToParcel(mWindowPtr, dest);
        } finally {
            releaseReference();
        }

        if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
            releaseReference();
        }