我使用从ListView
扩展的自定义适配器实现了我的ArrayAdapter
。
我的问题有时会ListView
缓慢加载。这意味着在没有ListView
的情况下首先加载空白活动,然后ListView
出来。在最坏的情况下,我被提示“强制关闭或等待”。我喜欢改善缓慢加载,因为这会让用户感到烦恼。
但有时候,加载速度快且几乎是即时的。
但我想确保我的ListView
设计是正确的,并且设计对于缓慢加载没有任何问题。因此,这个讨论对于面临与我相同问题的其他人会有用。
我的ListView设计如下。
每个ListItem都有三个组件,缩略图图像,ID文本和箭头图像,如附图所示。
在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;
}
答案 0 :(得分:0)
我做了一些事情来加快应用程序的速度。
我不确定哪一个是解决方案。
(1)我使用AsyncTask
加载来自sql数据库的所有数据,包括文本和缩略图。
(2)我将缩略图图像格式从png更改为jpg。
(3)然后我手动清除缓存。
该应用程序在加载时看起来更快,但有时它仍然很慢。大多数时候,它比以前更快。
我仍然在改进我的应用程序。
谢谢