【问题标题】:First time I receive 1 Picasso image and the second time I receive them all我第一次收到一张毕加索图片,第二次收到所有图片
【发布时间】:2017-04-23 19:59:43
【问题描述】:

我在 for 循环中创建了毕加索的目标。我第一次收到 1 张图像,其他图像进入“onPrepareLoad”语句。我第二次收到所有图像。为什么第一次不工作?

代码:

        final Set<Target> protectedFromGarbageCollectorTargets = new HashSet<>();

        for (int i = 0; i < alleFotosArray.size(); i++) {
            final Target target = new Target() {
                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                    protectedFromGarbageCollectorTargets.remove(this);

                    int width = bitmap.getWidth();
                    int height = bitmap.getHeight();

                    deelnemerSizesFotos sizeFotos = new deelnemerSizesFotos();

                    sizeFotos.setWidth(width);
                    sizeFotos.setHeight(height);

                    sizeFotosArray.add(sizeFotos);
                }

                @Override
                public void onBitmapFailed(Drawable errorDrawable) {
                    protectedFromGarbageCollectorTargets.remove(this);

                    deelnemerSizesFotos sizeFotos = new deelnemerSizesFotos();

                    sizeFotos.setWidth(200);
                    sizeFotos.setHeight(200);

                    sizeFotosArray.add(sizeFotos);
                }

                @Override
                public void onPrepareLoad(Drawable placeHolderDrawable) {
                    deelnemerSizesFotos sizeFotos = new deelnemerSizesFotos();

                    sizeFotos.setWidth(200);
                    sizeFotos.setHeight(200);

                    sizeFotosArray.add(sizeFotos);
                }
            };

            protectedFromGarbageCollectorTargets.add(target);
            Picasso.with(c).load(alleFotosArray.get(i).getImageurl()).into(target);
}

【问题讨论】:

  • 我有最终的目标,但是如何使用 ImageView 做到这一点?我没有 ImageView。
  • final 不会阻止垃圾回收。您需要将Target 的引用保留到不会被垃圾收集的对象。只是一个想法,您可以通过调用targetList.add(target); 将成员变量List&lt;Target&gt; targetList = new ArrayList&lt;&gt;(); 设置为Activity 以保持目标的引用。
  • 我需要把'targetList.add(target)'放在哪里?
  • 在你的 for 循环中。让我知道这是否能解决问题。

标签: android image bitmap imageview picasso


【解决方案1】:

为毕加索添加内存策略

Picasso.with(c).load(alleFotosArray.get(i).getImageurl()).memoryPolicy(MemoryPolicy.NO_CACHE).into(target);

【讨论】:

  • 有什么区别?
  • 抱歉,毕加索加载在 for 循环中
  • 你的 Picasso 语句在 for 循环之外
  • 我现在试试
  • 我第一次和第二次都需要接收所有图像的所有高度,但问题是很多图像第一次进入'onPrepareLoad'语句。
【解决方案2】:

您只需要保留对您创建的目标对象的引用,因为 Picasso 对它使用 WeakReference,而且从 Android 2.3(API 级别 9)开始,垃圾收集器在收集软/弱引用方面更加积极。

在 Activity 中保留引用的示例

public class YourActivity extends Activity {

    private List<Target> targetList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getImages();
    }

    private void getImages() {
        for (int i = 0; i < alleFotosArray.size(); i++) {
            final Target target = new Target() {
                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                    int width = bitmap.getWidth();
                    int height = bitmap.getHeight();

                    deelnemerSizesFotos sizeFotos = new deelnemerSizesFotos();

                    sizeFotos.setWidth(width);
                    sizeFotos.setHeight(height);

                    sizeFotosArray.add(sizeFotos);
                }

                @Override
                public void onBitmapFailed(Drawable errorDrawable) {
                    deelnemerSizesFotos sizeFotos = new deelnemerSizesFotos();

                    sizeFotos.setWidth(200);
                    sizeFotos.setHeight(200);

                    sizeFotosArray.add(sizeFotos);
                }

                @Override
                public void onPrepareLoad(Drawable placeHolderDrawable) {
                    deelnemerSizesFotos sizeFotos = new deelnemerSizesFotos();

                    sizeFotos.setWidth(200);
                    sizeFotos.setHeight(200);

                    sizeFotosArray.add(sizeFotos);
                }
            };

            targetList.add(target);
            Picasso.with(c).load(alleFotosArray.get(i).getImageurl()).into(target);
        }
    }
}

【讨论】:

  • 我使用 AsyncTask 类,但 List 也不起作用。
  • 您是否将您的列表声明为成员变量?
  • 在我的问题中,您可以看到我是如何做到的。我在全局变量列表中写了我的列表。
  • 但是第二次成功而第一次没有(可能是因为它们已经在缓存中),这真的很奇怪。
  • 如果您已经将引用存储在全局变量列表中,并且行为仍然存在,那就很奇怪了。通常这应该有效......
【解决方案3】:

我使用的是 ViewPager,所以我不必立即加载所有图像。如果我愿意,我可以在 ViewPager 的“onPageSelected”方法中一一加载它们。

代码:

AndroidImageAdapter adapterView = new AndroidImageAdapter(c, alleFotosArray, left, right, flImage);
        mViewPager.setAdapter(adapterView);

        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                    Picasso.with(c).load(alleFotosArray.get(position).getImageurl()).into(new Target() {
                        @Override
                        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                            int width = bitmap.getWidth();
                            int height = bitmap.getHeight();

                            deelnemerSizesFotos sizeFotos = new deelnemerSizesFotos();

                            sizeFotos.setWidth(width);
                            sizeFotos.setHeight(height);

                            sizeFotosArray.add(sizeFotos);

                            try {
                                int widthFoto = bitmap.getWidth();
                                int heightFoto = bitmap.getHeight();

                                heightContainer = mViewPager.getHeight();
                                widthContainer = mViewPager.getWidth();

                                if (widthFoto == 0 || heightFoto == 0) {
                                    widthFoto = 200;
                                    heightFoto = 200;
                                }

                                    FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) flImage.getLayoutParams();

                                    //in het begin krijg je 1 foto te zien van de vorige pagina. Omdat ik de breedte en hoogte niet van de container krijg
                                    //heb ik deze if gemaakt waarbij de hoogte en breedte wordt opgehaald
                                    if (heightContainer == 0 || widthContainer == 0) {
                                        heightContainer = params.height;

                                        //breedte scherm pixels ophalen
                                        DisplayMetrics metrics = new DisplayMetrics();
                                        WindowManager windowManager = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
                                        windowManager.getDefaultDisplay().getMetrics(metrics);

                                        widthContainer = metrics.widthPixels;
                                    }

                                    float r = (float) widthFoto / (float) widthContainer;
                                    float h = (float) heightFoto / r;

                                    // Changes the height and width to the specified *pixels*
                                    params.height = (int) h;
                                    params.width = widthContainer;

                                    flImage.setLayoutParams(params);
                            } catch (Exception e) {
                                FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) flImage.getLayoutParams();

                                //breedte scherm pixels ophalen
                                DisplayMetrics metrics = new DisplayMetrics();
                                WindowManager windowManager = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
                                windowManager.getDefaultDisplay().getMetrics(metrics);

                                params.width = metrics.widthPixels;

                                flImage.setLayoutParams(params);
                            } 

                        @Override
                        public void onBitmapFailed(Drawable errorDrawable) {
                            deelnemerSizesFotos sizeFotos = new deelnemerSizesFotos();

                            sizeFotos.setWidth(200);
                            sizeFotos.setHeight(200);

                            sizeFotosArray.add(sizeFotos);
                        }

                        @Override
                        public void onPrepareLoad(Drawable placeHolderDrawable) {
                            deelnemerSizesFotos sizeFotos = new deelnemerSizesFotos();

                            sizeFotos.setWidth(200);
                            sizeFotos.setHeight(200);

                            sizeFotosArray.add(sizeFotos);
                        }
                    });
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 2019-05-17
    • 2016-06-14
    • 2019-08-05
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    相关资源
    最近更新 更多