<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    L遷客

    技術(shù)博客
    隨筆 - 1, 文章 - 12, 評論 - 1, 引用 - 0
    數(shù)據(jù)加載中……

    AsyncTask的缺陷

    AsyncTask的缺陷

    導(dǎo)語:在開發(fā)Android應(yīng)用的過程中,我們需要時刻注意保障應(yīng)用的穩(wěn)定性和界面響應(yīng)性,因為不穩(wěn)定或者響應(yīng)速度慢的應(yīng)用將會給用戶帶來非常差的交互體驗。在越來越講究用戶體驗的大環(huán)境下,用戶也許會因為應(yīng)用的一次Force Close(簡稱FC)或者延遲嚴重的動畫效果而卸載你的應(yīng)用。由于現(xiàn)在的應(yīng)用大多需要異步連接網(wǎng)絡(luò),本系列文章就以構(gòu)建網(wǎng)絡(luò)應(yīng)用為例,從穩(wěn)定性和響應(yīng)性兩個角度分析多線程網(wǎng)絡(luò)任務(wù)的性能優(yōu)化方法。

    概述:為了不阻塞UI線程(亦稱主線程),提高應(yīng)用的響應(yīng)性,我們經(jīng)常會使用新開線程的方式,異步處理那些導(dǎo)致阻塞的任務(wù)。

    AsyncTask是Android為我們提供的方便編寫異步任務(wù)的工具類,但是,在了解AsyncTask的實現(xiàn)原理之后,發(fā)現(xiàn)AsyncTask并不能滿足我們所有的需求,使用不當還有可能導(dǎo)致應(yīng)用FC。

    本文主要通過分析AsyncTask提交任務(wù)的策略和一個具體的例子,說明AsyncTask的不足之處,至于解決辦法,我們將在下篇再講解。

    分析

    AsyncTask類包含一個全局靜態(tài)的線程池,線程池的配置參數(shù)如下:

    //5個核心工作線程

    private static final int CORE_POOL_SIZE =5;

    //最多128個工作線程

    private static final int MAXIMUM_POOL_SIZE = 128;

    //空閑線程的超時時間為1秒

    private static final int KEEP_ALIVE = 1;

    private static final BlockingQueue<Runnable> sWorkQueue =

               new LinkedBlockingQueue<Runnable>(10);//等待隊列

    private static final ThreadPoolExecutorsExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,

               //線程池是靜態(tài)變量,所有的異步任務(wù)都會放到這個線程池的工作線程內(nèi)執(zhí)行。

               MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue,sThreadFactory);

    我們這里不詳細講解ThreadPoolExecutor的原理,但將會講解一個異步任務(wù)提交到AsyncTask的線程池時可能會出現(xiàn)的4種情況,并會提出在Android硬件配置普遍較低這個客觀條件下,每個情況可能會出現(xiàn)的問題。

    1、線程池中的工作線程少于5個時,將會創(chuàng)建新的工作線程執(zhí)行異步任務(wù)(紅色表示新任務(wù),下同)

    2、線程池中已經(jīng)有5個線程,緩沖隊列未滿,異步任務(wù)將會放到緩沖隊列中等待

    3、線程池中已經(jīng)有5個線程,緩沖隊列已滿,那么線程池將新開工作線程執(zhí)行異步任務(wù)

    問題:Android的設(shè)備一般不超過2個cpu核心,過多的線程會造成線程間切換頻繁,消耗系統(tǒng)資源。

    4、線程池中已經(jīng)有128個線程,緩沖隊列已滿,如果此時向線程提交任務(wù),將會拋出RejectedExecutionException

    問題:拋出的錯誤不catch的話會導(dǎo)致程序FC。

    好吧,理論分析之后還是要結(jié)合實際例子,我們通過實現(xiàn)一個模擬異步獲取網(wǎng)絡(luò)圖片的例子,看看會不會出現(xiàn)上面提到的問題。

    例子:使用GridView模擬異步加載大量圖片

    ActivityA.java

    package com.zhuozhuo;

     

    import java.util.ArrayList;

    import java.util.Collection;

    import java.util.HashMap;

    import java.util.Iterator;

    import java.util.List;

    import java.util.ListIterator;

    import java.util.Map;

     

    import android.app.Activity;

    import android.app.AlertDialog;

    import android.app.Dialog;

    import android.app.ListActivity;

    import android.app.ProgressDialog;

    import android.content.Context;

    import android.content.DialogInterface;

    import android.content.Intent;

    import android.database.Cursor;

    import android.graphics.Bitmap;

    import android.os.AsyncTask;

    import android.os.Bundle;

    import android.provider.ContactsContract;

    import android.util.Log;

    import android.view.LayoutInflater;

    import android.view.View;

    import android.view.ViewGroup;

    import android.widget.AbsListView;

    import android.widget.AbsListView.OnScrollListener;

    import android.widget.Adapter;

    import android.widget.AdapterView;

    import android.widget.AdapterView.OnItemClickListener;

    import android.widget.BaseAdapter;

    import android.widget.GridView;

    import android.widget.ImageView;

    import android.widget.ListAdapter;

    import android.widget.SimpleAdapter;

    import android.widget.TextView;

    import android.widget.Toast;

     

    public class ActivityA extends Activity {

        private GridView mGridView;

        private List<HashMap<String, Object>> mData;

        private BaseAdapter mAdapter;

        private ProgressDialog mProgressDialog;

        private static final int DIALOG_PROGRESS = 0;

        @Override

        public void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            setContentView(R.layout.main);

            mGridView = (GridView) findViewById(R.id.gridview);

            mData = new ArrayList<HashMap<String,Object>>();

            mAdapter = new CustomAdapter();

            mGridView.setAdapter(mAdapter);

        }

        protected void onStart () {

           super.onStart();

           new GetGridDataTask().execute(null);//執(zhí)行獲取數(shù)據(jù)的任務(wù)

        }

        @Override

        protected Dialog onCreateDialog(int id) {

            switch (id) {

            case DIALOG_PROGRESS:

                mProgressDialog = new ProgressDialog(ActivityA.this);

                mProgressDialog.setMessage("正在獲取數(shù)據(jù)");

                mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);

                return mProgressDialog;

            }

            return null;

        }

        class CustomAdapter extends BaseAdapter {

           CustomAdapter() {

              

           }

           @Override

           public int getCount() {

               return mData.size();

           }

           @Override

           public Object getItem(int position) {

               return mData.get(position);

           }

           @Override

           public long getItemId(int position) {

               return 0;

           }

           @Override

           public View getView(int position, View convertView, ViewGroup parent) {

               View view = convertView;

               ViewHolder vh;

               if(view == null) {

                  view = LayoutInflater.from(ActivityA.this).inflate(R.layout.list_item, null);

                  vh = new ViewHolder();

                  vh.tv = (TextView) view.findViewById(R.id.textView);

                  vh.iv = (ImageView) view.findViewById(R.id.imageView);

                  view.setTag(vh);

               }

               vh = (ViewHolder) view.getTag();

               vh.tv.setText((String) mData.get(position).get("title"));

               Integer id = (Integer) mData.get(position).get("pic");

               if(id != null) {

                  vh.iv.setImageResource(id);

               }

               else {

                  vh.iv.setImageBitmap(null);

               }

              

               FifoAsyncTask task = (FifoAsyncTask) mData.get(position).get("task");

               if(task == null || task.isCancelled()) {

                  Log.d("Test", "" + position);

                  mData.get(position).put("task", new GetItemImageTask(position).execute(null));//執(zhí)行獲取圖片的任務(wù)

               }

              

               return view;

           }

        }

        static class ViewHolder {

           TextView tv;

           ImageView iv;

        }

        class GetGridDataTask extends FifoAsyncTask<Void, Void, Void> {

          

           protected void onPreExecute () {

               mData.clear();

               mAdapter.notifyDataSetChanged();

              

               showDialog(DIALOG_PROGRESS);//打開等待對話框

           }

           @Override

           protected Void doInBackground(Void... params) {

              

               try {

                  Thread.sleep(500);//模擬耗時的網(wǎng)絡(luò)操作

               } catch (InterruptedException e) {

                  e.printStackTrace();

               }

               for(int i = 0; i < 200; i++) {

                  HashMap<String, Object> hm = new HashMap<String, Object>();

                  hm.put("title", "Title");

                  mData.add(hm);

               }

              

               return null;

           }

           protected void onPostExecute (Void result) {

               mAdapter.notifyDataSetChanged();//通知ui界面更新

               dismissDialog(DIALOG_PROGRESS);//關(guān)閉等待對話框

           }

          

        }

        class GetItemImageTask extends FifoAsyncTask<Void, Void, Void> {

          

           int pos;

          

           GetItemImageTask(int pos) {

               this.pos = pos;

           }

           @Override

           protected Void doInBackground(Void... params) {

               try {

                  Thread.sleep(2000); //模擬耗時的網(wǎng)絡(luò)操作

               } catch (InterruptedException e) {

                  e.printStackTrace();

               }

               mData.get(pos).put("pic", R.drawable.icon);

               return null;

           }

           protected void onPostExecute (Void result) {

               mAdapter.notifyDataSetChanged();//通知ui界面更新

           }

        }

    }

    當網(wǎng)絡(luò)情況較差,異步任務(wù)不能盡快完成執(zhí)行的情況下,新開的線程會造成listview滑動不流暢。當開啟的工作線程過多時,還有出現(xiàn)FC的可能。

    至此,你還相信萬能的AsyncTask嗎?至于你信不信,反正我不信。

    總結(jié):

    AsyncTask可能存在新開大量線程消耗系統(tǒng)資源和導(dǎo)致應(yīng)用FC的風(fēng)險,因此,我們需要根據(jù)自己的需求自定義不同的線程池,由于篇幅問題,將留到下篇再講。

    posted on 2013-02-24 16:37 L遷客 閱讀(72) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 福利免费观看午夜体检区| 亚洲 日韩 色 图网站| 国产人成亚洲第一网站在线播放| 成视频年人黄网站免费视频| 亚洲日韩精品无码专区| 成人免费福利电影| 久久亚洲精品国产亚洲老地址 | 亚洲伊人久久大香线蕉影院| 99re6热视频精品免费观看| 亚洲AV无码乱码国产麻豆穿越 | 九月婷婷亚洲综合在线| 美女露100%胸无遮挡免费观看| 日韩成人免费视频播放| 久久亚洲中文字幕无码| 亚洲国模精品一区| a级毛片免费观看视频| 自怕偷自怕亚洲精品| 亚洲黄色免费观看| 亚洲人成影院77777| 国产福利电影一区二区三区,亚洲国模精品一区 | 最近中文字幕免费mv视频7| 一区二区三区免费视频观看 | 国产成+人+综合+亚洲专| 最近中文字幕mv免费高清视频7| 国产精品免费在线播放| 久久综合亚洲色HEZYO社区| 亚洲?V无码成人精品区日韩| 久草视频免费在线| 精品国产亚洲AV麻豆| 爱情岛论坛网亚洲品质自拍| 国国内清清草原免费视频99| 久久久久久久久无码精品亚洲日韩| 亚洲AV日韩AV永久无码下载| A在线观看免费网站大全| 免费观看91视频| 亚洲人成免费电影| 亚洲av无码av制服另类专区| 俄罗斯极品美女毛片免费播放| 国产高清视频免费在线观看 | 亚洲三级在线播放| 免费在线观看日韩|