如何事先获取将存储在 Android/Java 缓存中的未来 Glide 图像大小?

Posted

技术标签:

【中文标题】如何事先获取将存储在 Android/Java 缓存中的未来 Glide 图像大小?【英文标题】:How to priorly get future Glide image size which will be stored in cache in Android/Java? 【发布时间】:2020-10-18 18:52:45 【问题描述】:

在 MainActivity 中,我根据 imageview 大小使用 glide 将一些图像加载到 recyclerview 中。

见:

 @Override
    public void onBindViewHolder(PreviewAdapter.MyViewHolder holder, int position) 
        Glide.with(context).load(previewArrayList.get(position).getUrl()).diskCacheStrategy(DiskCacheStrategy.AUTOMATIC).into(holder.postImage);

XML:

<ImageView
    android:id="@+id/post_image"
    android:layout_
    android:layout_marginTop="4dp"
    android:layout_
    android:layout_below="@+id/post_name"
    android:scaleType="centerCrop" />

如你所见,我也使用 Glide 缓存 DiskCacheStrategy.AUTOMATIC 以便下次没有 Internet Glide 时可以显示图像。现在你可以在https://medium.com/@multidots/glide-vs-picasso-930eed42b81d这个帖子中看到“Glide resizes the image as per the dimension of the ImageView.

现在,我想要在 SpalshActivity 中的最终大小,Glide 将存储在缓存中。因此,当 SpalshActivity 之后,当用户第一次打开 MainActivity 没有 Internet Conncetion 时,它应该加载图像。

那怎么可能呢?

在 SpalshActivity 中,我已经在缓存图像,但它又是第一次在 MainActivity 中下载/调整大小。

SpalshActivity:

private void preloadImage(String url) 
        try 

            //File file = Glide.with(this).asFile().load(url).submit().get();
            //String path = file.getPath();


            Glide.with(this)
                    .load(url)
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    .listener(new RequestListener<Drawable>() 
                        @Override
                        public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) 
                            if (isPostDataLoaded) 
                                postImagesLoaded++;
                                if (postImagesLoaded == postImagesCount) 
                                    binding.progressBar.setVisibility(View.GONE);
                                    AlertDialogManager.showAlertDialogMessage(SplashActivity.this, "Error", "Something went wrong, Please try again later", false, "Exit", null, SplashActivity.this, IS_TABLET);
                                
                             else 
                                previewImagesLoaded++;
                                if (previewImagesLoaded == previewImagesCount) 
                                    binding.progressBar.setVisibility(View.GONE);
                                    AlertDialogManager.showAlertDialogMessage(SplashActivity.this, "Error", "Something went wrong, Please try again later", false, "Exit", null, SplashActivity.this, IS_TABLET);
                                
                            
                            return true;
                        

                        @Override
                        public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) 
                            if (isPostDataLoaded) 
                                postImagesLoaded++;
                                if (postImagesLoaded == postImagesCount) 
                                    PostSingleton.getInstance().setPostMap(postMap);
                                    startFreshActivity(PreviewActivity.class);
                                
                             else 
                                previewImagesLoaded++;
                                if (previewImagesLoaded == previewImagesCount) 
                                    PreviewSingleton.getInstance().setPreviewList(previewList);
                                    getPostImageCount();
                                    postPreloadAllImages();
                                
                            
                            return true;
                        
                    ).preload();
         catch (Exception e) 
            e.printStackTrace();
        
    

【问题讨论】:

【参考方案1】:

最好使用.downloadOnly() 预加载所有图像,而不是使用任何target。然后使用FileProvider加载图片。

private class CacheImage extends AsyncTask<String,Void,File> 
        @Override
        protected File doInBackground(String... strings) 
            try 
                return Glide.with(getContext())
                        .load(strings[0])
                        .downloadOnly(Target.SIZE_ORIGINAL,Target.SIZE_ORIGINAL)
                        .get();
             catch (Exception e) 
                Log.e(LOG_TAG,e.getMessage());
                return null;
            
        

        @Override
        protected void onPostExecute(File file) 
            if(file!=null)
               Uri file_uri = FileProvider.getUriForFile(getContext(),
                        getContext().getPackageName()+".images",file);
            
        
    

并将路径与 URL 一起存储在 SQLite 中。 现在使用 SQLite 中的FileProvider 获取image_url

Glide.with(imageView.getContext())
                .load(<image_url>)
                .asBitmap()
                .dontAnimate()
                .centerCrop()
                .override(<width>,<height>)
                .priority(Priority.IMMEDIATE)
                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
                .skipMemoryCache(true)
                .into(imageView);

您可能还需要添加,

在清单中,在 &lt;application&gt; 内部

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="app package name.images"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>

res/xml 内,作为file_paths.xml

<paths xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <cache-path name="images" path="image_manager_disk_cache"
        tools:path="DiskCache.Factory.DEFAULT_DISK_CACHE_DIR" />
</paths>

【讨论】:

非常感谢。我会实现这个。请给点时间 使用 SQLite 将您从 CacheImage 获得的值与基本图像 URL 一起存储在 DB 表中,CacheImageTable(url TEXT UNIQUE, file_path TEXT) 当然。我会这样做的

以上是关于如何事先获取将存储在 Android/Java 缓存中的未来 Glide 图像大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 packageManager 在 android java 中获取克隆的应用程序?

如何在内部存储android java中下载和保存媒体文件

GetWindowTextA - 将指定窗口的标题条文本拷贝到一个缓存区内

如何将鼠标悬停在图像上并通过缓动显示文本块? [复制]

什么是spool系统,什么是预输入,什么是缓输出?

C语言之清空缓存区