我在 Play 商店 (Google Play) 上发布了一个应用程序。几个月来,我的控制台一直收到错误。首先,这是我的应用程序中的相关代码:
主要活动
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//more code
//get storage directories
rutasTemp = getStorageDirectoriesWithoutNull(this);
int indexTemp = 0;
for (String s : rutasTemp) {
if (!(s.contains("usb"))) {
indexTemp++;
}
}
if (externalMemoryAvailable(this)) {
rutas = new String[indexTemp];
indexTemp = 0;
for (String s : rutasTemp) {
if (!(s.contains("usb"))) {
rutas[indexTemp] = s;
indexTemp++;
}
}
for (int i=0; i<rutas.length; i++) {
if (rutas[i].contains("emulated")) {
String temp = rutas[0];
rutas[0] = rutas[i];
rutas[i] = temp;
}
}
} else {
rutas = new String[1];
rutas[0] = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/";
}
//more code
carpetasPreferences = getSharedPreferences(SHARED_CARPETAS, Context.MODE_PRIVATE);
}
private void prepararPlayer(int desdeDonde) {
//more code
Map<String, ?> carpetasMap = carpetasPreferences.getAll();
String[] carpetasArray = null;
carpetasArray = new String[carpetasMap.size()];
int indice = 0;
for (Map.Entry<String, ?> asno: carpetasMap.entrySet()) {
carpetasArray[indice] = asno.getValue().toString() + "/";
indice++;
}
if (carpetasMap.size() == 0) {
if (notClickedOnce) {
carpetasArray = new String[rutas.length];
//button pressed first time
carpetasArray[0] = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/Music/";
if (rutas.length > 1) {
carpetasArray[1] = rutas[1];
}
}
}
if (desdeDonde == 0) {
if (sharedPreferences.contains(LIST_OF_FILES)) {
nombresArchivo = sharedPreferences.getStringSet(LIST_OF_FILES, new HashSet<String>());
} else {
buscarArchivos = new BuscarArchivos(this, carpetasArray, nombresArchivo, desdeDonde);
buscarArchivos.execute();
}
} else {
buscarArchivos = new BuscarArchivos(this, carpetasArray, nombresArchivo, desdeDonde);
buscarArchivos.execute();
}
//more code
}
private static class BuscarArchivos extends AsyncTask<Void, Void, String> {
WeakReference<MainActivity> activityReference;
String[] carpetasArray;
Set<String> nombArch;
int desdeDonde;
BuscarArchivos(MainActivity activity, String[] carpetasArray, Set<String> nombresArchivo,
int desdeDonde) {
this.activityReference = new WeakReference<>(activity);
this.carpetasArray = carpetasArray;
this.nombArch = nombresArchivo;
this.desdeDonde = desdeDonde;
}
@Override
protected String doInBackground(Void... voids) {
try {
for (String asn : carpetasArray) {
activityReference.get().listAllFiles(asn, nombArch);
}
activityReference.get().sharedPreferencesEditor
.putStringSet(activityReference.get()
.LIST_OF_FILES, nombArch);
activityReference.get().sharedPreferencesEditor.apply();
} catch (Exception e) {
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
return writer.toString();
}
return "final";
}
//rest of the code of BuscarArchivos
}
public void listAllFiles(String rutaAdentro, Set<String> archivos) {
File file = new File(rutaAdentro);
File[] files = file.listFiles();
if (files != null) {
for (File asno : files) {
if (asno.isFile()) {
archivos.add(asno.getName());
} else if (asno.isDirectory()) {
listAllFiles(asno.getAbsolutePath(), archivos);
}
}
}
}
private String[] getStorageDirectoriesWithoutNull(Context context) {
String[] allDirectories = StorageUtil
.getStorageDirectories(context);
ArrayList<String> directoriesList = new ArrayList<>();
for (String directory : allDirectories) {
if (directory != null) {
directoriesList.add(directory);
}
}
return directoriesList.toArray(new String[0]);
}
我在 getStorageDirectoriesWithoutNull
方法中使用 hendrawd 的 StorageUtil 库 (
https://github.com/hendrawd/StorageUtil)。
以下是活动中使用的适配器,其中选择音乐文件夹:
适配器
public Adaptador(Context contextInside, int layoutIdInside, ArrayList<HashMap<String,
String>> listaInside, String rutaInside) {
//more code
carpetasPreferences = getContext().getSharedPreferences(SHARED_CARPETAS, Context.MODE_PRIVATE);
carpetasPreferencesEditor = carpetasPreferences.edit();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//more code
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
carpetasPreferencesEditor.putString(elemento.get(PATH), elemento.get(PATH));
carpetasPreferencesEditor.apply();
} else {
if (carpetasPreferences.contains(elemento.get(PATH))) {
carpetasPreferencesEditor.remove(elemento.get(PATH));
carpetasPreferencesEditor.apply();
}
}
if (carpetasPreferences.contains(ruta)) {
carpetasPreferencesEditor.remove(ruta);
carpetasPreferencesEditor.apply();
}
}
});
//rest of the code
}
我希望我已经包含了所有相关代码。如果我忘记了什么,请告诉我,我将不胜感激。
我的 Google Play 控制台出现以下错误:
java.lang.NullPointerException
at java.io.File.<init>(File.java:283)
at gym.timer.app.MainActivity.listAllFiles(MainActivity.java:3093)
at gym.timer.app.MainActivity$BuscarArchivos.doInBackground(MainActivity.java:3133)
at gym.timer.app.MainActivity$BuscarArchivos.doInBackground(MainActivity.java:3118)
at android.os.AsyncTask$3.call(AsyncTask.java:394)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
如您所见,我在以下行中遇到了 NullPointerException:
File[] files = file.listFiles();
。
该应用程序在几乎所有设备上运行良好,但我在少数设备上遇到错误,特别是/仅在三星 A 系列设备上。下面我列出了设备的型号:
错误 SM-A217M sdk 31
错误 SM-A127M sdk 30
错误 SM-A305G sdk 30
错误 SM-A505G sdk 30
错误 SM-A307G sdk 30
错误 SM-A505G sdk 30
错误 SM-A105M sdk 30
错误 SM-A307G sdk 29
错误 SM-A305G sdk 30
错误 SM-A217F sdk 30
错误 SM-A127M sdk 33
我希望有人能帮助我。谢谢你。
我买了一部智能手机,特别是“SM-A307G”,它是出现错误的型号之一,只是为了能够重现该错误。我格式化了它,安装了应用程序,但没有出现错误;它工作正常。我想要的是重现错误,但没有出现错误。
使用
null
调用时,文件一参数构造函数会抛出 NPE
public File(String pathname) {
if (pathname == null) {
// your initial error
throw new NullPointerException();
}
this.path = fs.normalize(pathname);
this.prefixLength = fs.prefixLength(this.path);
}
错误堆栈跟踪未显示任何递归调用,因此错误来自对函数的初始调用
for (String asn : carpetasArray) {
activityReference.get().listAllFiles(asn, nombArch);
}
因此,您的
null
中可能有一个
carpetasArray
值
恕我直言,以下代码可以在该数组中生成
null
值
if (notClickedOnce) {
// possible null values here if rutas.length > 2, since you dont set carpetasArray indices higher than 1
carpetasArray = new String[rutas.length];
//button pressed first time
carpetasArray[0] = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Music/";
if (rutas.length > 1) {
// possible null value here if rutas[1] is null
carpetasArray[1] = rutas[1];
}
}
由于我们不知道
rutas
从哪里来,我的猜测是寻找上述可能性。listAllFiles
函数以添加类似 的内容
public void listAllFiles(String rutaAdentro, Set<String> archivos) {
if (rutaAdentro != null) {
// only run the function if rutaAdentro is not null to avoid NPE on new File(null)
File file = new File(rutaAdentro);
File[] files = file.listFiles();
if (files != null) {
for (File asno : files) {
if (asno.isFile()) {
archivos.add(asno.getName());
} else if (asno.isDirectory()) {
listAllFiles(asno.getAbsolutePath(), archivos);
}
}
}
}
}
这样做,你就不应该再有NPE了。