moveToFirst和moveToNext的区别

来源:互联网 发布:股票入门知识软件 编辑:程序博客网 时间:2024/06/14 03:02

在第一次使用,也就是刚得到cursor对象的时候,使用这两个方法都能得到一样的效果,就是把游标记录指定到第一行记录.

从源码中可以看出端倪

cursor是个接口,具体的实现类是AbstractCursor

abstract class AbstractCursor implements CrossProcessCursor 
public interface CrossProcessCursor extends Cursor 
在AbstractCursor中实现了这两个方法:

 @Override    public final boolean moveToFirst() {        return moveToPosition(0);    }@Override    public final boolean moveToNext() {        return moveToPosition(mPos + 1);    }
可以看出,最终是调用了moveToPosition定位到绝对位置,而这里的mPos初始值是-1;

public AbstractCursor() {        mPos = -1;    }



这里再补充一下调用contentResolver的过程,一般是这样调用的getContext.getContentResolver 得到一个ContentResolve(抽象类)对象.

而getContentResolver这个方法是在具体的ContextImpl类中实现的.

  @Override    public ContentResolver getContentResolver() {        return mContentResolver;    }
private ApplicationContentResolver mContentResolver;
ApplicationContentResolver是ContextImpl的内部类,

 private static final class ApplicationContentResolver extends ContentResolver {        public ApplicationContentResolver(Context context, ActivityThread mainThread) {            super(context);            mMainThread = mainThread;        }        @Override        protected IContentProvider acquireProvider(Context context, String name) {            return mMainThread.acquireProvider(context, name);        }        @Override        protected IContentProvider acquireExistingProvider(Context context, String name) {            return mMainThread.acquireExistingProvider(context, name);        }        @Override        public boolean releaseProvider(IContentProvider provider) {            return mMainThread.releaseProvider(provider);        }                private final ActivityThread mMainThread;    }

执行contentResolver的query方法,会先去查找contentProvider在客户端的代理ContentProviderProxy(该类实现了IContentProvider接口,所以会直接返回这个接口)

 public final Cursor query(Uri uri, String[] projection,            String selection, String[] selectionArgs, String sortOrder) {        IContentProvider provider = acquireProvider(uri);        if (provider == null) {            return null;        }        try {            long startTime = SystemClock.uptimeMillis();            Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);            if (qCursor == null) {                releaseProvider(provider);                return null;            }            // force query execution            qCursor.getCount();            long durationMillis = SystemClock.uptimeMillis() - startTime;            maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder);            // Wrap the cursor object into CursorWrapperInner object            return new CursorWrapperInner(qCursor, provider);        } catch (RemoteException e) {            releaseProvider(provider);            return null;        } catch(RuntimeException e) {            releaseProvider(provider);            throw e;        }    }

最终会调用ActivityThread的同名的方法,去通过跨进程获取provider的代理.跟进去看一下acquireProvider方法:
public final IContentProvider acquireProvider(Context c, String name) {        IContentProvider provider = getProvider(c, name);        if(provider == null)            return null;        IBinder jBinder = provider.asBinder();        synchronized(mProviderMap) {            ProviderRefCount prc = mProviderRefCountMap.get(jBinder);            if(prc == null) {                mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));            } else {                prc.count++;            } //end else        } //end synchronized        return provider;    

实际上拿到的这个IContentProvider对象,是binder服务端的具体实现类ContentProviderNative

该类中的query方法:

public Cursor query(Uri url, String[] projection, String selection,            String[] selectionArgs, String sortOrder) throws RemoteException {        //TODO make a pool of windows so we can reuse memory dealers        CursorWindow window = new CursorWindow(false /* window will be used remotely */);        BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor();        IBulkCursor bulkCursor = bulkQueryInternal(            url, projection, selection, selectionArgs, sortOrder,            adaptor.getObserver(), window,            adaptor);        if (bulkCursor == null) {            return null;        }        return adaptor;    }
返回了一个BulkCursorToCursorAdatper对象,
public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor

public abstract class AbstractWindowedCursor extends AbstractCursor

主要这里我们想要看这个provider执行query后返回的具体的cursor对象是哪个?所以说这个cursor对象是服务端返回的.




原创粉丝点击