列出Android应用程序目录中的文件时出现幻像空指针异常

时间:2013-12-29 08:18:51

标签: java android io

首先,非常感谢花点时间看看我的问题。我会尽量保持简短而清晰。

此活动的最终目标(我的应用程序的主要活动)是读取文件夹中的所有文件并将其列在微调器中,以便用户可以选择要加载的文件。现在我在for循环中遇到空指针异常,我从File []列表中获取文件名。

这是类代码。正如你所看到的那样,我还没有真正进入微调器。

    package ca.sulli.quilxotic;


import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Spinner;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.channels.FileChannel;
import java.util.ArrayList;

public class Launcher extends Activity {

    public static Reader reader;
    public static Book book;

    /* FILE IO */
    public static File sdCard;
    public static File directory;
    public static File[] fileList;
    public static ArrayList<String> fileNameList;

    /* INTERFACE */
    public Spinner bookSpinner;
    public CheckBox debugCheck;
    public Button beginBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /* CUSTOM LAYOUT SETUP */
        this.requestWindowFeature(Window.FEATURE_NO_TITLE); //Remove title bar
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //Remove notification bar

        setContentView(R.layout.launcher);

        bookSpinner = (Spinner)findViewById(R.id.bookSpinner);
        debugCheck = (CheckBox)findViewById(R.id.debugCheck);
        beginBtn = (Button)findViewById(R.id.beginBtn);

        sdCard = Environment.getExternalStorageDirectory();
        directory = new File(sdCard.getAbsolutePath() + "/Quilxotic");

        if(!directory.exists())
            directory.mkdir();

        Log.e(null,"Copying content to SDCard");
        CopyContent();
        Log.e(null,"Done copying content to SDCard");

        fileList = new File(directory.getAbsolutePath()).listFiles();
        int fileCount = new File(directory.getAbsolutePath()).list().length;
        Log.e(null,fileCount + " files found in /Quilxotic...");

        for (File file : fileList){
            fileNameList.add(file.getPath());
            Log.e(null,"Added file: " + file.getPath());
        }

/*
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, fileNameList);

        bookSpinner.setAdapter(adapter);
        bookSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {

            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {

            }
        }); {

        }

*/
}

    private void OpenBook()
    {
        book = new Book();
        reader = new Reader(book);
    }

    private void CopyContent()
    {

        File f = new File(getCacheDir()+"/example.xml");
        if (!f.exists()) try {

            InputStream is = getAssets().open("example.xml");
            int size = is.available();
            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();


            FileOutputStream fos = new FileOutputStream(f);
            fos.write(buffer);
            fos.close();
        } catch (Exception e) { throw new RuntimeException(e); }

        try {
            File sd = Environment.getExternalStorageDirectory();
            File data = Environment.getDataDirectory();

            if (sd.canWrite()) {
                String originPath = "/data/ca.sulli.quilxotic/cache/example.xml";
                String destPath = "Quilxotic/example.xml";
                File currentXML = new File(data, originPath);
                File backupXML = new File(sd, destPath);

                if (currentXML.exists() && !backupXML.exists()) {
                    FileChannel src = new FileInputStream(currentXML).getChannel();
                    FileChannel dst = new FileOutputStream(backupXML).getChannel();
                    dst.transferFrom(src, 0, src.size());
                    src.close();
                    dst.close();
                } else {
                    Log.e(null, "File does not exist: " + currentXML.toString() + "or destination XML exists");
                }
            } else {
                Log.e(null, "SDCard not writable, backup aborted.");
            }
        } catch (Exception ex) {
            Log.e(null, "Error backing up database to sdcard.", ex);
        }
    }


}

由于我无法理解的原因,我在for循环的某个地方遇到空指针异常。如果我注释掉for循环,应用程序会正确加载布局。这是堆栈:

java.lang.RuntimeException: Unable to start activity ComponentInfo{ca.sulli.quilxotic/ca.sulli.quilxotic.Launcher}: java.lang.NullPointerException
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
        at android.app.ActivityThread.access$600(ActivityThread.java:123)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4424)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:825)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:592)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.NullPointerException
        at ca.sulli.quilxotic.Launcher.onCreate(Launcher.java:73)
        at android.app.Activity.performCreate(Activity.java:4465)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1051)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
            at android.app.ActivityThread.access$600(ActivityThread.java:123)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4424)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:825)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:592)
            at dalvik.system.NativeStart.main(Native Method)

为了完成,这是我的清单。我只有两个活动,即用户选择要加载哪个文件的启动器,以及将(最终)解析文件并对其进行操作的阅读器。到目前为止,我可以确定我的其他类没有任何直接错误导致这种情况,但也许我已经将错误设置错误。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="ca.sulli.quilxotic"
    android:versionCode="1"
    android:versionName="1.0" 

    >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/quill"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="ca.sulli.quilxotic.Launcher"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="ca.sulli.quilxotic.Reader"
            android:label="@string/app_name"
            android:parentActivityName="ca.sulli.quilxotic.Launcher">
        </activity>
    </application>

</manifest>

再次感谢任何看过的人。在此期间我会继续摆弄它,但我只是看不出那个for循环或它迭代的文件列表有什么问题。谢谢!

更新:尝试使其符合指南。问题已经解决,但为了完成:

  1. 在提出问题之前,你做过一些研究吗?  我已经通过几个示例和堆栈溢出页面关于从目录创建文件列表。

  2. 您是否解释过您已尝试解决问题的方法?  如上所述,注释掉For循环解决了异常。我也尝试了不同的方法来编写For循环,并确保在此之前的所有变量都包含有效数据。

  3. 您是否指定了您正在使用的语言和平台,包括相关的版本号?  这是Android的minAPI为8.我正在使用Android Studio IDE。

  4. 如果您的计划产生的结果与您的预期不同,您是否说明了您的预期,为什么期望以及实际结果?  它应该创建一个目录中文件的文件名的ArrayList作为字符串。当然它也不应该崩溃。

  5. 您是否仔细阅读了自己的整个问题,以确保它有意义,并且包含足够的信息给没有您已经知道的任何背景的人?  是

1 个答案:

答案 0 :(得分:2)

您需要在访问之前初始化fileNameList

public static ArrayList<String> fileNameList = new ArrayList<>();