Python中文网

一个关于 编程问题的解答网站.

有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Emulator在调用函数时引发异常(安卓 studio)

我正在安卓 studio上编写一个游戏,它运行得很好,但当我在另一个类中移动一个函数时,它开始崩溃

我这样做是为了让我可以在任何地方都使用它,只使用一次,而不是在我需要使用它的每个类上复制粘贴

我在谷歌上查看了如何解决这个问题,但什么都没用,错误是“getExternalFilesDir”或“openFileOutput”返回空值

这个类有两个函数(基本上做相同的事情),但我不能使用

import 安卓.media.MediaScannerConnection;
import 安卓.util.Log;
import 安卓x.appcompat.app.AppCompatActivity;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class WriteUserData extends AppCompatActivity {
    
    public void writeToFile(String data, String file) {
        try {
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput(file + ".txt", MODE_PRIVATE));
            outputStreamWriter.write(data);
            outputStreamWriter.close();
        }
        catch (IOException e) {
            Log.e("Exception", "File write failed: " + e.toString());
        }
    }

    public void saveFile(String fileName, String addText){
        try {
            // Creates a file in the primary external storage space of the
            // current application.
            // If the file does not exists, it is created.
            File newFile = new File(this.getExternalFilesDir(null), fileName + ".txt");
            if (!newFile.exists())
                newFile.createNewFile();

            // Adds a line to the file
            BufferedWriter writer = new BufferedWriter(new FileWriter(newFile, true /*append*/));
            writer.write(addText);
            writer.close();
            // Refresh the data so it can seen when the device is plugged in a
            // computer. You may have to unplug and replug the device to see the
            // latest changes. This is not necessary if the user should not modify
            // the files.
            MediaScannerConnection.scanFile(this,
                    new String[]{newFile.toString()},
                    null,
                    null);
        } catch (IOException e) {
            Log.e("ReadWriteFile", "Error while trying to add text in " + fileName + ".txt");
        }
    }

}

还有一个地方,我试图调用函数,但却使仿真器崩溃(我删除了一些代码“导入”),因此您更容易理解

    private boolean showStats = true;
    private final static long Interval = 30;
    private Handler handler = new Handler();
    private int flashDisplay = 0;

    @SuppressLint("SetTextI18n")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game_over);

        // change game over screen on click
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        if(showStats){
                            getStats();
                        }
                        flashDisplay++;
                    }
                });
            }
        }, 0, Interval);
    }

    private static void bring(){
        WriteUserData saveScore = new WriteUserData();
        saveScore.saveFile("userdata", "ThisTextWork");
        saveScore.writeToFile("ThisTextWorkToo", "config");
    }

    @SuppressLint("SetTextI18n")
    private void getStats(){
        bring();
    }
}

这就是错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.FileOutputStream 安卓.content.Context.openFileOutput(java.lang.String, int)' on a null object reference Blockquote


共 (1) 个答案

  1. # 1 楼答案

    你误解了活动的运作方式

    public class WriteUserData extends AppCompatActivity {
    

    您正在扩展一个活动类,因此WriteUserData也是一个活动。在这种情况下,应该这样命名-WriteUserDataActivity

    然而,看看你在这里做什么:

    WriteUserData saveScore = new WriteUserData();
    

    这不是你应该如何使用一项活动。它的创建应该有一个意图和startActivity(),请参见此处:

    https://developer.android.com/training/basics/firstapp/starting-activity

    您想要做的是移动在单独类中打开文件的逻辑,以避免代码重复。这很好,但它不应该通过活动来完成。相反,应该使用Utils/Helper类。你的类不应该扩展任何东西,应该有一个私有构造函数:

    public class WriteUserDataUtils { 
        private WriteUserDataUtils() { 
            // utils classes shouldn't be instanced
        }
        ... 
    }
    

    之后,将其内部的方法更改为^{

    public static void writeToFile(String data, String file) {
        ...
    }
    
    public static void saveFile(String fileName, String addText) {
        ...
    }
    

    最后,扩展Activity的原因是某些事情需要Context(例如打开文件流)。通过将其作为参数传递,可以轻松解决此问题:

    public static void writeToFile(String data, String file, Context context) {
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput(file + ".txt", MODE_PRIVATE));
        ...
    }
    
    public static void saveFile(String fileName, String addText, Context context){
        try {
            File newFile = new File(context.getExternalFilesDir(null), fileName + ".txt");
        ...
    }
    

    将其重构为utils类后,可以从活动中调用它,如下所示:

    private static void bring(){
        WriteUserDataUtils.saveFile("userdata", "ThisTextWork", this);
        WriteUserDataUtils.writeToFile("ThisTextWorkToo", "aconfig", this);
    }
    

    如果你需要进一步的澄清,请告诉我