Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug when loadImage into RemoteViewsFactory #199

Closed
daimonkor opened this issue Mar 7, 2013 · 19 comments
Closed

Bug when loadImage into RemoteViewsFactory #199

daimonkor opened this issue Mar 7, 2013 · 19 comments
Labels

Comments

@daimonkor
Copy link

bug http://prntscr.com/vez6f

    File cacheDir = new File(WidgetProvider.IMG_PATH);
            DisplayImageOptions optionsWithFakeDisplayer = new DisplayImageOptions.Builder()
                    .displayer(new FadeInBitmapDisplayer(2000)).cacheOnDisc()
                    .showImageForEmptyUri(R.drawable.ic_launcher)
                    .showStubImage(R.drawable.ic_launcher).build();

            ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
                    this).threadPoolSize(3)
                    .threadPriority(Thread.NORM_PRIORITY - 1)
                    .denyCacheImageMultipleSizesInMemory().offOutOfMemoryHandling()
                    .memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024))
                    .discCache(new UnlimitedDiscCache(cacheDir))
                    .defaultDisplayImageOptions(optionsWithFakeDisplayer) 
                    .enableLogging().build();
            ImageLoader.getInstance().init(config);

////////////////////////
public class ClansListViewFactory implements
        RemoteViewsService.RemoteViewsFactory {

    @Override
    public RemoteViews getViewAt(int position) {
        row = null;
        row = new RemoteViews(context.getPackageName(),
                R.layout.clans_clan_thumbnail);

        if(arrayList != null && !arrayList.isEmpty()){
              ImageLoader.getInstance().loadImage(arrayList.get(position).getClansIconSrc(),
                    new SimpleImageLoadingListener() {

                        @Override
                        public void onLoadingComplete(String imageUri,
                                View view, Bitmap loadedImage) {
            row.setImageViewBitmap(R.id.clan_icon,loadedImage);
                            super.onLoadingComplete(imageUri, view, loadedImage);
                        }
                    });


        }

        return row;
    }

it is listview factory for widget
ImageLoader work well into another activity
please help

@nostra13
Copy link
Owner

nostra13 commented Mar 8, 2013

It seems getViewAt(int position) is called from non-UI thread. ImageLoader.loadImage(...) should be called on UI thread.
Try to change your logic or play with Looper.prepare() (call it before ImageLoader.loadImage(...))

@daimonkor
Copy link
Author

sorry but http://prntscr.com/vgrvr

Looper.prepare() was pasted before ImageLoader.loadImage(...)

@daimonkor
Copy link
Author

        if(Looper.myLooper() == null)
            Looper.prepare();
                    ImageLoader.getInstance().loadImage(arrayList.get(ClansListViewFactory.this.position).getClansIconSrc(),
                            new SimpleImageLoadingListener() {
                                @Override
                                public void onLoadingFailed(String imageUri, View view,
                                        FailReason failReason) {
                                    Log.v("FAILED", "DSDDDDDDDDD");
                                Drawable drawable =  ClansListViewFactory.this.context.getResources().getDrawable( R.drawable.ic_launcher );
                                Bitmap bitmap = ((BitmapDrawable) com.icebergteam.wotwidget.news.ui.NewsItem.scaleImage(drawable,50)).getBitmap();
                                row.setImageViewBitmap(R.id.clan_icon, bitmap);
                                    super.onLoadingFailed(imageUri, view, failReason);
                                }

                                @Override
                                public void onLoadingComplete(String imageUri,
                                        View view, Bitmap loadedImage) {
                                    Log.v("COMPLETE", "DSDDDDDDDDD");
                            Drawable drawable = new BitmapDrawable(loadedImage);
                            Bitmap bitmap = ((BitmapDrawable) com.icebergteam.wotwidget.news.ui.NewsItem.scaleImage(drawable,50)).getBitmap();
                                row.setImageViewBitmap(R.id.clan_icon,bitmap);
                                    super.onLoadingComplete(imageUri, view, loadedImage);
                                }

                                @Override
                                public void onLoadingStarted(String imageUri,
                                        View view) {
                                    Log.v("DDDDDDDDDDDD", "DSDDDDDDDDD");
                                    super.onLoadingStarted(imageUri, view);
                                }
                            });

http://prntscr.com/vihda
missing call onLoadingComplete(...)

@nostra13
Copy link
Owner

nostra13 commented Mar 8, 2013

I think you need synchronous image loading.
Try to use next code in getViewAt(...):

final Object lock = new Object();
boolean loaded = false;
ImageSize targetImageSize = new ImageSize(70, 70);
ImageLoader.getInstance().loadImage(imageUri, targetImageSize, options, new SimpleImageLoadingListener() {
    @Override
    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
        loaded = true;
        // Do whatever you want with loadedImage

        synchronize(lock) {
            lock.notifyAll();
        }
    }
});
if (!loaded) {
    synchronize(lock) {
        lock.wait();
    }
}

Remove all your code about Looper.

@daimonkor
Copy link
Author

http://prntscr.com/vilop Looper need

@Override
    public RemoteViews getViewAt(int position) {
        this.position = position;
        this.row = null;
        this.row = new RemoteViews(context.getPackageName(),
                R.layout.clans_clan_thumbnail);

        if(arrayList != null && !arrayList.isEmpty()){
            this.lock = null;
            this.lock = new Object();
            this.loaded = false;
                    ImageLoader.getInstance().loadImage(arrayList.get(ClansListViewFactory.this.position).getClansIconSrc(),
                            new SimpleImageLoadingListener() {
                                @Override
                                public void onLoadingFailed(String imageUri, View view,
                                        FailReason failReason) {
                                    Log.v("FAILED", "DSDDDDDDDDD");
                                Drawable drawable =  ClansListViewFactory.this.context.getResources().getDrawable( R.drawable.ic_launcher );
                                Bitmap bitmap = ((BitmapDrawable) com.icebergteam.wotwidget.news.ui.NewsItem.scaleImage(drawable,50)).getBitmap();
                                ClansListViewFactory.this.row.setImageViewBitmap(R.id.clan_icon, bitmap);
                                ClansListViewFactory.this.loaded = true;
                                 synchronized(ClansListViewFactory.this.lock) {
                                     ClansListViewFactory.this. lock.notifyAll();
                                    super.onLoadingFailed(imageUri, view, failReason);
                                }
                                }

                                @Override
                                public void onLoadingComplete(String imageUri,
                                        View view, Bitmap loadedImage) {
                                    Log.v("COMPLETE", "DSDDDDDDDDD");
                            Drawable drawable = new BitmapDrawable(loadedImage);
                            Bitmap bitmap = ((BitmapDrawable) com.icebergteam.wotwidget.news.ui.NewsItem.scaleImage(drawable,50)).getBitmap();
                            ClansListViewFactory.this.row.setImageViewBitmap(R.id.clan_icon,bitmap);
                                    super.onLoadingComplete(imageUri, view, loadedImage);
                                    ClansListViewFactory.this.loaded =true;
                                }


                            });

                    if (!ClansListViewFactory.this.loaded) {
                        synchronized(ClansListViewFactory.this.lock) {
                            try {
                                ClansListViewFactory.this.lock.wait();
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    }   



        }

        return row;
    }

@nostra13
Copy link
Owner

nostra13 commented Mar 8, 2013

Ok, try with Looper.

@daimonkor
Copy link
Author

@Override
    public RemoteViews getViewAt(int position) {
        this.position = position;
        this.row = null;
        this.row = new RemoteViews(context.getPackageName(),
                R.layout.clans_clan_thumbnail);

        if(arrayList != null && !arrayList.isEmpty()){
            this.lock = null;
            this.lock = new Object();
            this.loaded = false;
            if(Looper.myLooper() == null){
                Looper.prepare();
            }
                    ImageLoader.getInstance().loadImage(arrayList.get(ClansListViewFactory.this.position).getClansIconSrc(),
                            new SimpleImageLoadingListener() {
                                @Override
                                public void onLoadingFailed(String imageUri, View view,
                                        FailReason failReason) {

                                    Log.v("FAILED", "DSDDDDDDDDD");
                                Drawable drawable =  ClansListViewFactory.this.context.getResources().getDrawable( R.drawable.ic_launcher );
                                Bitmap bitmap = ((BitmapDrawable) com.icebergteam.wotwidget.news.ui.NewsItem.scaleImage(drawable,50)).getBitmap();
                                ClansListViewFactory.this.row.setImageViewBitmap(R.id.clan_icon, bitmap);
                                ClansListViewFactory.this.loaded = true;
                                     synchronized(ClansListViewFactory.this.lock) {
                                         ClansListViewFactory.this. lock.notifyAll();
                                        super.onLoadingFailed(imageUri, view, failReason);
                                    }
                                }

                                @Override
                                public void onLoadingComplete(String imageUri,
                                        View view, Bitmap loadedImage) {

                                        Log.v("COMPLETE", "DSDDDDDDDDD");
                                        Drawable drawable = new BitmapDrawable(loadedImage);
                                        Bitmap bitmap = ((BitmapDrawable) com.icebergteam.wotwidget.news.ui.NewsItem.scaleImage(drawable,50)).getBitmap();
                                        ClansListViewFactory.this.row.setImageViewBitmap(R.id.clan_icon,bitmap);

                                     ClansListViewFactory.this.loaded =true;

                                     synchronized(ClansListViewFactory.this.lock) {

                                         ClansListViewFactory.this. lock.notifyAll();
                                        super.onLoadingComplete(imageUri, view, loadedImage);
                                    }
                                }


                            });

                    if (!ClansListViewFactory.this.loaded) {
                        synchronized(ClansListViewFactory.this.lock) {
                            try {
                                ClansListViewFactory.this.lock.wait();
                            } catch (InterruptedException e) {

                                e.printStackTrace();
                            }
                        }
                    }   


        }

        return row;
    }

http://prntscr.com/vip66 one call getViewAt(...) and missing call complete or failed
I modified code (paste log)
http://prntscr.com/viyc3
please help

@daimonkor
Copy link
Author

@Override
    public RemoteViews getViewAt(int position) {
    final RemoteViews row = new RemoteViews(context.getPackageName(),
                R.layout.clans_clan_thumbnail);

        if(arrayList != null && !arrayList.isEmpty()){
            final Object lock = new Object();
            loaded = false;
            if(Looper.myLooper() == null){
                Looper.prepare();
            }

            LogManager.LogV(className, "getViewAt", "run", position);
                    ImageLoader.getInstance().loadImage(arrayList.get(position).getClansIconSrc(),
                            new SimpleImageLoadingListener() {
                                @Override
                                public void onLoadingStarted(String imageUri,
                                        View view) {

                                    loaded = true;
                                    Log.v("Started", "DSDDDDDDDDD");
                                    synchronized(lock) {
                                         lock.notifyAll();

                                    }
                                }

                                @Override
                                public void onLoadingFailed(String imageUri, View view,
                                        FailReason failReason) {
                                    loaded = true;
                                    Log.v("FAILED", "DSDDDDDDDDD");
                                Drawable drawable =  ClansListViewFactory.this.context.getResources().getDrawable( R.drawable.ic_launcher );
                                Bitmap bitmap = ((BitmapDrawable) com.icebergteam.wotwidget.news.ui.NewsItem.scaleImage(drawable,50)).getBitmap();
                                row.setImageViewBitmap(R.id.clan_icon, bitmap);

                                     synchronized(lock) {
                                         lock.notifyAll();

                                    }
                                }

                                @Override
                                public void onLoadingComplete(String imageUri,
                                        View view, Bitmap loadedImage) {
                                     loaded =true;
                                        Log.v("COMPLETE", "DSDDDDDDDDD");
                                        Drawable drawable = new BitmapDrawable(loadedImage);
                                        Bitmap bitmap = ((BitmapDrawable) com.icebergteam.wotwidget.news.ui.NewsItem.scaleImage(drawable,50)).getBitmap();
                                        row.setImageViewBitmap(R.id.clan_icon,bitmap);


                                     synchronized(lock) {

                                         lock.notifyAll();

                                    }
                                }

                            });

                    if (!loaded) {
                        LogManager.LogV(className, "getViewAt", "if wait");
                        synchronized(lock) {
                            try {
                                LogManager.LogV(className, "getViewAt", "if wait sync");
                                lock.wait();
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    }   

        }
        LogManager.LogV(className, "getViewAt", "return");
        return row;
    }

http://prntscr.com/vtr1a
feedback function "started" call normally, but "failed" or "completed" call missing
please help

@nostra13
Copy link
Owner

It would be better you send me your project (if you can). So I can play with it to search the solution.

@daimonkor
Copy link
Author

please write your skype

@nostra13
Copy link
Owner

Write me on email - nostra13[at]gmail[dot]com

@NateWickstrom
Copy link

Any luck on this? I'm wanting to do the same thing...

@IstiN
Copy link

IstiN commented May 20, 2013

I've fixed it. See code:

    Map<Integer, Boolean> flags = Collections.synchronizedMap(new HashMap<Integer, Boolean>());
    Bitmap mBitmap;
    Handler handler = new Handler(Looper.getMainLooper());

    @Override
    public RemoteViews getViewAt(final int position) {
        flags.put(position, false);
        handler.post(new Runnable() {
            @Override
            public void run() {
                ImageLoader.getInstance().loadImage(item.getImageUrl(), new SimpleImageLoadingListener() {
                    @Override
                    public void onLoadingStarted(String imageUri, View view) {
                    }

                    @Override
                    public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                        flags.put(position, true);
                    }

                    @Override
                    public void onLoadingCancelled(String imageUri, View view) {
                        flags.put(position, true);
                    }

                    @Override
                    public void onLoadingComplete(String arg0, View arg1, Bitmap bitmap) {
                        mBitmap = bitmap;
                        flags.put(position, true);
                    }
                });
            }
        });

        while (!flags.get(position)) {
            Thread.sleep(200l);
        }
        flags.put(position, false);
        if (mBitmap != null) {
            row.setImageViewBitmap(R.id.icon, mBitmap);
        } else {
            row.setImageViewResource(R.id.icon, R.drawable.bg_cover);
        }
        mBitmap = null;
        flags.put(position, false);
        handler.post(new Runnable() {
            @Override
            public void run() {
                ImageLoader.getInstance().loadImage(item.getImageUrl(), new SimpleImageLoadingListener() {
                    @Override
                    public void onLoadingStarted(String imageUri, View view) {
                    }

                    @Override
                    public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                        flags.put(position, true);
                    }

                    @Override
                    public void onLoadingCancelled(String imageUri, View view) {
                        flags.put(position, true);
                    }

                    @Override
                    public void onLoadingComplete(String arg0, View arg1, Bitmap bitmap) {
                        mBitmap = bitmap;
                        flags.put(position, true);
                    }
                });
            }
        });

        while (!flags.get(position)) {
            Thread.sleep(200l);
        }
        flags.put(position, false);
        if (mBitmap != null) {
            row.setImageViewBitmap(R.id.icon, mBitmap);
        } else {
            row.setImageViewResource(R.id.icon, R.drawable.bg_cover);
        }
        mBitmap = null;
    }

@daimonkor
Copy link
Author

ÉÌÉ Ñ ÐÕÔÁÀÓØ ÉÌÉ ÔÕÔ ÉÄ£Ô 2 ÒÁÚÁ ÐÏÄÒÑÄ ÏÄÉÎÁËÏ×ÙÊ ËÏÄ?

2013/5/21 Vova Klyshevich notifications@github.com

I've fixed it. See code:

Map flags = Collections.synchronizedMap(new HashMap());

Bitmap mBitmap;

Handler handler = new Handler(Looper.getMainLooper());

@OverRide https://github.com/Override
public RemoteViews getViewAt(final int position) {
...

flags.put(position, false);
handler.post(new Runnable() {

                    @Override
                    public void run() {
                        ImageLoader.getInstance().loadImage(item.getImageUrl(), new SimpleImageLoadingListener() {

                            @Override
                            public void onLoadingStarted(String imageUri, View view) {

                            }

                            @Override
                            public void onLoadingFailed(String imageUri, View view,
                                    FailReason failReason) {
                                flags.put(position, true);
                            }

                            @Override
                            public void onLoadingCancelled(String imageUri,
                                    View view) {
                                flags.put(position, true);
                            }

                            @Override
                            public void onLoadingComplete(String arg0, View arg1, Bitmap bitmap) {
                                mBitmap = bitmap;
                                flags.put(position, true);
                            }

                        });
                    }

                });

                while (!flags.get(position)) {
                    Thread.sleep(200l);
                }
                flags.put(position, false);
                if (mBitmap != null) {
                    row.setImageViewBitmap(R.id.icon, mBitmap);
                } else {
                    row.setImageViewResource(R.id.icon, R.drawable.bg_cover);
                }
                mBitmap = null;flags.put(position, false);
                handler.post(new Runnable() {

                    @Override
                    public void run() {
                        ImageLoader.getInstance().loadImage(item.getImageUrl(), new SimpleImageLoadingListener() {

                            @Override
                            public void onLoadingStarted(String imageUri, View view) {

                            }

                            @Override
                            public void onLoadingFailed(String imageUri, View view,
                                    FailReason failReason) {
                                flags.put(position, true);
                            }

                            @Override
                            public void onLoadingCancelled(String imageUri,
                                    View view) {
                                flags.put(position, true);
                            }

                            @Override
                            public void onLoadingComplete(String arg0, View arg1, Bitmap bitmap) {
                                mBitmap = bitmap;
                                flags.put(position, true);
                            }

                        });
                    }

                });

                while (!flags.get(position)) {
                    Thread.sleep(200l);
                }
                flags.put(position, false);
                if (mBitmap != null) {
                    row.setImageViewBitmap(R.id.icon, mBitmap);
                } else {
                    row.setImageViewResource(R.id.icon, R.drawable.bg_cover);
                }
                mBitmap = null;

...
}

Reply to this email directly or view it on GitHubhttps://github.com//issues/199#issuecomment-18178500
.

ëÏÒÎÉÅà äÍÉÔÒÉÊ

@laaptu
Copy link

laaptu commented Jul 12, 2013

@IstiN : Could you format your code a little and if not hassle could you please explain the logic behind.
Thanks in advance

@nostra13
Copy link
Owner

I think you can use sync methods of ImageLoader to display images now (loadImageSync(...))

@grebulon
Copy link

Does Vova's solution pre-dates loadImageSync?

@nostra13
Copy link
Owner

Yes, it does.

@betalita
Copy link

betalita commented Dec 3, 2014

thanks a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants