1

我在使用 Glide 库(带有编译 SDK 26 的 v4.2.0)和 christbanes Photoview库时遇到了一件奇怪的事情。我能够加载、显示一些图像(大小 <300 Kb)并能够使用 Photoview 库执行缩放手势,但不能对所有图像执行缩放手势。尽管图像存在于 /storage/emulated/0/hhp_images/ 位置,但 Glide 仍然会加载一些图像并为其他图像显示此错误。

W/Glide: Load failed for file:///storage/emulated/0/hhp_images/cylhd_chang.jpg with size [1080x1704]
         class com.bumptech.glide.load.engine.GlideException: Failed to load resource
           Cause (1 of 2): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class java.io.InputStream, LOCAL
             Cause (1 of 1): class java.io.FileNotFoundException: /storage/emulated/0/hhp_images/cylhd_chang.jpg (No such file or directory)
           Cause (2 of 2): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class android.os.ParcelFileDescriptor, LOCAL
             Cause (1 of 1): class java.io.FileNotFoundException: No such file or directory
I/Glide: Root cause (1 of 2)
         java.io.FileNotFoundException: /storage/emulated/0/hhp_images/cylhd_chang.jpg (No such file or directory)
             at java.io.FileInputStream.open(Native Method)
             at java.io.FileInputStream.<init>(FileInputStream.java:146)
             at java.io.FileInputStream.<init>(FileInputStream.java:99)
             at android.content.ContentResolver.openInputStream(ContentResolver.java:700)
             at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResourceFromUri(StreamLocalUriFetcher.java:87)
             at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:62)
             at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:17)
             at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:41)
             at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:61)
             at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:293)
             at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:263)
             at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:230)
             at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
             at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
             at java.lang.Thread.run(Thread.java:761)
             at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:386)
I/Glide: Root cause (2 of 2)
         java.io.FileNotFoundException: No such file or directory
             at android.os.Parcel.openFileDescriptor(Native Method)
             at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:283)
             at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:200)
             at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:977)
             at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:905)
             at com.bumptech.glide.load.data.FileDescriptorLocalUriFetcher.loadResource(FileDescriptorLocalUriFetcher.java:22)
             at com.bumptech.glide.load.data.FileDescriptorLocalUriFetcher.loadResource(FileDescriptorLocalUriFetcher.java:14)
             at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:41)
             at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:61)
             at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:293)
             at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:388)
             at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailed(SourceGenerator.java:118)
             at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:46)
             at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:61)
             at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:293)
             at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:263)
             at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:230)
             at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
             at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
             at java.lang.Thread.run(Thread.java:761)
             at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:386)
W/InputEventReceiver: Attempted to finish an input event but the input event receiver has already been disposed.

它无法加载的图像大小是可变的,即在某些情况下它是 150 Kb 或大约 300 Kb。所以我认为这不是由于大尺寸。但我无法弄清楚问题所在。

这是调用 glide 并在 PopupWindow 中加载图像的类的代码 -

public class PhotoFullPopupWindow extends PopupWindow {

    View view;
    Context mContext;
    PhotoView photoView;
    ProgressBar loading;
    ViewGroup parent;
    private static PhotoFullPopupWindow instance = null;


    public PhotoFullPopupWindow(Context ctx, int layout, View v, String imageUrl, Bitmap bitmap) {
        super(((LayoutInflater) ctx.getSystemService(LAYOUT_INFLATER_SERVICE)).inflate( R.layout.popup_photo_full, null)
                , ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);

        if (Build.VERSION.SDK_INT >= 21) {
            setElevation(5.0f);
        }

//        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        this.mContext = ctx;
        this.view = getContentView();
        ImageButton closeButton = (ImageButton) this.view.findViewById(R.id.ib_close);
        setOutsideTouchable(true);

        setFocusable(true);
        // Set a click listener for the popup window close button
        closeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Dismiss the popup window
                dismiss();
            }
        });
        //---------Begin customising this popup--------------------

        photoView = (PhotoView) view.findViewById(R.id.image);
//        loading = (ProgressBar) view.findViewById(R.id.loading);
        photoView.setMaximumScale(6);
        parent = (ViewGroup) photoView.getParent();
        // ImageUtils.setZoomable(imageView);
        //----------------------------
        if (bitmap != null) {
//            loading.setVisibility(View.GONE);
            if (Build.VERSION.SDK_INT >= 16) {
                parent.setBackground(new BitmapDrawable(mContext.getResources(), Constants.fastblur(Bitmap.createScaledBitmap(bitmap, 50, 50, true))));// ));
            } else {
                onPalette(Palette.from(bitmap).generate());

            }
            photoView.setImageBitmap(bitmap);
        } else {
//            loading.setIndeterminate(true);
//            loading.setVisibility(View.VISIBLE);
            GlideApp.with(ctx) .asBitmap()
                    .load(Uri.fromFile(new File(imageUrl)))
//                    .override(600, 200)
                    .error(R.drawable.sample_image)
                    .listener(new RequestListener<Bitmap>() {
                        @Override
                        public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Bitmap> target, boolean isFirstResource) {
//                            loading.setIndeterminate(false);
//                            loading.setBackgroundColor(Color.LTGRAY);
                            Toast.makeText(mContext, "Error: Unable to open image", Toast.LENGTH_SHORT).show();
//                            dismiss();
                            return false;
                        }

                        @Override
                        public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
                            if (Build.VERSION.SDK_INT >= 16) {
//                                parent.setBackground(new BitmapDrawable(mContext.getResources(), Constants.fastblur(Bitmap.createScaledBitmap(resource, 50, 50, true))));// ));
                                parent.setBackgroundColor(Color.BLACK);
                            } else {
                                onPalette(Palette.from(resource).generate());

                            }
                            photoView.setImageBitmap(resource);

//                            loading.setVisibility(View.GONE);
                            return false;
                        }
                    })



                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    .into(photoView);

            showAtLocation(v, Gravity.CENTER, 0, 0);
        }
        //------------------------------

    }

    public void onPalette(Palette palette) {
        if (null != palette) {
            ViewGroup parent = (ViewGroup) photoView.getParent().getParent();
            parent.setBackgroundColor(palette.getDarkVibrantColor(Color.GRAY));
        }
    }
}

我尝试在普通的 ImageView 200dp * 200dp 而不是 Photoview 中加载图像,但仍然出现相同的错误。

已解决- 实际上代码没有问题。设备存在问题 - Moto G4 Plus。当我在其他模拟器上运行该应用程序时,它运行成功。

4

2 回答 2

0

在我的情况下,我得到的网址没有https://(例如,www.google.ru/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png)。

我从日志中看到:

I/Glide: 根本原因 (1 of 3) java.io.FileNotFoundException: /example.com/static/img/brands/hyundai.png (没有这样的文件或目录)

于 2019-03-11T13:24:40.610 回答
0

因为当应用Android版本为6.0时,你必须要求运行时权限READ_EXTERNAL_STORAGE

你可以这样做

 /**
 * permission code
 */
private static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1;

/**
 * requestPermissions and do something
 *
 */
public void requestRead() {
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {

        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
    } else {
        readFile();
    }
}

/**
 * do you want to do
 */
public void readFile() {
    // do something
}

/**
 * onRequestPermissionsResult
 *
 * @param requestCode
 * @param permissions
 * @param grantResults
 */
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

    if (requestCode == MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            readFile();
        } else {
            // Permission Denied
            Toast.makeText(ToolbarActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
        }
        return;
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

或者

你可以试试https://github.com/permissions-dispatcher/PermissionsDispatcher

于 2017-12-23T09:41:17.637 回答