美文网首页
Android Loader源码分析(二)

Android Loader源码分析(二)

作者: _Ryan | 来源:发表于2017-08-18 18:11 被阅读54次

    Android Loader源码分析(一)中说道在start方法的最后,会调用mLoader.startLoading();
    startLoading方法又会调用onStartLoading方法

    //在Loader.java文件中
    public final void startLoading() {
        mStarted = true;
        mReset = false;
        mAbandoned = false;
        onStartLoading();
    }
      
    //在CursorLoader.java 文件中
    @Override
    protected void onStartLoading() {
        if (mCursor != null) {
            deliverResult(mCursor);
        }
        if (takeContentChanged() || mCursor == null) {
            forceLoad();
        }
    }
      
    public void forceLoad() {
        onForceLoad();
    }
    

    在数据还未加载时,mCursor为null,此时会执行forceLoad()
    forceLoad()会执行onForceLoad(),此方法的实现是在AsyncTaskLoader.java中

    @Override
    protected void onForceLoad() {
        super.onForceLoad();
        cancelLoad();
        mTask = new LoadTask();
        if (DEBUG) Log.v(TAG, "Preparing load: mTask=" + mTask);
        executePendingTask();
    }
    

    (1)、forceLoad()会调用onForceLoad()。而onForceLoad()中会新建LoadTask对象,然后执行executePendingTask()
    (2)、在executePendingTask()中会调用LoadTask对象的executeOnExecutor()

    void executePendingTask() {
        if (mCancellingTask == null && mTask != null) {
            if (mTask.waiting) {
                mTask.waiting = false;
                mHandler.removeCallbacks(mTask);
            }
            if (mUpdateThrottle > 0) {
                long now = SystemClock.uptimeMillis();
                if (now < (mLastLoadCompleteTime+mUpdateThrottle)) {
                    // Not yet time to do another load.
                    mTask.waiting = true;
                    mHandler.postAtTime(mTask, mLastLoadCompleteTime+mUpdateThrottle);
                    return;
                }
            }
            mTask.executeOnExecutor(mExecutor, (Void[]) null);
        }
    }
      
    //LoadTask的实现
    final class LoadTask extends AsyncTask<Void, Void, D> implements Runnable {
        private final CountDownLatch mDone = new CountDownLatch(1);
     
        boolean waiting;
     
        /* Runs on a worker thread */
        @Override
        protected D doInBackground(Void... params) {
            try {
                D data = AsyncTaskLoader.this.onLoadInBackground();
                return data;
            } catch (OperationCanceledException ex) {
                if (!isCancelled()) {
                    throw ex;
                }
                return null;
            }
        }
     
        /* Runs on the UI thread */
        @Override
        protected void onPostExecute(D data) {
            try {
                AsyncTaskLoader.this.dispatchOnLoadComplete(this, data);
            } finally {
                mDone.countDown();
            }
        }
     
        /* Runs on the UI thread */
        @Override
        protected void onCancelled(D data) {
            try {
                AsyncTaskLoader.this.dispatchOnCancelled(this, data);
            } finally {
                mDone.countDown();
            }
        }
     
        /* Runs on the UI thread, when the waiting task is posted to a handler.
         * This method is only executed when task execution was deferred (waiting was true). */
        @Override
        public void run() {
            waiting = false;
            AsyncTaskLoader.this.executePendingTask();
        }
     
        /* Used for testing purposes to wait for the task to complete. */
        public void waitForLoader() {
            try {
                mDone.await();
            } catch (InterruptedException e) {
                // Ignore
            }
        }
    }
    
    1. LoadTask是AsyncTaskLoader的内部类。实际上,它是AsyncTask的子类,executeOnExecutor()会将任务提交到线程池中去执行;
    2. 这个被提交到线程池的任务会执行AsyncTask的doInBackground()。
    3. LoadTask的doInBackground()会调用onLoadInBackground()
    4. onLoadInBackground()方法会调用loadInBackground() 这个方法是在CursorLoader中实现的
    /* Runs on a worker thread */
    @Override
    public Cursor loadInBackground() {
        synchronized (this) {
            if (isLoadInBackgroundCanceled()) {
                throw new OperationCanceledException();
            }
            mCancellationSignal = new CancellationSignal();
        }
        try {
            Cursor cursor = getContext().getContentResolver().query(mUri, mProjection, mSelection,
                    mSelectionArgs, mSortOrder, mCancellationSignal);
            if (cursor != null) {
                try {
                    // Ensure the cursor window is filled.
                    cursor.getCount();
                    cursor.registerContentObserver(mObserver);
                } catch (RuntimeException ex) {
                    cursor.close();
                    throw ex;
                }
            }
            return cursor;
        } finally {
            synchronized (this) {
                mCancellationSignal = null;
            }
        }
    }
    
    1. 当AsyncTask中的任务执行完时,会通过onPostExecute()反馈执行结果。
    2. onPostExecute()会执行dispatchOnLoadComplete(),而后者会调用deliverResult()来分发消息。
    3. 最终会执行mListener.onLoadComplete()。mListener是什么呢?它是我们在执行LoaderManager.java的start()函数时,通过mLoader.registerListener(mId, this)注册到Loader上的。也就是说,mListener是LoaderManager中的LoaderInfo对象。

    相关文章

      网友评论

          本文标题:Android Loader源码分析(二)

          本文链接:https://www.haomeiwen.com/subject/ognarxtx.html