1

我实现了ListView使用扩展自ArrayAdapter. 我的问题是有时ListView加载缓慢。这意味着首先加载一个没有 的空白活动ListView,然后ListView出来。在最坏的情况下,系统会提示我“强制关闭或等待”。我喜欢改善这种缓慢的加载,因为它对用户来说很烦人。

但有时,加载速度很快,几乎是立即的。

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

我的 ListView 设计如下。

每个 ListItem 包含三个组件,缩略图、ID 文本和箭头图像,如附图所示图片

在加载过程中ListView, (1)从数据库中检索所有 ID 文本并填充到 ListArrayList<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;
}
4

1 回答 1

0

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

于 2013-08-15T12:05:28.563 回答