我有一个问题,我试图解决几个小时但无法解决它,我需要一些帮助。我试图从Login活动中检索URL字符串并尝试使用parcelable对象将其传递给Main活动,但我在getParcelable方法上收到NullPointerException。
以下是创建URL parcelable对象并将其放入Intent并调用Main活动的代码
public void onGetPremiumURLCompletion(List<String> urls){
String[] urlList = new String[urls.size()];
for (int i = 0; i < urls.size(); i++) {urlList[i] = urls.get(i);}
URL urlParcelable = new URL(urlList);
for (int i = 0; i < urlParcelable.getUrls().length; i++) {Log.w("url from parcelable",urlParcelable.getUrls()[i]);}
Intent intent = new Intent(this,Home.class);
intent.putExtra("PremiumURLList",urlParcelable);
progress.dismiss();
startActivity(intent);
}
以下是URL parcelable class
public class URL implements Parcelable {
private String[] urls;
public static final Parcelable.Creator<URL> CREATOR = new Parcelable.Creator<URL>() {
public URL createFromParcel(Parcel in) {
return new URL(in);
}
public URL[] newArray(int size) {
return new URL[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(urls);
}
private URL(Parcel in) {
in.readStringArray(urls);
}
public URL(String[] urlList){
urls = urlList;
}
public String[] getUrls() {
return urls;
}}
以下是我从意图中接收parcelable对象的方法。
Bundle b = getIntent().getExtras();
URL urlList = b.getParcelable("PremiumURLList");
我在getParcelable line上收到以下错误
Caused by: java.lang.NullPointerException
at android.os.Parcel.readStringArray(Parcel.java:962)
at com.rayat.pricewiz.entity.URL.<init>(URL.java:33)
at com.rayat.pricewiz.entity.URL.<init>(URL.java:9)
at com.rayat.pricewiz.entity.URL$1.createFromParcel(URL.java:14)
at com.rayat.pricewiz.entity.URL$1.createFromParcel(URL.java:12)
at android.os.Parcel.readParcelable(Parcel.java:2104)
at android.os.Parcel.readValue(Parcel.java:2013)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2314)
at android.os.Bundle.unparcel(Bundle.java:249)
at android.os.Bundle.getParcelable(Bundle.java:1206)
at com.rayat.pricewiz.view.activity.tabhome.Home.onCreate(Home.java:72)
at android.app.Activity.performCreate(Activity.java:5426)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
请帮忙。
由于
答案 0 :(得分:1)
你的问题在这里:
private URL(Parcel in) {
in.readStringArray(urls);
}
此时 urls
为null,readStringArray(String[])
方法需要一个非null的参数,并且与生成的读取数组的长度相同。我发现这种方法几乎无用,因为除非事先知道数组的固定大小,否则它并不能真正起作用。或者,我建议您使用createStringArray()
:
private URL(Parcel in) {
urls = in.createStringArray();
}
答案 1 :(得分:0)
我遇到了一个问题,试图理解原因。我们必须检查代码才能理解。
您可以看到 writeStringArray 检查可为空的值,然后将数组的大小作为int值保存到可打包的文件中(否则将-1值写为整数)。
public final void writeStringArray(@Nullable String[] val) {
if (val != null) {
int N = val.length;
writeInt(N);
for (int i=0; i<N; i++) {
writeString(val[i]);
}
} else {
writeInt(-1);
}
}
readStringArray 使用@NonNull参数。因此它可能会引发异常(如果您的数组为null)。
public final void readStringArray(@NonNull String[] val) {
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
val[i] = readString();
}
} else {
throw new RuntimeException("bad array lengths");
}
}
最后,您可以看到 createStringArray 方法正在首先读取数组的大小。然后读取数组的每个字符串(在其中使用nativeReadString)。
@Nullable
public final String[] createStringArray() {
int N = readInt();
if (N >= 0) {
String[] val = new String[N];
for (int i=0; i<N; i++) {
val[i] = readString();
}
return val;
} else {
return null;
}
}
因此您可以: