【问题标题】:NullPointerException: Attempt to get length of null array with right permissionsNullPointerException:尝试获取具有正确权限的空数组的长度
【发布时间】:2018-04-14 06:29:15
【问题描述】:

我为学校制作了这个应用程序,明天需要提交。小问题,它总是在某个点崩溃。

我的应用从 Firebase 下载一个 .zip 文件并将其解压缩:

-- 缓存目录

 --images
     --image01.jpg
     --image02.jpg
     --image03.jpg
     --and so on...
 --info.txt
 --scan234702640.zip // this is the file that includes the /images and the info.txt

所以我的类 imageHandler 中有以下代码:

// Get the file
    gsReference.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {

            String path = "";
            File f = new File(context.getExternalCacheDir().toURI());
            File[] files1 = f.listFiles();
            for (File inFile1 : files1) {
                if (inFile1.getName().contains("scan")) {
                    path = context.getExternalCacheDir() + "/" +  inFile1.getName();
                }
            }

            //Decompress zip and build bitmap array
            try {
                ZipFile zip = new ZipFile(path);
                zip.extractAll(context.getExternalCacheDir() + "/");
            } catch (ZipException e){
                Toast.makeText(context, "ZIP error " + e.getCode() + " : " + e.getMessage(), Toast.LENGTH_SHORT).show();
            }

            //Construct bitmap array
            ArrayList<Bitmap> pictures = new ArrayList<Bitmap>();
            File f3 = new File(context.getExternalCacheDir().toString() + "/images/");
            if (f3.exists()) {
                File[] files3 = f3.listFiles(); //THE PROBLEM IS SOMEWHERE HERE

                if (files3 != null) {
                    for (File inFile3 : files3) {
                        if (inFile3.exists()) {
                            BitmapFactory.Options options = new BitmapFactory.Options();
                            options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                            Bitmap bitmap = BitmapFactory.decodeFile(inFile3.getPath(), options);
                            pictures.add(bitmap);
                        }
                    }
                }
            }

            // DEBUG: Show what we have in our cache location

            String message = "";
            File f2 = new File(context.getExternalCacheDir().toURI() + "/images");
            File[] files2 = f2.listFiles();
            for (File inFile2 : files2) {
                if (inFile2.isDirectory()) {
                    message += "/" + inFile2.getName() + "\n";
                } else {
                    message += inFile2.getName() + "\n";
                }
            }

            AlertDialog dialog = new AlertDialog.Builder(context)
                    .setTitle("Test Message")
                    .setMessage(message)
                    .show();

            // END OF DEBUG


        }
    });

    return scan;

因此,它在显示“问题出在此处”的部分崩溃。我已经询问了所有 EXTERNAL_STORAGE 权限,并检查了文件是否存在。我发现,在调试模式下,它成功地将位图添加到数组中,但是当我有例如 10 个图像时,它在加载所有 10 个图像后崩溃。 所以请帮助我;)

非常感谢, 朱尔斯

编辑 这是控制台日志:

10-31 00:07:31.060 7536-7536/com.julescitronic.meeting E/AndroidRuntime: FATAL EXCEPTION: main
                                                                     Process: com.julescitronic.meeting, PID: 7536
                                                                     java.lang.NullPointerException: Attempt to get length of null array
                                                                         at com.julescitronic.meeting.imageHandler$2.onSuccess(imageHandler.java:152)
                                                                         at com.julescitronic.meeting.imageHandler$2.onSuccess(imageHandler.java:127)
                                                                         at com.google.firebase.storage.StorageTask$1.zza(Unknown Source:9)
                                                                         at com.google.firebase.storage.StorageTask$1.zzl(Unknown Source:4)
                                                                         at com.google.firebase.storage.zze$2.run(Unknown Source:10)
                                                                         at android.os.Handler.handleCallback(Handler.java:789)
                                                                         at android.os.Handler.dispatchMessage(Handler.java:98)
                                                                         at android.os.Looper.loop(Looper.java:164)
                                                                         at android.app.ActivityThread.main(ActivityThread.java:6541)
                                                                         at java.lang.reflect.Method.invoke(Native Method)
                                                                         at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

【问题讨论】:

  • images / image?
  • 哦,对不起。正确的是图像。我刚才打错了。然而,这甚至不可能是问题。图像可以很好地加载到位图数组中。我只是在它这样做后崩溃了
  • 是的,我看到您也检查了它,但要正确。
  • 如果您发布正在发生的特定错误,可能会更容易诊断。
  • 在您的最后一句话中,您似乎更像是内存问题而不是权限问题。您能否提供更多信息或日志?

标签: java android arrays for-loop nullpointerexception


【解决方案1】:
listFiles();

是一个文件权限,我在 Android API 23 及更高版本的代码中遇到了类似的崩溃(因为在运行时需要文件存储权限),所以我提供了以下相同的内容:

if (Build.VERSION.SDK_INT >= 23) {
            if (AppMain.mContext.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                Log.v(TAG, "Permission is granted");
                return true;
            } else {
                ActivityCompat.requestPermissions(activityContext, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                return false;
            }

在此之后,我在 listFile 操作上没有得到空指针。

【讨论】:

    【解决方案2】:

    我也有同样的问题。使用 this insted 的 Bitmap 加载图片,因为通过 Bitmap 加载图片会占用大量内存并导致您的应用崩溃

    【讨论】:

    • 是的,我已经使用毕加索将我的大部分图像加载到应用程序中。但是这次我不得不使用位图,因为我需要将它存储在包含位图数组的自定义“扫描”项中
    【解决方案3】:

    我发现,在调试模式下,它成功地将位图添加到数组中,但是当我有例如 10 个图像时,它在加载所有 10 个图像后崩溃。

    根据你的最后一句话,我相信你有记忆问题而不是权限问题。

     BitmapFactory.Options options = new BitmapFactory.Options();
     options.inPreferredConfig = Bitmap.Config.ARGB_8888;
     Bitmap bitmap = BitmapFactory.decodeFile(inFile3.getPath(), options);
     pictures.add(bitmap);
    

    使用此代码,您可以加载每个位图的完整大小并将其添加到位图列表中,从而使 GC 无法释放与位图关联的本机对象。如果您加载的图像比方说 10 MB * 10 图像,这可能是一个大问题。这很容易导致内存问题。

    我建议更有效地加载位图。这意味着,您将一个下采样位图加载到内存中并使用该位图,因为如果将一个大小为 3000x4000 的位图显示在大小为 512x384 的 ImageView 上,它是没有意义的。此链接是一个很好的指南,可以提供帮助:

    https://developer.android.com/topic/performance/graphics/load-bitmap.html

    【讨论】:

    • 图片并没有那么大……实际上它们真的很小:大约 20kb
    猜你喜欢
    • 1970-01-01
    • 2015-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    相关资源
    最近更新 更多