如何更快地提高ListView加载时间?

时间:2013-07-28 13:46:45

标签: android

我使用从ListView扩展的自定义适配器实现了我的ArrayAdapter。 我的问题有时会ListView缓慢加载。这意味着在没有ListView的情况下首先加载空白活动,然后ListView出来。在最坏的情况下,我被提示“强制关闭或等待”。我喜欢改善缓慢加载,因为这会让用户感到烦恼。

但有时候,加载速度快且几乎是即时的。

但我想确保我的ListView设计是正确的,并且设计对于缓慢加载没有任何问题。因此,这个讨论对于面临与我相同问题的其他人会有用。

我的ListView设计如下。

每个ListItem都有三个组件,缩略图图像,ID文本和箭头图像,如附图image所示。

ListView的加载过程中,(1)从数据库中检索所有ID文本并填充到ListArray List<String> listIDs

        public class MyListFragment extends ListFragment implements OnItemClickListener {
                dbHelper = new TrackerDBAdapter(getActivity());
                dbHelpLatLong = new LatLogDBAdapter(getActivity());
                dbHelpNotification = new NotificationDatabaseAdapter(getActivity());
                dbHelper.open();
                Cursor cursor = dbHelper.fetchAllTrackerInTheList();
                listIDs = new ArrayList<String>();
                activationStatus = new ArrayList<String>();
                thisListFragmentContext = getActivity();
                for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                     listIDs.add(cursor.getString(1));                   
                }
            dbHelper.close();

(2)Then my custom list adapter is called. 




        adapter = new customList_Adaptor(thisListFragmentContext,
                        R.layout.list_row, listIDs, this);
        }

That is the loading process inside my `ListFragment`.

(3)以下类是我的自定义ArrayAdapter,我实施了使用ImageView加载缩略图AsyncTask。我的问题是

(i)我仍然从数据库中检索ID文本,并加载箭头图像。我应该将这些流程也加入AsyncTask吗? (ii)如果我需要它,我应该实现另一个AsyncTask还是使用用于缩略图加载的AsyncTask? (iii)其中,程序设计的哪个方面我仍然可以改进,这对我的慢速加载是否可疑?

public class customList_Adaptor extends ArrayAdapter<String>{


    protected static final int CAMERA_REQUEST = 0;
    private TrackerDBAdapter dbHelper;
    private Context context;
    private List<String> listIDs = new ArrayList<String>();
    private List<String> activationState = new ArrayList<String>();
    public MyListFragment mMyListFragment;
    public customList_Adaptor(Context context, int textViewResourceId,
            List<String> objects, List<String> activationStatus, MyListFragment mMyListFragment) {
        super(context, textViewResourceId, objects);
        this.setContext(context);
        this.listIDs = objects;
        this.activationState = activationStatus;
        this.mMyListFragment= mMyListFragment;
        dbHelper = new TrackerDBAdapter(context);
    }


    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        if(listIDs != null)
            return listIDs.size();
        else
            return 0;
    }

    @Override
    public String getItem(int arg0) {
        // TODO Auto-generated method stub
        if(listIDs != null)
            return listIDs.get(arg0);
        else
            return null;
    }

    @Override
    public long getItemId(int arg0) {
        // TODO Auto-generated method stub
        return arg0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View vi=convertView;
        ViewHolder viewHolder=new ViewHolder();
        LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if(vi==null){
            vi = inflater.inflate(R.layout.list_row, parent, false);
            viewHolder.id=(TextView)vi.findViewById(R.id.title);
            viewHolder.thumbnailImage=(ImageView)vi.findViewById(R.id.list_image);
            viewHolder.activationStatus = (TextView)vi.findViewById(R.id.activated);
            //lazy load image
            BitmapWorkerTask task = new BitmapWorkerTask(viewHolder.thumbnailImage);
            task.execute(position);

            viewHolder.arrow=(ImageView)vi.findViewById(R.id.list_arrow);
            vi.setTag(viewHolder);
        }
        else
            viewHolder=(ViewHolder) vi.getTag();

        viewHolder.thumbnailImage.setOnClickListener(new onMyClick(position));               
        // Setting all values in listview
        viewHolder.id.setText(listIDs.get(position));   

        if(activationState.get(position).equals("Not activated yet")){
             viewHolder.activationStatus.setText(activationState.get(position));
             viewHolder.activationStatus.setTextColor(android.graphics.Color.GRAY);
        }
        else if(activationState.get(position).equals("Activated"))
            viewHolder.activationStatus.setText("");
        return vi;
    }

    public class onMyClick implements OnClickListener {

        private final int pos;
        public onMyClick(int pos) {
            this.pos = pos;
        }

        @Override
        public void onClick(View v) {
            MyListFragment.clickedimageView = (ImageView) v.findViewById(R.id.list_image);                      
            mMyListFragment.imagepos(pos);
        }

    }

    public Context getContext() {
        return context;
    }

    public void setContext(Context context) {
        this.context = context;
    }

    //Lazy image update
    class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
        private final WeakReference<ImageView> imageViewReference;
        private int data = 0;

        public BitmapWorkerTask(ImageView imageView) {
            // Use a WeakReference to ensure the ImageView can be garbage collected
            imageViewReference = new WeakReference<ImageView>(imageView);
        }

        // Decode image in background.
        @Override
        protected Bitmap doInBackground(Integer... params) {
            setData(params[0]);
            Bitmap bitmap = null;
            dbHelper.open();
            Cursor mCursor = dbHelper.getImagebyIDnumber(getData());
            byte[] img_bytes = mCursor.getBlob(13);
            bitmap = BitmapFactory.decodeByteArray(img_bytes, 0, img_bytes.length);         

            dbHelper.close();        
            return bitmap;
        }

        // Once complete, see if ImageView is still around and set bitmap.
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (imageViewReference != null && bitmap != null) {
                final ImageView imageView = imageViewReference.get();
                if (imageView != null) {
                    imageView.setImageBitmap(bitmap);
                }
            }
        }

        public int getData() {
            return data;
        }

        public void setData(int data) {
            this.data = data;
        }
    }

   }


public class ViewHolder {
      TextView id;
      TextView activationStatus;
      ImageView thumbnailImage;
      ImageView arrow;
}

1 个答案:

答案 0 :(得分:0)

我做了一些事情来加快应用程序的速度。 我不确定哪一个是解决方案。 (1)我使用AsyncTask加载来自sql数据库的所有数据,包括文本和缩略图。 (2)我将缩略图图像格式从png更改为jpg。 (3)然后我手动清除缓存。 该应用程序在加载时看起来更快,但有时它仍然很慢。大多数时候,它比以前更快。 我仍然在改进我的应用程序。 谢谢