- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图让 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/
如果您想使用 String.Concat() 连接 5 个或更多字符串,则它会使用 Concat(String[])。 为什么不一直使用 Concat(String[]) 而不再需要 Concat(S
今天在使用 String 时,我遇到了一种我以前不知道的行为。我无法理解内部发生的事情。 public String returnVal(){ return "5";
似乎在我所看到的任何地方,都有一些过时的版本,这些版本不再起作用。 我的问题似乎很简单。我有一个Java类,它映射到derby数据库。我正在使用注释,并且已经成功地在数据库中创建了所有其他表,但是在这
一、string::size_type() 在C++标准库类型 string ,在调用size函数求解string 对象时,返回值为size_type类型,一种类似于unsigned类型的int 数据
我正在尝试将数据保存到我的 plist 文件中,其中包含字符串数组的定义。我的plist - enter image description here 我将数据写入 plist 的代码是 -- let
我有一个带有键/值对的 JavaScript 对象,其中值是字符串数组: var errors = { "Message": ["Error #1", "Error #2"], "Em
例如,为了使用相同的函数迭代 List 和 List> ,我可以编写如下内容: import java.util.*; public class Test{ public static voi
第一个Dictionary就像 Dictionary ParentDict = new Dictionary(); ParentDict.Add("A_1", "1")
这是我的 jsp 文件: 我遇到了错误 The method replace(String, String, String) in the type Functions is not appl
我需要一些帮助。我有一个方法应该输出一个包含列表内容的 txt 文件(每行中的每个项目)。列表项是字符串数组。问题是,当我调用 string.Join 时,它返回文字字符串 "System.Strin
一位同事告诉我,使用以下方法: string url = "SomeURL"; string ext = "SomeExt"; string sub = "SomeSub"; string s
给定类: public class CategoryValuePair { String category; String value; } 还有一个方法: public
我正在尝试合并 Stream>>对象与所有 Streams 中的键一起映射到单个映射中. 例如, final Map someObject; final List>> list = someObjec
在这里使用 IDictionary 的值(value)是什么? 最佳答案 使用接口(interface)的值(value)始终相同:切换到另一个后端实现时,您不必更改客户端代码。 请考虑稍后分析您的代
我可以知道这两个字典声明之间的区别吗? var places = [String: String]() var places = [Dictionary()] 为什么当我尝试以这种方式附加声明时,只有
在 .NET 4.0 及更高版本中存在 string.IsNullOrWhiteSpace(string) 时,在检查字符串时使用 string.IsNullOrEmpty(string) 是否被视为
这个名字背后的原因是什么? SS64在 PowerShell 中解释此处的字符串如下: A here string is a single-quoted or double-quoted string
我打算离开 this 文章,尝试编写一个接受字符串和 &str 的函数,但我遇到了问题。我有以下功能: pub fn new(t_num: S) -> BigNum where S: Into {
我有一个结构为 [String: [String: String]] 的多维数组。我可以使用 for 循环到达 [String: String] 位,但我不知道如何访问主键(这个位 [String:
我正在尝试使用 sarama(管理员模式)创建主题。没有 ConfigEntries 工作正常。但我需要定义一些配置。 我设置了主题配置(这里发生了错误): tConfigs := map[s
我是一名优秀的程序员,十分优秀!