moveToFirst和moveToNext的区别

在第一次使用,也就是刚得到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对象是服务端返回的.




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值