<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## AsnycTask的內部的實現機制 ### 寫在前面 我們為什么要用AsnycTask。 在Android程序開始運行的時候會單獨啟動一個進程,默認情況下所有 這個程序操作都在這個進程中進行。一個Android程序默認情況下只有 一個進程,但是一個進程卻是可以有許線程的。 我們通常會把一些比較耗時的操作,例如網絡請求、數據庫操作、復雜計算等邏輯都封裝到單獨的線程,這樣就可以避免阻塞主線程。 ### 內部機制 主要分為兩大部分: 1、與主線的交互,它內部實例化了一個靜態的自定義類InternalHand- ler,這個類是繼承自Handler的,在這個自定義類中綁定了一個叫做 AsyncTaskResult的對象,每次子線程需要通知主線程,就調用send- ToTarget發送消息給handler。然后在handler的handleMessage 中AsyncTaskResult根據消息的類型不同(例如MESSAGE POST- PROGRESS會更新進度條 , MESSAGEPOST CANCEL取消任務)而 做不同的操作,值得一提的是,這些操作都是在UI線程進行的,意味著, 從子線程一旦需要和UI線程交互,內部自動調用了handler對象把消息 放在了主線程了。 ~~~ mFuture = new FutureTask<Result>(mWorker) { @Override protected void More ...done() { Message message; Result result = null; try { result = get(); } catch (InterruptedException e) { android.util.Log.w(LOG_TAG, e); } catch (ExecutionException e) { throw new RuntimeException("An error occured while executing doInBackground()", e.getCause()); } catch (CancellationException e) { message = sHandler.obtainMessage(MESSAGE_POST_CANCEL, new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null)); message.sendToTarget(); return; } catch (Throwable t) { throw new RuntimeException("An error occured while executing " `+ "doInBackground()", t);` } message = sHandler.obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(AsyncTask.this, result)); message.sendToTarget(); } }; private static class InternalHandler extends Handler { @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"}) @Override public void More ...handleMessage(Message msg) { AsyncTaskResult result = (AsyncTaskResult) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT: // There is only one result result.mTask.finish(result.mData[0]); break; case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); break; case MESSAGE_POST_CANCEL: result.mTask.onCancelled(); break; } } } ~~~ 2、AsyncTask內部調度,雖然可以新建多個AsyncTask的子類的實例, 但是AsyncTask的內部Handler和ThreadPoolExecutor都是static 的,這么定義的變量屬于類的,是進程范圍內共享的,所以AsyncTask 控制著進程范圍內所有的子類實例,而且該類的所有實例都共用一個線 程池和Handler。 ~~~ public abstract class AsyncTask<Params, Progress, Result> { private static final String LOG_TAG = "AsyncTask"; private static final int CORE_POOL_SIZE = 5; private static final int MAXIMUM_POOL_SIZE = 128; private static final int KEEP_ALIVE = 1; private static final BlockingQueue<Runnable> sWorkQueue = new LinkedBlockingQueue<Runnable>(10); private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); public Thread More ...newThread(Runnable r) { return new Thread(r, "AsyncTask #" + mCount.getAndIncrement()); } }; private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_ SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory); private static final int MESSAGE_POST_RESULT = 0x1; private static final int MESSAGE_POST_PROGRESS = 0x2; private static final int MESSAGE_POST_CANCEL = 0x3; ~~~ 從代碼還可以看出,默認核心線程池的大小是5,緩存任務隊列是10。 意味著,如果線程池的線程數量小于5,這個時候新添加一個異步任 務則會新建一個線程;如果線程池的數量大于等于5,這個時候新建一 個異步任務這個任務會被放入緩存隊列中等待執行。 ### 注意的地方 - 由于Handler需要和主線程交互,而Handler又是內置于AsnycTask中的,所以, AsyncTask的創建必須在主線程。 - AsyncTaskResult的doInBackground(mParams)方法執行異步任務運行在子線 程中,其他方法運行在主線程中,可以操作UI組件。 - 不要手動的去調用AsyncTask的onPreExecute, doInBackground, publishPro- gress, onProgressUpdate, onPostExecute方法,這些都是由Android系統自 動調用的 - 一個任務AsyncTask任務只能被執行一次。 - 運行中可以隨時調用cancel(boolean)方法取消任務,如果成功調用isCancelled() 會 返 回 true,并 且 不 會 執 行 onPostExecute() 方 法 了,取 而 代 之 的 是 調 用 onCancelled() 方法。而且從源碼看,如果這個任務已經執行了這個時候調用 cancel是不會真正的把task結束,而是繼續執行,只不過改變的是執行之后的回 調方法是onPostExecute還是onCancelled。 -------------- ### Activity OnConfiguration 1、如果你的App沒有明確指定屏幕 方向和configChanges時,當用戶旋轉屏幕的時候Activity就會重新 啟動,而這個時候您的異步加載數據的線程可能正在請求網絡。當一 個新的Activity被重新創建之后,可能由重新啟動了一個新的任務去 請求網絡,這樣之前的一個異步任務不經意間就泄露了,假設你還在 onPostExecute寫了一些其他邏輯,這個時候就會發生意想不到異常。 2、一般簡單的數據類型的,對付configChanges我們很好處理,我們直接 可 以 通 過onSaveInstanceState() 和 onRestoreInstanceState() 進 行 保 存 與 恢 復。 3、對于AsyncTask,我們可以用到Square開源的EventBus類庫http://square.github.io/ otto/。首先自定義一個AsyncTask的子類,在onPostExecute方法中, 把返回結果拋給事件總線。 ~~~ @Override protected String doInBackground(Void... params) { Random random = new Random(); final long sleep = random.nextInt(10); try { Thread.sleep(10 * 6000); } catch (InterruptedException e) { e.printStackTrace(); } return "Slept for " + sleep + " seconds"; } @Override protected void onPostExecute(String result) { MyBus.getInstance().post(new AsyncTaskResultEvent(result)); } ~~~ 在Activity的onCreate中注冊這個事件總線,這樣異步線程的消息就會 被otta分發到當前注冊的activity,這個時候返回結果就在當前activity 的onAsyncTaskResult中了。 ~~~ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.otto_layout); findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new MyAsyncTask().execute(); } }); MyBus.getInstance().register(this); } @Override protected void onDestroy() { MyBus.getInstance().unregister(this); super.onDestroy(); } @Subscribe public void onAsyncTaskResult(AsyncTaskResultEvent event) { Toast.makeText(this, event.getResult(), Toast.LENGTH_LONG).show(); } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看