টার্গেট অবজেক্টের বিটম্যাপলয়েড প্রথম লোডের জন্য ডাকা হয় না


126

আমার ফাংশনে:

public void getPointMarkerFromUrl(final String url, final OnBitmapDescriptorRetrievedListener listener) {
final int maxSize = context.getResources().getDimensionPixelSize(R.dimen.icon_max_size);
Target t = new Target() {
  @Override
  public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
    if (bitmap != null)
      listener.bitmapRetrieved(getBitmapDescriptorInCache(url, bitmap));
    else
      loadDefaultMarker(listener);
  }

  @Override
  public void onBitmapFailed(Drawable errorDrawable) {
    loadDefaultMarker(listener);
  }

  @Override
  public void onPrepareLoad(Drawable placeHolderDrawable) {
  }
};

Picasso.with(context)
    .load(url)
    .resize(maxSize, maxSize)
    .into(t);
}

অন ​​বিটম্যাপলয়েড () কখনই আমি প্রথমবার ছবি লোড করি না। আমি https://github.com/square/picasso/issues/39 এর মতো কিছু বিষয় পড়েছি যা আনতে (টার্গেট টি) পদ্ধতিটি পুনঃসমন করার চেষ্টা করে (এটি দুর্বল রেফারেন্সের সমস্যা বলে মনে হচ্ছে ...), তবে এই ফাংশন পিকাসোর শেষ প্রকাশে উপলব্ধ নেই (২.৩.২) আমি কেবল আনার () পদ্ধতিটি পেয়েছি, তবে আমি একই সাথে (মাইটারেজেট) ব্যবহার করতে পারি না

আপনি কীভাবে আমাকে কাস্টম টার্গেট সহ আনয়ন () ব্যবহার করবেন তা আমাকে ব্যাখ্যা করতে পারেন? ধন্যবাদ.

ডক: http://square.github.io/picasso/javadoc/com/squareup/picasso/RequestCreator.html#fetch--


1
ওখট্টপ ২.০.০ ব্যবহার নিশ্চিত করুন, পিকাসো ২.৩.২ ব্যবহার করার সময় আমি একই সমস্যার মুখোমুখি ওখট্টপ ১.6.০
হাকিম

github.com/square/okhttp তবে, আপনি পিকাসো ২.৩.২ ব্যবহার করে ওখটিপি (এবং ওকিও) লাইব্রেরি অন্তর্ভুক্ত করার জন্য এটি বাধ্যতামূলক। আপনি কি গ্রহন বা অ্যান্ড্রয়েড স্টুডিও ব্যবহার করছেন?
হাকিম

আমি ইন্টেলিজ ব্যবহার করছি। আমি আমার গ্রেডের উপর নির্ভরশীলতা দেখেছি, আমি ওখট্টিপি দেখিনি ... পিকাসো এটি ছাড়া কাজ করছে বলে মনে হচ্ছে
psv

@psv আপনি চিহ্নিতকারীদের সাথে নীচের সমাধানটি কীভাবে কার্যকর করেছিলেন?
মোস্তফা গেভেন

উত্তর:


247

অন্যান্য উত্তরদাতাদের দ্বারা উল্লিখিত (@ লুকাস এবং @ ম্রাদজিনস্কি), পিকাসো কেবলমাত্র Targetবস্তুর দুর্বল রেফারেন্স রাখে । আপনি যখন Targetআপনার ক্লাসগুলির মধ্যে একটিতে একটি শক্তিশালী রেফারেন্স সঞ্চয় করতে পারেন , তবে সমস্যাগুলি হতে পারে যদি Targetরেফারেন্সগুলি কোনওভাবেই হয় তবে Viewযেহেতু আপনি কার্যকরভাবে সেই বিষয়ে দৃ strong় রেফারেন্সও রাখবেন View(যা পিকাসোর অন্যতম বিষয় স্পষ্টভাবে আপনাকে এড়াতে সহায়তা করে)।

আপনি এই অবস্থায় হন, আমি ট্যাগিং বলতে চাই Targetথেকে View:

final ImageView imageView = ... // The view Picasso is loading an image into
final Target target = new Target{...};
imageView.setTag(target);

এই পদ্ধতির আপনার পক্ষে পিকাসোকে সমস্ত কিছু পরিচালনা করার সুযোগ রয়েছে। এটি WeakReferenceআপনার প্রতিটি দর্শনের জন্য অবজেক্টগুলিকে পরিচালনা করবে - যত তাড়াতাড়ি কারওর প্রয়োজন নেই, Targetছবিটির প্রসেসিংয়ের যে কোনও প্রকারটিও প্রকাশ করা হবে, যাতে আপনি দীর্ঘস্থায়ী টার্গেটের কারণে মেমরি ফাঁসের সাথে আটকে থাকেন না, তবে আপনার লক্ষ্য স্থায়ী হবে যতক্ষণ না এর দৃষ্টিভঙ্গি জীবিত থাকবে


15
আমার দিন বাঁচিয়েছে ধন্যবাদ।
cy198706

24
আমার কাছে কোনও চিত্রের ভিউ নেই, আমি কীভাবে এই সমস্যার সমাধান করব? এই ধরণের পরিস্থিতিতে পরিস্থিতি মোকাবেলা করার সময়, জিসি হ'ল আপনার আরও খারাপ শত্রু
টিম 687

3
আপনি এটি একটি অ্যারেলিস্ট <টার্গেট> এও সঞ্চয় করতে পারেন এবং এটি কাজ করবে, কেবল এই অ্যারেলিস্টটি পরিষ্কার করতে ভুলবেন না :-)
অলিভার ডিকসন

2
অনবিটম্যাপলয়েড এবং বিটম্যাপফেইলেডে, আমি বিটম্যাপটি প্রক্রিয়া করার পরেও চিত্রভিউ.সেটট্যাগ (নাল) করছি। এটির কি দরকার নেই?
জাগুয়ার

1
ধন্যবাদ!
সবেমাত্র

55

পিকাসো টার্গেট অবজেক্টের দৃ strong় উল্লেখ রাখে না, সুতরাং এটি আবর্জনা সংগ্রহ করা হয় এবং onBitmapLoadedবলা হয় না called

সমাধানটি বেশ সহজ, কেবল একটি শক্তিশালী রেফারেন্স করুন Target

public class MyClass {
   private Target mTarget = new Target() {...};

   public void getPointMarkerFromUrl(final String url, final OnBitmapDescriptorRetrievedListener listener) {

         Picasso.with(context)
         .load(url)
         .resize(maxSize, maxSize)
         .into(mTarget);
   }
}      

2
বা আপনার Viewবাস্তবায়ন করুন Target
dnkoutso

দস্তাবেজগুলিতে এটি বলে যে আপনাকে ওভাররাইড করতে হবে Object.equals(Object)এবং Object.hashCode()পদ্ধতিগুলি। আপনার কি কাজের নমুনা আছে?
চিপ

এটা কোথায় লেখা আছে? এমনকি আমার টার্গেটের () উল্লেখের বিষয়ে দৃ strong় উল্লেখ করে আমার এখনও সমস্যা রয়েছে।
PSv

আমি এখন ওকে এইচটিটিপি ইনস্টল করেছি, এটি লোড করা কিছুটা দ্রুত তবে প্রথম প্রবর্তনে আমার এখনও একই সমস্যা রয়েছে। কোন ধারনা ?
PSv

@ পিএসভি: আপনি পিকাসোর প্রথম প্রবর্তন সমস্যাটি সমাধান করতে পেরেছিলেন? আমি একই সমস্যা আছে? আপনি যদি সমাধান করে থাকেন তবে কীভাবে সমাধান করলেন?
TheDevMan

25

আমার যদি চিত্রকল্প থাকে তবে আমি এগুলি সহজভাবে তৈরি করতে পারি: চিত্রভিউ.সেটট্যাগ (লক্ষ্য);

আমি বিটম্যাপগুলি বিজ্ঞপ্তিতে লোড করার জন্য পরবর্তী সমাধান ব্যবহার করি, সুতরাং আমার কেবল বিটম্যাপ দরকার।

সুতরাং সেট ডাইনি তৈরি করুন লক্ষ্য বস্তুগুলি সংরক্ষণ করবে এবং ফিনিস লোডিংয়ের পরে সেগুলি সরিয়ে ফেলবে।

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

private void loadBitmap(String url) {
   Target bitmapTarget = new BitmapTarget(nEvent);
   protectedFromGarbageCollectorTargets.add(bitmapTarget);
   Picasso.with(context).load(url).into(bitmapTarget);
}

class BitmapTarget implements Target {

        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) {

                    //handle bitmap
                    protectedFromGarbageCollectorTargets.remove(this);
                }
            }
        }

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

        @Override
        public void onPrepareLoad(Drawable drawable) {

        }
    }

13
ImageView profile = new ImageView(context);
        Picasso.with(context).load(URL).into(profile, new Callback() {
            @Override
            public void onSuccess() {
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {//You will get your bitmap here

                        Bitmap innerBitmap = ((BitmapDrawable) profile.getDrawable()).getBitmap();
                    }
                }, 100);
            }

            @Override
            public void onError() {

            }
        });

1
এটি আমার সমস্যাও সমাধান করেছে। আমি এটি বিজ্ঞপ্তি সহ ব্যবহার করতে চেয়েছিলাম। কখনও কখনও চিত্র লক্ষ্য সহ ডাউনলোড হয় এবং কখনও কখনও না। তবে
ইমেজভিউ

1
আমার ক্ষেত্রে, সব বাদে, এটিই ছিল সেরা সমাধান!
নূর হোসেন

4

যারা ভিউ ব্যবহার করছেন না তাদের জন্য এখানে সমাধান। এই সহায়ক পদ্ধতিটি কোনও ফলাফল না আসা অবধি অস্থায়ীভাবে লক্ষ্য অবজেক্টটি সঞ্চয় করতে একটি তালিকা ব্যবহার করে যাতে এটি জিসিড না হয়:

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

public void downloadBitmap(final Context context, final String url, final MyCallback callback) {
    Target target = new Target() {

        @Override
        public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
            targets.clear();
            callback.onSuccess(bitmap);
        }

        @Override
        public void onBitmapFailed(Exception e, Drawable errorDrawable) {
            targets.clear();
            callback.onFailure(null);
        }

        @Override
        public void onPrepareLoad(Drawable placeHolderDrawable) {
        }
    };
    targets.add(target);
    Picasso.with(context).load(url).into(target);
}

3

@ লিউকাস বলেছেন (এবং উদ্ধৃত করে), পিকাসো টার্গেট অবজেক্টের একটি শক্ত রেফারেন্স রাখে না। আবর্জনা সংগ্রহ এড়াতে আপনার অবশ্যই অবজেক্টের একটি শক্তিশালী রেফারেন্স রাখা উচিত।

আনার () পদ্ধতি সম্পর্কে। ডকুমেন্টেশনে এটি খুব পরিষ্কার যে আনতে () কোনও চিত্র ভিউ বা টার্গেটের সাথে ব্যবহার করা হবে না, এটি কেবল ক্যাশে আপকে "উষ্ণ" করা এবং অন্য কিছুই নয়, সুতরাং আপনি যেভাবে এটি ব্যবহার করতে সক্ষম হবেন না চাই।

আমি আপনাকে @ লিউকাস ব্যাখ্যা করার মতো দৃ strong় রেফারেন্স রাখার পরামর্শ দিচ্ছি, এটি কাজ করা উচিত। যদি না হয় তবে প্রকল্পের গিটহাব পৃষ্ঠায় একটি নতুন সমস্যা খুলুন।


3

আমি অনুরূপ সমস্যার মুখোমুখি হয়েছি এবং লক্ষ্যটির রেফারেন্স ধরে রাখা কোনওভাবেই সহায়তা করেনি তাই আমি নিম্নলিখিত কোডটি ব্যবহার করেছি যা বিটম্যাপটি দেয়:


Bitmap bitmap = picasso.with(appContext).load(url).get();

নীচের দিকে -> কোনও কলব্যাক নেই এবং আপনি এই ফাংশনটি মূল থ্রেডে কল করতে পারবেন না, আপনাকে নীচের উদাহরণের মতো একটি ব্যাকগ্রাউন্ড থ্রেডে এই ফাংশনটি চালাতে হবে:


handlerThread = new HandlerThread(HANDLER_THREAD_NAME);
handlerThread.start();

Handler handler = new Handler(handlerThread.getLooper());
handler.post(new Runnable() {
    @Override
    public void run() {
        Bitmap bitmap = null;
        try {
            bitmap = picasso.with(appContext).load(url).get();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bitmap != null) {
                //do whatever you wanna do with the picture.
                //for me it was using my own cache
                imageCaching.cacheImage(imageId, bitmap);
            }
        }
    }
});

পুরোপুরি আরও ভাল কাজ করে এমন আরেকটি জিনিস হ'ল গ্লাইড ব্যবহার করা using

আমার প্রকল্পের উদ্দেশ্যটি ছিল ইমেজ গ্যালারী দেখানোর জন্য 2 টি পৃথক চিত্র ডাউনলোড করে এপিআই ব্যবহার করা এবং ব্যবহারকারীকে কোন এপিআই ব্যবহার করতে হবে তা চয়ন করার ক্ষমতা দেওয়ার জন্য আমার উভয়টিকেই ব্যবহার করা দরকার।

আমার বলতে হবে, ফলাফলগুলি দেখে আমি অবাক হয়ে গিয়েছিলাম, গ্লাইডের এপিআই প্রতিটি ক্ষেত্রে নির্বিঘ্নে কাজ করেছিলেন (গ্লাইডের টার্গেটের দুর্বল রেফারেন্স নেই) উইল পিকাসো আমাকে নরক দিয়েছে (এটি আমার প্রথমবার ছিল গ্লাইড ব্যবহার করে, আমি সাধারণত এতদিন পিকাসো ব্যবহার করেছি, আজকের মতো মনে হচ্ছে এটি পরিবর্তন হবে ^^)।


0

আমি একই সমস্যার মুখোমুখি হয়েছি কিন্তু যখন আমি উল্লিখিত হিসাবে নির্ভরতা পরিবর্তন করি তখন এটি এখন সঠিকভাবে কাজ করে।

 implementation 'com.squareup.picasso:picasso:2.5.2'
 implementation 'com.squareup.okhttp:okhttp:2.3.0'
 implementation 'com.squareup.okhttp:okhttp-urlconnection:2.3.0'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.