0

I would expect this (inside getView()) to work...

but nothing happens, the bitmaps are not loaded into the ImageView....

Thread th= new Thread(new Runnable() {

           @Override
           public void run() {

               ImageLoader.getInstance().displayImage(rss.getChannel().getItems().get(position).getEnclosure().getUrl(),holder.imageView,options,new ImageLoadingListener() {
                   @Override
                   public void onLoadingStarted(String imageUri, View view) {
                   //...stuff...
                   }

                   //... more stuff

                   @Override
                   public void onLoadingCancelled(String imageUri, View view) {
                  //...stuff
                  }
               });

           }
       });

th.start();

Please why it's not???

Thanks :-)

Lisa Anne
  • 4,482
  • 17
  • 83
  • 157

3 Answers3

4

What you try to do is really bad practice. However, I cant tell you from the information you provide us what the problem is. I think that the ImageLoading library is already doing things in its own thread, therefore your Thread is already finished. Also only the main UI Thread can access or manipulate UI Views, but there should be an exception thrown if this would be the problem.

Furthermore, I would recommend you to use Picasso. It handles Threadpooling, scheduling, caching, memory management (avoid memory leaks by using WeakReference) and recycling view in ListView or RecyclerView.

Update:

You are creating a Thread everytime getView() is called while scrolling. This is bad practice, because creating a Thread is expensive. Think about flinging or fast scrolling a list. If you scroll 20 elements, 20 Threads will be created and started. All the thready have the same priority as the main UI thread. That means that the CPU is shared between 20 Threads plus the main UI Thread. This could lead to bad UI performance. You should use a ThreadPool. Furthermore, you don't stop your Thread. This brings two problems:

  1. Your view get recycled in getView() while the Thread is not, so the thread is still running while the view should display already another item.
  2. You get memory leaks! Do you know how Garbage Collection works? It starts at thread level and searches for unused objects (objects that are not referenced anymore by any other object). Your Thread is a inner class. Therefore it has a hard reference to the surrounding Adapter class. The Adapter is attached to the ListView, the ListView to the Activity. So if your Activity gets closed by the user the garbage collector can not collect Activity and all the views and other objects until the Thread (or in your case, all Threads) are finished. You probably run out of memory.

Last but not least, the Android System has its own message queue based threading system and only the main UI Thread can access UI Views. I don't want to get to deep in detail here, I'm sure you can google it. At this point I recommend to use AsyncTask if you really have to start your own Thread. But you also have to cancel the AsyncTask manually to avoid memory leaks.

sockeqwe
  • 15,574
  • 24
  • 88
  • 144
  • No, it does not work, because even if `ImageLoader` uses its own thread to update the imageview, nonetheless `ImageLoader.getInstance().displayImage` gets called, hence the imageview should be updated... :-((( Thanks Anyway – Lisa Anne Feb 12 '15 at 18:16
  • Please what is so bad about my approach ? – Lisa Anne Feb 12 '15 at 18:21
  • The exception is not always thrown, but as a result you won't have your UI updated. http://stackoverflow.com/questions/20600326/android-why-does-this-not-throw-wrong-thread-exception – vinitius Feb 12 '15 at 18:21
  • I would also recommend you to use Picasso. But you can do it manually if you want , just when setting the imageResource for your imageView, you have to be on the UIThread – vinitius Feb 12 '15 at 18:23
  • @LisaAnne I have updated my answer with an detailed explanation why its bad practice – sockeqwe Feb 12 '15 at 18:41
1

First of all, Android application UI not updated or accessed from worker thread. So your Thread not going to change/access Image.

Second, you don't need Thread for Image loading, as your ImageLoader library itself take care of it.

user370305
  • 108,599
  • 23
  • 164
  • 151
1

Only the UIThread can change its views. I suggest to use runOnUIThread() method from Activity.

More info: https://developer.android.com/training/multiple-threads/communicate-ui.html

vinitius
  • 3,212
  • 2
  • 17
  • 22