er...

On 6月30日, 下午10时40分, Streets Of Boston <flyingdutc...@gmail.com> wrote:
> Your code in your getView implementation of the adapter looks good at
> first sight. The structure of this method looks good.
>
> I think there are a few issues though.
>
> In your getView(...) method, you access the variable 'appList':
>
>                         if (position >= appList.size()) {
>                                 return null;
>                         }
>
> and
>
>                         ObjectToShow objectToShow = appList.get
> (position);
>                         ObjectToShow objectToShowWithMetadata =
> appMap.get
>
> The only place i can find a declared variable called 'appList' in your
> example code is the one that is a private member of IconLoaderThread:
>
>         class IconLoaderThread extends Thread {
>                 List<ObjectToShow> appList;
>                 ...
>         }
>
> In short, this 'appList' is accessed in two threads without any
> synchronization or attempt to make it immutable.
>
> Also, the plain assignment here worries me:
>                 public EfficientAdapter(Context c, List<ObjectToShow>
> appList) {
>                         if (appList != null) {
>                                 // Just refresh the list
>                             --> appLocalList = appList; <---
>                                 ...
>                         }
>                         ...
>                 }
>
> because in the method 'initList' you do something similar, but you
> assign a copy of appList to appLocalList.
>
> On Jun 30, 12:43 am, Peter <pkana...@gmail.com> wrote:
>
> > Doug, you were right.
>
> > If I inflate a new view each time instead of using the cached
> > convertView, the images never show incorrectly. This is obviously less
> > efficient, but it's right. I need to look more closely to see if I was
> > abusing the ViewHolder pattern, but I don't see how I was.
>
> > This is what I'm doing now in convertView():
>
> > public View getView(int position, View convertView, ViewGroup
> > parent)
> >                 {
> >                         if (position >= appList.size()) {
> >                                 return null;
> >                         }
> >                         convertView = mInflater.inflate
> > (R.layout.app_list_item, null);
>
> >                         ObjectToShow objectToShow = appList.get
> > (position);
> >                         ObjectToShow objectToShowWithMetadata =
> > appMap.get
> >                         (objectToShow.getKey());
> >                         if(objectToShow != null) {
> >                                 if(objectToShowWithMetadata.getName() !
> > = null) {
> >                                         ((TextView)
> > convertView.findViewById(R.id.app_list_item_name)).setText
> > (objectToShowWithMetadata.getName());
> >                                 }
> >                                 if(iconMap.get(objectToShow.getKey()) !
> > = null) {
> >                                         ((ImageView)
> > convertView.findViewByI(R.id.app_list_item_icon)).setImageBitmap
> > (iconMap.get(objectToShow.getKey()));
> >                                 }
> >                         } else {
> >                                 ((TextView)convertView.findViewById
> > (R.id.app_list_item_name)).setText(defaultText);
> >                                 ((ImageView)convertView.findViewByI
> > (R.id.app_list_item_icon)).setImageDrawable(defaultIcon);
> >                         }
> >                         return convertView;
> >                 }
>
> > Any thoughts?
>
> > On Jun 27, 4:17 pm, Doug <dougforp...@gmail.com> wrote:
>
> > > Have you tried *not* caching the component views in your ViewHolder
> > > object - instead looking them up whenever you get a redraw request?
> > > You may find that the list is re-using objects, and your image issue
> > > is simply an artifact of that.
>
> > > Doug
>
> > > On Jun 26, 10:56 pm, Peter <pkana...@gmail.com> wrote:
>
> > > > > There's not adefaultnumberof views created for an adapter. A list
> > > > > creates as many views as it needs to fill the screen. Views get reused
> > > > > only when you start scrolling or when the adapter send a
> > > > > notifyDatasetChanged(). You say you have a thread updating the data,
> > > > > what is exactly that thread doing? Please show code.
>
> > > > Here is some code. Perhaps it will help.
>
> > > > ********** the worker thread ***************
> > > > --------------------------------------
>
> > > >         class IconLoaderThread extends Thread {
> > > >                 List<ObjectToShow> appList;
> > > >                 void loadAllResources(List<ObjectToShow> appList) {
> > > >                         this.appList = appList;
> > > >                         start();
> > > >                 }
>
> > > >                 public void run() {
> > > >                         int maxSize;
>
> > > >                         for (int i = 0; i < maxSize; i++) {
> > > >                                 ObjectToShow appInfo = appList.get(i);
> > > > // network access occurs here
> > > >                                 Bitmap icon = 
> > > > appQuery.lookupAppIcon(appInfo);
> > > >                                 Message msg = 
> > > > handler.obtainMessage(MSG_REFRESH_APP_ICON);
> > > >                                 Bundle data = new Bundle();
> > > >                                 data.putString("s3ObjectKey", 
> > > > appInfo.getS3ObjectKey());
> > > >                                 msg.obj = icon;
> > > >                                 msg.setData(data);
> > > >                                 handler.sendMessage(msg);
> > > >                         }
> > > >                         Message doneMsg = 
> > > > handler.obtainMessage(MSG_ICONS_DONE);
> > > >                         handler.sendMessage(doneMsg);
> > > >                 }
> > > >         }
>
> > > > ********** the handler ***************
> > > > --------------------------------------
>
> > > >         private Handler handler = new Handler() {
> > > >                 public void handleMessage(Message msg) {
> > > >                         ObjectToShow appInfo;
> > > >                         switch (msg.what) {
> > > >                         case MSG_INIT_APP_LIST:
> > > >                                 initProgressBar();
> > > >                                 
> > > > handler.sendEmptyMessage(MSG_NEXT_LOAD_STEP);
> > > >                                 break;
> > > >                         case MSG_REFRESH_APP_ICON:
> > > >                                 Bitmap icon = (Bitmap)msg.obj;
> > > >                                 String s3ObjectKey = 
> > > > msg.getData().getString("s3ObjectKey");
> > > >                                 if(icon == null || s3ObjectKey == null) 
> > > > {
> > > >                                         Log.w(TAG, "Error loading 
> > > > icon");
> > > >                                 } else {
> > > >                                         
> > > > efficientAdapter.updateAppInfoIcon(s3ObjectKey, icon);
> > > >                                 }
> > > >                                 break;
> > > >                         case MSG_REFRESH_APP_METADATA:
> > > >                                 appInfo = (ObjectToShow)msg.obj;
> > > >                                 if(appInfo == null) {
> > > >                                         Log.w(TAG, "Error loading 
> > > > icon");
> > > >                                 } else {
> > > >                                         
> > > > efficientAdapter.updateAppInfoMetadata(appInfo);
> > > >                                 }
> > > >                                 break;
> > > >                         case MSG_METADATA_DONE:
> > > >                                 metadataLoaded = true;
> > > >                                 
> > > > handler.sendEmptyMessage(MSG_NEXT_LOAD_STEP);
> > > >                                 break;
> > > >                         case MSG_ICONS_DONE:
> > > >                                 iconsLoaded = true;
> > > >                                 
> > > > handler.sendEmptyMessage(MSG_NEXT_LOAD_STEP);
> > > >                                 break;
> > > >                         case MSG_NEXT_LOAD_STEP:
> > > >                                 if (metadataLoaded && iconsLoaded) {
> > > >                                         doneLoadingMetadata();
> > > >                                 }
> > > >                                 else if (metadataLoaded || iconsLoaded) 
> > > > {
> > > >                                         if (firstRun) {
> > > >                                                 // Set the adapter here.
> > > >                                                 firstRun = false;
> > > >                                                 
> > > > appListView.setAdapter(efficientAdapter);
> > > >                                                 dismissLoadingMessage();
> > > >                                         }
> > > >                                         initIconThread();
>
> ...
>
> 阅读更多 >>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers-unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to