调用函数时模拟器抛出异常(android studio)
Posted
技术标签:
【中文标题】调用函数时模拟器抛出异常(android studio)【英文标题】:Emulator throws exception (android studio) when function is called 【发布时间】:2020-08-01 11:50:56 【问题描述】:我正在 android studio 上编写一个游戏,它运行良好,但是当我在另一个类中移动一个函数时它开始崩溃。
我这样做是为了让我可以在任何地方使用它,只需拥有它一次,而不是在我需要使用它的每个类上复制粘贴。
我在谷歌上查看了如何解决这个问题,但没有任何效果,我认为错误是“getExternalFilesDir”或“openFileOutput”返回空值。
这是具有两个功能的类(基本上做同样的事情)但我不能使用。
import android.media.MediaScannerConnection;
import android.util.Log;
import androidx.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");
还有一个地方我尝试调用函数但模拟器崩溃(我删除了一些代码'import'),所以你更容易理解。
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:尝试在空对象引用上调用虚拟方法“java.io.FileOutputStream android.content.Context.openFileOutput(java.lang.String, int)” 块引用
【问题讨论】:
错误是什么? 整个错误都在那里:hasteb.in/pokefeki.sql 你需要这里的错误。不一定是完整的堆栈跟踪,但您的问题必须是自包含的。 完成了,我想这就是你的意思 【参考方案1】:您误解了活动的工作原理。
public class WriteUserData extends AppCompatActivity
您正在扩展一个 Activity 类,因此 WriteUserData
也是一个 Activity。在这种情况下,它应该被命名为 - WriteUserDataActivity
。
但是,看看你在这里做什么:
WriteUserData saveScore = new WriteUserData();
这不是您应该使用活动的方式。它应该使用 Intent 和 startActivity()
创建,请参见此处:
https://developer.android.com/training/basics/firstapp/starting-activity
您想要做的是移动在单独的类中打开文件的逻辑以避免代码重复。这很好,但应该不通过活动来完成。相反,您应该使用 Utils/Helper 类。你的类不应该扩展任何东西,应该有一个私有的构造函数:
public class WriteUserDataUtils
private WriteUserDataUtils()
// utils classes shouldn't be instanced
...
之后,把里面的方法改成static
:
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 类后,您可以像这样从 Activity 中调用它:
private static void bring()
WriteUserDataUtils.saveFile("userdata", "ThisTextWork", this);
WriteUserDataUtils.writeToFile("ThisTextWorkToo", "aconfig", this);
如果您需要任何进一步的说明,请告诉我。
【讨论】:
谢谢,它工作得很好,我想让你知道(或者如果有人有同样的问题)“bring()”不应该是静态的:private void bring() WriteUserDataUtils.saveFile("userdata", "ThisTextWork", this); WriteUserDataUtils.writeToFile("ThisTextWorkToo", "aconfig", this);
以上是关于调用函数时模拟器抛出异常(android studio)的主要内容,如果未能解决你的问题,请参考以下文章
JMockit 期望 API:如何在方法/构造函数调用时抛出异常
使用appium在android浏览器上运行selenium webdriver脚本,在模拟器上启动浏览器但抛出chromedriver异常