Vô hiệu hóa bộ nhớ cache trong Picasso


76

Ví dụ: tôi tải hình ảnh từ đĩa bằng Picasso , Picasso.with(ctx).load(new File("/path/to/image")).into(imageView)nhưng bất cứ khi nào tôi lưu hình ảnh mới trong tệp đó và làm mới ImageView, Picasso vẫn có bitmap được lưu trong bộ nhớ cache.

Có thể làm mất hiệu lực bộ nhớ cache trong Picasso không?


1
sau khi Picasso.with(getActivity()).invalidate(file);làm thế nào tôi có thể lưu vào bộ nhớ cache lại?
tux-world

Câu trả lời:


86

Trong các phiên bản gần đây của Picasso, có một phương pháp mới để vô hiệu hóa mà không có bất kỳ cách giải quyết nào, vì vậy tôi nghĩ rằng lớp PicassoTools tùy chỉnh được đề cập trước đó, hiện đã lỗi thời trong trường hợp này

Picasso.with(getActivity()).invalidate(file);

3
Chà, điều đó làm mất hiệu lực của một tập tin. Vẫn không có phương pháp nào để làm mất hiệu lực của tất cả bộ nhớ cache. Dù sao, tôi đã trả lời điều đó gần một năm trước, vì vậy tôi không ngạc nhiên khi họ đã thêm nó kể từ đó.
shalafi

Đúng, nó làm mất hiệu lực một tệp duy nhất, như tác giả muốn, không cần phải xóa toàn bộ bộ nhớ cache, nó không hiệu quả. Bạn đã thử tự mình thực hiện nó trong Picasso một năm trước chưa?
mes

Đảm bảo rằng bạn đang sử dụng phiên bản Picasso mới nhất nếu không phiên bản này IllegalStateExceptioncó thể bị vứt bỏ. github.com/square/picasso/commit/…
Jared Rummler

8
vô hiệu không hoạt động, hình ảnh vẫn còn trong bộ nhớ cache đĩa
user5155835

8
Bạn cần phải tải hình ảnh với Picasso.with(imageView.getContext()).load(imageUrl).networkPolicy(NetworkPolicy.NO_CACHE).into(imageView);như vô hiệu () không xóa bộ nhớ cache mạng
Joe Maher

82

Trên thực tế, dựa trên câu trả lời của riêng bạn, có một cách dễ dàng hơn để làm điều đó mà không cần đến thư viện. Thêm lớp này vào gói com.squareup.picasso.

package com.squareup.picasso;

public class PicassoTools {

    public static void clearCache (Picasso p) {
        p.cache.clear();
    }
}

Vì bộ nhớ cache có khả năng hiển thị gói, lớp sử dụng này có thể xóa bộ nhớ cache cho bạn. Bạn chỉ cần gọi nó là:

PicassoTools.clearCache(Picasso.with(context));

21
Bạn không cần phải truy cập vào bình. bạn phải tạo tệp này và đặt nó vào đúng gói (com.squareup.picasso)
shalafi

4
Có cách nào để thực hiện việc này nếu bạn đang sử dụng Gradle với Android Studio thay vì tệp jar của tiện ích bổ sung không?
TheLet MobileMaster,

3
Không, bạn không cần phải chạm vào lọ Picasso, bạn chỉ cần tạo tệp trong gói phù hợp.
shalafi,

7
Đó là một điều đáng tiếc, điều Picasso.with(getApplication()).cache.clear();đó không hoạt động. Nó sẽ sạch hơn nhiều.
Michael Schmidt

3
Trường Picasso.cache không hiển thị !!
Iman Marashi

66

Hủy kiểm tra bộ nhớ cache và bộ nhớ cache ổ đĩa bằng cách chỉ ra chính sách bộ nhớ theo cờ: emoryPolicy.NO_CACHE và NetworkPolicy.NO_CACHE như đoạn mã dưới đây:

   mPicasso.with(mContext)
            .load(url)
            .memoryPolicy(MemoryPolicy.NO_CACHE )
            .networkPolicy(NetworkPolicy.NO_CACHE)
            .resize(512, 512)
            .error(R.drawable.login)
            .noFade()
            .into(imageView);

1
Cảm ơn! Thêm .networkPolicy (NetworkPolicy.NO_CACHE) phù hợp với tôi.
Có thể Uludağ

1
Bởi câu trả lời này hình ảnh không bao giờ được lưu vào bộ nhớ đệm! vậy tại sao lại sử dụng nó?
Iman Marashi

9
@ImanMarashi rất hữu ích nếu bạn thường làm việc với cùng một url và giá trị hình ảnh khác nhau (Ví dụ: amazonws.com/yourProject/user_profile_images/user1/profile.jpg. Url không bao giờ thay đổi, nhưng giá trị của nó thì có.
Borja

14

Thử sử dụng:

Picasso.with(ctx).load(new File("/path/to/image")).skipMemoryCache().into(imageView)

Điều này hoạt động, tuy nhiên tôi muốn hình ảnh lưu trữ hình ảnh vào bộ nhớ cache, chỉ không đọc từ nó nếu chúng tôi biết hình ảnh đã cũ! Tôi phát hiện ra rằng không thể làm điều đó ở Picasso, vì vậy tôi sẽ đánh dấu câu trả lời của bạn là đúng.
Maarten

Tôi muốn làm mới bằng cách nào đó một hình ảnh đã được tải trước đó. bỏ quaMemoryCache () đã thực hiện thủ thuật! Cảm ơn!
russellhoff

Tính năng này hiện không được dùng nữa
Rob

12

Những gì bạn có thể làm nếu muốn xóa tất cả bộ nhớ cache cùng một lúc, là tạo một tùy chỉnh Picasso.LruCache, sau đó sử dụngclear phương pháp trên đó.

Đây là một mẫu:

Picasso.Builder builder = new Picasso.Builder(this);
LruCache picassoCache = new LruCache(this);
builder.memoryCache(picassoCache);
Picasso.setSingletonInstance(builder.build());

Để xóa bộ nhớ cache:

picassoCache.clear();

Lời nhắc tương tự từ Picasso lib: github.com/square/picasso/issues/935
vmeyer

12

Thứ tự tìm kiếm hình ảnh trong Picasso là: Bộ nhớ đệm -> Bộ đệm đĩa -> Mạng

Vì vậy, có một số trường hợp chúng ta cần làm mất hiệu lực bộ nhớ cache trong Picasso:

1. xác thực bộ nhớ đệm bộ nhớ:

  • Chữ thường: Khi hình ảnh đã được cập nhật trong bộ đệm đĩa hoặc máy chủ từ xa
  • Giải pháp: Xóa cache của Url, File, Uri nếu tồn tại

    mPicasso.with(appContext).invalidate(File);
    mPicasso.with(appContext).invalidate(Url);
    mPicasso.with(appContext).invalidate(Uri);
    

.

2. xác thực bộ nhớ cache và bộ nhớ cache ổ đĩa trực tuyến

※ lưu ý: Cập nhật nghĩa trực tuyến trực tiếp lên ImageView

  • Trường hợp người dùng: Hình ảnh được cập nhật trên máy chủ từ xa

  • Giải pháp: Hủy bỏ hình ảnh trên bộ nhớ cache và bộ nhớ cache ổ đĩa, sau đó yêu cầu hình ảnh trên máy chủ từ xa

    mPicasso.with(appContext)
        .load(url)
        .memoryPolicy(MemoryPolicy.NO_CACHE )
        .networkPolicy(NetworkPolicy.NO_CACHE)
        .into(imageView);
    

    -> Hủy bộ nhớ đệm và bộ đệm đĩa

.

3. xác thực bộ nhớ cache và bộ nhớ cache ổ đĩa Ngoại tuyến

※ lưu ý: Cập nhật ngoại tuyến nghĩa là không cập nhật lên ImageView, chỉ tìm nạp nền để sử dụng sau

  • Trường hợp người dùng: Bạn biết hình ảnh trên máy chủ từ xa được cập nhật, nhưng chỉ muốn cập nhật bộ nhớ cache chỉ để sử dụng sau đó (không cập nhật vào chế độ xem hình ảnh)
  • Giải pháp: chỉ tìm nạp

     mPicasso.with(appContext)
        .load(url)
        .memoryPolicy(MemoryPolicy.NO_CACHE)
        .networkPolicy(NetworkPolicy.NO_CACHE)
        .fetch();
    

※ Lưu ý: Sử dụng fetch () là tốt nhưng nó cũng tiêu tốn tài nguyên mạng, vì vậy hãy cân nhắc kỹ, kiểm tra kịch bản 4 bên dưới để có giải pháp tốt hơn

4. xác thực bộ nhớ đệm và bộ nhớ đệm đĩa Ngoại tuyến nếu bộ nhớ đệm đĩa tồn tại

  • Trường hợp người dùng: Chỉ vô hiệu hóa bộ đệm nếu đã tồn tại trong bộ đệm đĩa
  • Giải pháp: Nên kiểm tra đĩa bằng cách sử dụng tham số: NetworkPolicy.OFFLINE cache trước khi tìm nạp

     mPicasso.with(appContext)
        .load(url)
        .memoryPolicy(MemoryPolicy.NO_CACHE)
        .networkPolicy(NetworkPolicy.OFFLINE)
        .fetch(new Callback() {
            @Override
            public void onSuccess() {
                //Success: mean disk cache exist -> should do actual fetch
                picasso.load(url).fetch();
            }
    
            @Override
            public void onError() {
            //Failed: mean disk cache not exist
        }
    });
    

Picasso là một libs tuyệt vời, tôi hy vọng Squareup sẽ thêm nhiều API tiện lợi hơn để quản lý bộ nhớ cache trong tương lai sắp tới.


11

Một tùy chọn khác là xóa chính thư mục bộ nhớ cache, chẳng hạn như khi khởi động ứng dụng:

deleteDirectoryTree(context.getCacheDir());

Ở đâu:

/**
 * Deletes a directory tree recursively.
 */
public static void deleteDirectoryTree(File fileOrDirectory) {
    if (fileOrDirectory.isDirectory()) {
        for (File child : fileOrDirectory.listFiles()) {
            deleteDirectoryTree(child);
        }
    }

    fileOrDirectory.delete();
}

Thao tác đó sẽ xóa toàn bộ thư mục bộ nhớ cache, điều này rất tốt nếu bạn muốn mô phỏng lần đầu tiên sử dụng ứng dụng của mình. Nếu bạn chỉ muốn xóa bộ nhớ cache Picasso, hãy thêm "picasso-cache" vào đường dẫn.


@Lawrence Kesteloot bạn có thể giúp tôi câu hỏi này được không? stackoverflow.com/questions/33657619/… . Tôi đã sử dụng phương pháp của bạn rất thành công nhưng hiện tại tôi đang gặp vấn đề. Cảm ơn trước
madsongr

1
Các câu trả lời khác chỉ loại bỏ Memory Cache chứ không phải Disc Cache - điều này cũng xử lý đĩa! :)
Mohit Singh

8

Bạn có thể xóa bộ nhớ cache hình ảnh của picasso bằng cách thiết lập bộ nhớ cache của riêng bạn và xóa nó. Mã này đã được thử nghiệm trên Picasso 2.5.0

private Picasso picasso;
private LruCache picassoLruCache;

picassoLruCache = new LruCache(context);

// Set cache
picasso = new Picasso.Builder(context) //
        .memoryCache(picassoLruCache) //
        .build();

// Clear cache
picassoLruCache.clear();

6

Không lặp lại tốt, nhưng cách tiếp cận này đã khắc phục sự cố của tôi với bộ nhớ cache và Picasso. Chỉ sử dụng điều này khi bạn muốn làm mất hiệu lực bộ nhớ cache cho một URL cụ thể, cách tiếp cận này chậm và có lẽ không phải là cách làm chính xác nhưng hiệu quả đối với tôi.

    String url = "http://www.blablabla.com/Raiders.jpg";
    Picasso.with(this).invalidate(url);
    Picasso.with(this)
            .load(url)
            .networkPolicy(
                    NetworkUtils.isConnected(this) ?
                            NetworkPolicy.NO_CACHE : NetworkPolicy.OFFLINE)
            .resize(200, 200)
            .centerCrop()
            .placeholder(R.mipmap.ic_avatar)
            .error(R.mipmap.ic_avatar)
            .into(imageView);

2

Một phần rất quan trọng bị thiếu trong câu trả lời được chấp nhận ở đây. Tôi đã tìm thấy thủ thuật từ đây: http://blogs.candoerz.com/question/124660/android-image-cache-is-not-clearing-in-picasso.aspx

Chỉ gọi dòng sau, sẽ không xóa bộ nhớ cache của ảnh khi bạn sử dụng các tùy chọn tùy chỉnh như thay đổi kích thước, cắt giữa, v.v. khi hiển thị ảnh gốc.

Picasso.with(getContext()).invalidate(file);

Giải pháp:

Khi hiển thị hình ảnh, hãy sử dụng stableKey()phương pháp.

Picasso.with(getContext()).load(new File(fileUri))
                         .skipMemoryCache()
                         .placeholder(R.drawable.placeholder)
                         .stableKey(fileUri)
                         .into(imageview);

Sau đó, bạn có thể xóa bộ nhớ cache của tệp này sau bằng cách gọi:

Picasso.with(getContext()).invalidate(fileUri);

Hy vọng điều này sẽ giúp ích.


1

Bạn có thể bỏ qua bộ nhớ đệm bằng cách skipMemoryCache()

xem phần sau

        Picasso.with(this)
            .load(IMAGE_URL)
            .skipMemoryCache()
            .placeholder(R.drawable.placeholder)
            .error(R.drawable.no_image)
            .into(mImageViewPicasso);

gradle compile "com.squareup.picasso:picasso:2.4.0"


0

Một tùy chọn khác là lưu hình ảnh mới vào một tệp khác với tệp gốc. Vì bộ nhớ cache bitmap Picasso bị khóa khỏi đường dẫn tệp, việc tải hình ảnh mới từ một tệp khác sẽ dẫn đến lỗi bộ nhớ cache. Điều này cũng có lợi ích phụ là không phải xóa toàn bộ bộ nhớ cache.


0

sử dụng shutdown()thay thế Theo mã nguồn; tắt máy sẽ ngừng chấp nhận yêu cầu khác cũng như xóa tất cả bộ nhớ cache

 /** Stops this instance from accepting further requests. */
  public void shutdown() {
    if (this == singleton) {
      throw new UnsupportedOperationException("Default singleton instance cannot be shutdown.");
    }
    if (shutdown) {
      return;
    }
    cache.clear();
    cleanupThread.shutdown();
    stats.shutdown();
    dispatcher.shutdown();
    for (DeferredRequestCreator deferredRequestCreator : targetToDeferredRequestCreator.values()) {
      deferredRequestCreator.cancel();
    }
    targetToDeferredRequestCreator.clear();
    shutdown = true;
  }

Ngoài ra, bạn không thể tắt cá thể singleton. Vì vậy, bạn cần phải có biến cá thể cho Picasso. Đừng quên khởi động lại phiên bản picasso mỗi khi bạn có shutdown()nó để sử dụng lại nó


0
File f = new File(path, name);
Picasso.with(this).invalidate(Uri.fromFile(f));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.