由今後、FutureTask、呼び出し可能再到AsyncTask

このような再版として、してくださいクレジット:https://blog.csdn.net/dxh040431104/article/details/93329349

 

将来、FutureTask、多くの呼び出し可能なオンライン説明は、私はちょうど私の洞察力の一部を言い、ここで言うことができません

FutureTaskは将来Runableの実現である、それは直接スロースレッドとして使用することができます

Callable<Integer> callable = new Callable<Integer>() {
    @Override
    public Integer call() throws Exception {
        return null;
    }
} ;
FutureTask futureTask = new FutureTask(callable);
new Thread(futureTask).start();

FutureTaskとRunable差FutureTaskは、複数の値もRunable以外の方法で実行される戻す、ということである、これらのインタフェースは、将来に定義される、キャンセル、isCancelled、isDone、取得

FutureTaskはまた、スレッドプール(例えばRunableなど)エグゼキュータで使用することができ

Callable<Integer> callable = new Callable<Integer>() {
    @Override
    public Integer call() throws Exception {
        return null;
    }
} ;
ExecutorService executorService = Executors.newCachedThreadPool();
FutureTask futureTask = new FutureTask(callable);
Future result = executorService.submit(futureTask);

若しくは

Callable<Integer> callable = new Callable<Integer>() {
    @Override
    public Integer call() throws Exception {
        return null;
    }
} ;
ExecutorService executorService = Executors.newCachedThreadPool();
Future result = executorService.submit(callable);

ソースから最終的executorService.submit(futureTask)にパッケージ化実際には(呼び出し可能)executorService.submitを見ることができるはずです。次のように


上記の理解で、私たちは、AsyncTaskを議論します:

private void testAsyncTask() {
    MyAsyncTask myAsyncTask = new MyAsyncTask();
    myAsyncTask.execute();
}

class MyAsyncTask extends AsyncTask<Void, Integer, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... voids) {
        if(isCancelled()) {
            return null;
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
    }
}

これは最も単純AsyncTask文言ですが、それが内部でどのようにそれを実行するために?実行から見ました。

@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
    return executeOnExecutor(sDefaultExecutor, params);
}
@MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
        Params... params) {
.....................
    onPreExecute();
    exec.execute(mFuture);

    return this;
}

私たちは見onPreExecuteは、このアプローチは、メインスレッドであなたにいくつかのUIの更新を与えるために基本的であることをノートが@MainThreadこと、それはないです。

ここでexec.execute(mFuture)は、あなたがexecを見ることができる前からsDefaultExecutorが、これは何であるかsDefaultExecutorですか?

ソースによって、私たちは、これが執行されるでしょう、

private static class SerialExecutor implements Executor {
    final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
    Runnable mActive;

    public synchronized void execute(final Runnable r) {
        mTasks.offer(new Runnable() {
            public void run() {
                try {
                    r.run();
                } finally {
                    scheduleNext();
                }
            }
        });
        if (mActive == null) {
            scheduleNext();
        }
    }

    protected synchronized void scheduleNext() {
        if ((mActive = mTasks.poll()) != null) {
            THREAD_POOL_EXECUTOR.execute(mActive);
        }
    }
}

赤Runable Rは上記mFuture、exec.execute(mFutureが)ここに渡し、実際にあります。実際scheduleNextで実行し、次はフォーカスであるTHREAD_POOL_EXECUTOR何がありますか?

public static final Executor THREAD_POOL_EXECUTOR;

static {
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
            sPoolWorkQueue, sThreadFactory);
    threadPoolExecutor.allowCoreThreadTimeOut(true);
    THREAD_POOL_EXECUTOR = threadPoolExecutor;
}

実際には、スレッドプール、そして私の目の前で話すのは同じです。だから今、私たちは非常に明確にする必要があり、AsyncTaskは、実際には、非同期呼び出しを行うには、スレッドプールとFutureTaskの使用です。スレッドプールを見つけたので、どこAsyncTask FutureTaskとコーラブル内部のそれで?

public AsyncTask(@Nullable Looper callbackLooper) {
    mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
        ? getMainHandler()
        : new Handler(callbackLooper);

    mWorker = new WorkerRunnable<Params, Result>() {
        public Result call() throws Exception {
            mTaskInvoked.set(true);
            Result result = null;
            try {
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                //noinspection unchecked
                result = doInBackground(mParams);
                Binder.flushPendingCommands();
            } catch (Throwable tr) {
                mCancelled.set(true);
                throw tr;
            } finally {
                postResult(result);
            }
            return result;
        }
    };

    mFuture = new FutureTask<Result>(mWorker) {
        @Override
        protected void done() {
            try {
                postResultIfNotInvoked(get());
            } catch (InterruptedException e) {
                android.util.Log.w(LOG_TAG, e);
            } catch (ExecutionException e) {
                throw new RuntimeException("An error occurred while executing doInBackground()",
                        e.getCause());
            } catch (CancellationException e) {
                postResultIfNotInvoked(null);
            }
        }
    };
}
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
    Params[] mParams;
}

AsyncTaskのコンストラクタでは見ることができます。mWorkerはmFutureがFutureTaskあり、呼び出し可能です。

その全体のプロセスは、doInBackgroundでonPreExecuteコーラブルを実行し、実行し、最後に実行postResultIfNotInvoked非常に簡単です。

private void postResultIfNotInvoked(Result result) {
    final boolean wasTaskInvoked = mTaskInvoked.get();
    if (!wasTaskInvoked) {
        postResult(result);
    }
}

これpostResultIfNotInvoked呼び出しがpostResultです。それは非常に明確ではありません。


注意点:

AsyncTaskはFutureTaskと非同期に実行されるため、ので、いくつかのピットAsyncTaskはありFutureTaskを存在します。

キャンセル方法AsyncTask実際には完全には有効ではありません。我々は、次のコードを見て:

public final boolean cancel(boolean mayInterruptIfRunning) {
    mCancelled.set(true);
    return mFuture.cancel(mayInterruptIfRunning);
}

最後に、Thread.interruptによって中断されていますが、スレッド呼び出し待機Objectクラスは、()、(長い)待つか待って(長い、int)メソッド、またはクラスは、参加)(参加ならば中断は、限られています(長い、参加、(長い)スリープ(ロング)、int)をまたはスリープ(ロング、int)メソッド、あなたが壊れにすることができ、ネットワーク通信、こうしたブロックされたファイルの読み込みなどが中断されてはなりません

だから、内部のネットワーク要求ならば、我々は、キャンセルの方法によって要求されたネットワークをオフに停止することはできません。

ですから、割り込みフラグがセットされているかどうかを判断するために、独自のisInterruptメソッドを呼び出す必要があり、AsyncTaskのために、それが判断したisCancelled doInBackgroundで呼び出す必要があります。

@Override
protected Void doInBackground(Void... voids) {
    if(isCancelled()) {
        return null;
    }
    return null;
}

何か問題があれば指摘してくださいありがとう

 

おすすめ

転載: blog.csdn.net/dxh040431104/article/details/93329349