gpt4 book ai didi

android - 尝试使用 onSaveInstanceState() 恢复 String[][] 时出现 "java.lang.NullPointerException: Attempt to get length of null array"

转载 作者:行者123 更新时间:2023-11-29 23:17:51 25 4
gpt4 key购买 nike

我试图让 WordSearch 在我点击主页按钮后回到 Activity 和 fragment 时可以恢复(在模式中 - 不保留 Activity ),

点击主页:应该调用onSaveInstance。

再次点击应用:应该回到应用并恢复之前的状态。

但我无法取回 String[][] 字段 this.characterGrid。

有人知道为什么吗?

import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

import com.google.gson.annotations.SerializedName;

import java.util.Arrays;
import java.util.List;

public class WordSearch implements Parcelable {
public static final Parcelable.Creator<WordSearch> CREATOR =
new Parcelable.Creator<WordSearch>() {
public WordSearch createFromParcel(Parcel source) {
return new WordSearch(source);
}

public WordSearch[] newArray(int size) {
return new WordSearch[size];
}
};
public final String word;
public final @SerializedName("character_grid") String[][] characterGrid;
public final @SerializedName("word_locations") List<String> translations;
public final @SerializedName("source_language") String sourceLanguage;
public final @SerializedName("target_language") String targetLanguage;

WordSearch(String sourceLanguage, String targetLanguage, String word,
String[][] characterGrid, List<String> translations) {
this.sourceLanguage = sourceLanguage;
this.targetLanguage = targetLanguage;
this.word = word;
this.characterGrid = characterGrid;
this.translations = translations;
}

private WordSearch(Parcel in) {
this.sourceLanguage = in.readString();
this.targetLanguage = in.readString();
this.word = in.readString();
int size = in.readInt();
Log.d("gzl", "WordSearch characterGrid size = " + size);
this.characterGrid = new String[size][];
Log.d("gzl", "WordSearch characterGrid size = " + size);
for (int i = 0; i < size; i++) {
Log.d("gzl", "WordSearch " + Arrays.toString(this.characterGrid[i]));
in.readStringArray(this.characterGrid[i]);
// if (this.characterGrid[i] != null) {
// in.readStringArray(this.characterGrid[i]);
// }
Log.d("gzl", "WordSearch characterGrid position " + i + " "
+ Arrays.toString(this.characterGrid[i]));
}
this.translations = in.createStringArrayList();
}

@Override public int describeContents() {
return 0;
}

@Override public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.sourceLanguage);
dest.writeString(this.targetLanguage);
dest.writeString(this.word);
dest.writeInt(this.characterGrid.length);
Log.d("gzl", "writeToParcel " + this.characterGrid.length + "");
for (String[] array : this.characterGrid) {
Log.d("gzl", "writeToParcel " + Arrays.toString(array));
dest.writeStringArray(array);
}
dest.writeStringList(this.translations);
Log.d("gzl", "writeToParcel\n");

RuntimeException re = new RuntimeException();
re.fillInStackTrace();
Log.e("gzl", "writeToParcel stackTrace", re);
}
}

fragment :

    @Override
public void onResume() {
super.onResume();
if (wordSearches != null) {
// Log.d("gzl", wordSearches.get(position).toString());
Log.d("gzl", "onResume position = " + position);
Log.d("gzl", "onResume wordSearches = " + wordSearches);
setupWordSearch(wordSearches.get(position), boardView, sourceWord);
}
}

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
if (wordSearches != null) {
outState.putParcelableArrayList(WORD_SEARCHES, wordSearches);
outState.putInt(CURRENT_POSITION, position);
Log.d("gzl", "onSaveInstanceState");
Log.d("gzl", wordSearches.toString());
}
super.onSaveInstanceState(outState);
}

我如何恢复数据:

   @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
position = savedInstanceState.getInt(CURRENT_POSITION);
// wordSearches = savedInstanceState.getParcelableArrayList(WORD_SEARCHES);

wordSearches = savedInstanceState.<WordSearch>getParcelableArrayList(WORD_SEARCHES);
if (wordSearches != null) {
Log.d("gzl", "onCreate " + wordSearches.toString());
} else {
Log.d("gzl", "onCreate " + "wordSearches = null");
}

Log.d("gzl", "onCreate savedInstanceState " + savedInstanceState.toString());

} else {
getWordSearches();
}
}

我得到了以下日志:

2019-03-04 23:42:13.317 25699-25699/com.gongzelong.duolingowordsearch D/gzl: WordSearch characterGrid size = 8
2019-03-04 23:42:16.830 25699-25713/com.gongzelong.duolingowordsearch W/zygote64: Clearing bad or obsolete profile data from file /data/misc/profiles/cur/0/com.gongzelong.duolingowordsearch/primary.prof: Profile EOF reached prematurely for ReadProfileHeader
2019-03-04 23:42:21.947 25699-25699/com.gongzelong.duolingowordsearch D/gzl: WordSearch characterGrid size = 8
2019-03-04 23:42:25.529 25699-25699/com.gongzelong.duolingowordsearch D/gzl: WordSearch null
2019-03-04 23:46:52.471 25699-25699/com.gongzelong.duolingowordsearch D/AndroidRuntime: Shutting down VM
2019-03-04 23:46:52.508 25699-25699/com.gongzelong.duolingowordsearch E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.gongzelong.duolingowordsearch, PID: 25699
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gongzelong.duolingowordsearch/com.gongzelong.duolingowordsearch.MainActivity}: java.lang.NullPointerException: Attempt to get length of null array
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.lang.NullPointerException: Attempt to get length of null array
at android.os.Parcel.readStringArray(Parcel.java:1261)
at com.gongzelong.duolingowordsearch.model.WordSearch.<init>(WordSearch.java:48)
at com.gongzelong.duolingowordsearch.model.WordSearch.<init>(WordSearch.java:12)
at com.gongzelong.duolingowordsearch.model.WordSearch$1.createFromParcel(WordSearch.java:16)
at com.gongzelong.duolingowordsearch.model.WordSearch$1.createFromParcel(WordSearch.java:14)
at android.os.Parcel.readParcelable(Parcel.java:2860)
at android.os.Parcel.readValue(Parcel.java:2754)
at android.os.Parcel.readListInternal(Parcel.java:3184)
at android.os.Parcel.readArrayList(Parcel.java:2384)
at android.os.Parcel.readValue(Parcel.java:2775)
at android.os.Parcel.readArrayMapInternal(Parcel.java:3123)
at android.os.BaseBundle.initializeFromParcelLocked(BaseBundle.java:273)
at android.os.BaseBundle.unparcel(BaseBundle.java:226)
at android.os.Bundle.getSparseParcelableArray(Bundle.java:1009)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1361)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3269)
at android.support.v4.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:3223)
at android.support.v4.app.FragmentController.dispatchCreate(FragmentController.java:190)
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:369)
at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:85)
at com.gongzelong.duolingowordsearch.MainActivity.onCreate(MainActivity.java:14)

但是我可以正确地写ToParcel:

2019-03-04 23:41:43.149 25699-25699/com.gongzelong.duolingowordsearch D/gzl: writeToParcel [ü, á, p, a, n]
2019-03-04 23:41:43.150 25699-25699/com.gongzelong.duolingowordsearch D/gzl: writeToParcel [k, a, k, m, l]
2019-03-04 23:41:43.150 25699-25699/com.gongzelong.duolingowordsearch D/gzl: writeToParcel [a, x, q, e, h]
2019-03-04 23:41:43.150 25699-25699/com.gongzelong.duolingowordsearch D/gzl: writeToParcel [p, s, a, j, í]
2019-03-04 23:41:43.150 25699-25699/com.gongzelong.duolingowordsearch D/gzl: writeToParcel [á, q, l, j, l]

更新:

我尝试在 MainActivity#onCreate 中像这样添加权限(读取和写入),但它没有修复崩溃。

if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {
//android 6.0 之后需要在activity中动态获取权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
//申请WRITE_EXTERNAL_STORAGE权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
1);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
//申请WRITE_EXTERNAL_STORAGE权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
1);
}
}

最佳答案

一旦您必须向 Parcel 读取/写入本地不受支持的内容,我建议您创建一个 ParcelableUtils 类来帮助组织您的代码。在这种情况下,String[][] 不受原生支持,因此我将创建方法来处理它。

public class ParcelableUtils {

private ParcelableUtils() {
throw new UnsupportedOperationException("static methods only");
}

public static String[][] createStringArrayArray(Parcel in) {
int size = in.readInt();

if (size != -1) {
String[][] arrayArray = new String[size][];

for (int i = 0; i < size; i++) {
arrayArray[i] = in.createStringArray();
}

return arrayArray;
} else {
return null;
}
}

public static void writeStringArrayArray(Parcel dest, String[][] arrayArray) {
if (arrayArray != null) {
dest.writeInt(arrayArray.length);

for (String[] array : arrayArray) {
dest.writeStringArray(array);
}
} else {
dest.writeInt(-1);
}
}
}

总体技巧是先写数组的数组的大小,然后再写每个数组。如果您查看 Parcel.java 的源代码,这正是 writeStringArray() 的实现方式。另一边也是如此:我们读取数组数组的大小,然后直接从 Parcel 创建每个数组。

有了这个,您在 WordSearch 上的 Parcelable 实现变得更容易处理:

private WordSearch(Parcel in) {
this.sourceLanguage = in.readString();
this.targetLanguage = in.readString();
this.word = in.readString();
this.characterGrid = ParcelableUtils.createStringArrayArray(in);
this.translations = in.createStringArrayList();
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.sourceLanguage);
dest.writeString(this.targetLanguage);
dest.writeString(this.word);
ParcelableUtils.writeStringArrayArray(dest, characterGrid);
dest.writeStringList(this.translations);
}

关于android - 尝试使用 onSaveInstanceState() 恢复 String[][] 时出现 "java.lang.NullPointerException: Attempt to get length of null array",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54987054/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com