简体   繁体   中英

File for loop causing force close on Nexus 7, not SGS2?

When my app runs on my S2, it works perfectly with absolutely no errors, however when I try and run it on my Nexus 7 it force closes and I have no idea why it's happening on one device and not on another...

Here is the LogCat:

07-03 18:33:29.139: E/AndroidRuntime(11990): FATAL EXCEPTION: main
07-03 18:33:29.139: E/AndroidRuntime(11990): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.liamw.root.logeraser/com.liamw.root.logeraser.MainActivity}: java.lang.NullPointerException
07-03 18:33:29.139: E/AndroidRuntime(11990):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2312)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2362)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at android.app.ActivityThread.access$600(ActivityThread.java:156)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1250)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at android.os.Handler.dispatchMessage(Handler.java:99)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at android.os.Looper.loop(Looper.java:137)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at android.app.ActivityThread.main(ActivityThread.java:5229)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at java.lang.reflect.Method.invokeNative(Native Method)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at java.lang.reflect.Method.invoke(Method.java:525)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:799)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at dalvik.system.NativeStart.main(Native Method)
07-03 18:33:29.139: E/AndroidRuntime(11990): Caused by: java.lang.NullPointerException
07-03 18:33:29.139: E/AndroidRuntime(11990):    at com.liamw.root.logeraser.FolderTools.folderSize(FolderTools.java:96)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at com.liamw.root.logeraser.FolderTools.folderSize(FolderTools.java:87)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at com.liamw.root.logeraser.MainActivity.initialize(MainActivity.java:194)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at com.liamw.root.logeraser.MainActivity.onCreate(MainActivity.java:131)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at android.app.Activity.performCreate(Activity.java:5167)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
07-03 18:33:29.139: E/AndroidRuntime(11990):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2266)
07-03 18:33:29.139: E/AndroidRuntime(11990):    ... 11 more

The 2 foldersize functions are:

public long folderSize() {
        long length = 0;

        for (File file : directory.listFiles()) {
            if (file.isFile())
                length += file.length();
            else if (file != null)
                length += folderSize(file);
        }

        return length;
    }

and

public long folderSize(File directory) {
        long length = 0;

        for (File file : directory.listFiles()) {
            if (file.isFile())
                length += file.length();
            else if (file != null)
                length += folderSize(file);
        }

        return length;
    }

Line 96:

for (File file : directory.listFiles()) { 

(second function)

Line 87:

length += folderSize(file);

(first function)

I don't understand why this only happens on the one device though!

EDIT1:

Directory declaration:

directory = new File("/data/log");

(It's already defined as a global variable)

The directory doesn't exist on your Nexus 7 and so directory.listFiles() returns null and therefore the iterator throws an NPE.

Here's what the javadoc for File.listFiles() says:

 An array of abstract pathnames denoting the files and directories in the directory denoted by this abstract pathname. The array will be empty if the directory is empty. Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs. 

A simple exists() would do the job but it won't cover the case where you don't have access to the directory, which will return Null as well. So best just check for listFiles() returning null and while doing that you consolidate your two methods into one:

public long folderSize(File directory) {
    long length = 0;
    File[] files = directory.listFiles();
    if (files != null) {
        for (File file : files) {
            length += file.isFile() ? file.length() : folderSize(file);
        }
    }
    return length;
}

Now you just call this passing the directory along:

long size = folderSize(directory);

Also make sure you have the android.permission.READ_EXTERNAL_STORAGE permission defined in your manifest.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM