Parcelable
を実装するさまざまなアクティビティにオブジェクトを渡すと、私のアプリケーションに奇妙なエラーが発生しているようです(GitHub参照)。java.lang.RuntimeException:Parcel android.os.Parcel:不明な型コードをアンマーシャリングしていません
スタックオーバーフローに関するその他の質問と回答を確認しましたが、解決策を見つけることができませんでした。私は、例えば、答えhereを試してみた - ここでは参考のためにある:
-keepclassmembers class * implements android.os.Parcelable {
static ** CREATOR;
}
私もwriteToParcel
のメソッド呼び出しが順番になっていることを確認作りました。この問題についての他のほとんどの質問には答えがありません。
また、私は新しい問題を尋ねている理由は、自分のアプリでインターフェイスをどのように使用したかによって問題が発生したと考えているからです(後ほど説明します)。スタックオーバーフローに関する他の質問は、私の特定のシナリオに合っていません。
以下では、必要に応じてコードの詳細を調べるために、GitHub経由でコードへのリンクを提供しました。
私は(Parcelable
を実装するオブジェクトを渡す)
launch a new activityへ]ボタンをクリックし
Process: com.satsuware.flashcards, PID: 4664
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.satsuware.flashcards/com.satsumasoftware.flashcards.ui.FlashCardActivity}: java.lang.RuntimeException: Parcel [email protected]: Unmarshalling unknown type code 6815860 at offset 200
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
...
Caused by: java.lang.RuntimeException: Parcel [email protected]: Unmarshalling unknown type code 6815860 at offset 200
at android.os.Parcel.readValue(Parcel.java:2319)
at android.os.Parcel.readListInternal(Parcel.java:2633)
at android.os.Parcel.readArrayList(Parcel.java:1914)
at android.os.Parcel.readValue(Parcel.java:2264)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2592)
at android.os.BaseBundle.unparcel(BaseBundle.java:221)
at android.os.Bundle.getParcelable(Bundle.java:786)
at android.content.Intent.getParcelableExtra(Intent.java:5377)
at com.satsumasoftware.flashcards.ui.FlashCardActivity.onCreate(FlashCardActivity.java:71)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
...
私は(もsee GitHub)のように、前述のアクティビティを呼び出す:
Intent intent = new Intent(TopicDetailActivity.this, FlashCardActivity.class);
intent.putExtra(FlashCardActivity.EXTRA_TOPIC, mTopic);
intent.putExtra(FlashCardActivity.EXTRA_NUM_CARDS, mSelectedNumCards);
intent.putExtra(FlashCardActivity.EXTRA_CARD_LIST, mFilteredCards);
startActivity(intent);
私がmTopic
を渡すときに考慮すべき主要部分です。これは私が作成したTopic
interfaceです。
しかし、Topic
インタフェースはParcelable
を拡張し、そうTopic
を実装するオブジェクトは、コンストラクタ、CREATOR
フィールド、及びParcelable
を実装するクラスは、通常持ってなければならない方法を含みます。
関連するクラスはGitHubリンクから見ることができますが、以下ではこれらのクラスの関連する部分について説明します。ここでTopic
インタフェースである:
public interface Topic extends Parcelable {
int getId();
String getIdentifier();
String getName();
Course getCourse();
ArrayList<FlashCard> getFlashCards(Context context);
class FlashCardsRetriever {
public static ArrayList<FlashCard> filterStandardCards(ArrayList<FlashCard> flashCards, @StandardFlashCard.ContentType int contentType) {
ArrayList<FlashCard> filteredCards = new ArrayList<>();
for (FlashCard flashCard : flashCards) {
boolean isPaper2 = ((StandardFlashCard) flashCard).isPaper2();
boolean condition;
switch (contentType) {
case StandardFlashCard.PAPER_1:
condition = !isPaper2;
break;
case StandardFlashCard.PAPER_2:
condition = isPaper2;
break;
case StandardFlashCard.ALL:
condition = true;
break;
default:
throw new IllegalArgumentException("content type '" + contentType + "' is invalid");
}
if (condition) filteredCards.add(flashCard);
}
return filteredCards;
}
...
}
}
implements Topic
ことクラス(オブジェクト):Course
である上記のコードの最後の行の一つで
public class CourseTopic implements Topic {
...
public CourseTopic(int id, String identifier, String name, Course course) {
...
}
@Override
public int getId() {
return mId;
}
@Override
public String getIdentifier() {
return mIdentifier;
}
...
protected CourseTopic(Parcel in) {
mId = in.readInt();
mIdentifier = in.readString();
mName = in.readString();
mCourse = in.readParcelable(Course.class.getClassLoader());
}
public static final Parcelable.Creator<CourseTopic> CREATOR = new Parcelable.Creator<CourseTopic>() {
@Override
public CourseTopic createFromParcel(Parcel in) {
return new CourseTopic(in);
}
@Override
public CourseTopic[] newArray(int size) {
return new CourseTopic[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mId);
dest.writeString(mIdentifier);
dest.writeString(mName);
dest.writeParcelable(mCourse, flags);
}
}
、私はmCourse
を通過見ることができ、オブジェクトを作成しました。
public class Course implements Parcelable {
...
public Course(String subject, String examBoard, @FlashCard.CourseType String courseType,
String revisionGuide) {
...
}
public String getSubjectIdentifier() {
return mSubjectIdentifier;
}
public String getExamBoardIdentifier() {
return mBoardIdentifier;
}
public ArrayList<Topic> getTopics(Context context) {
ArrayList<Topic> topics = new ArrayList<>();
String filename = mSubjectIdentifier + "_" + mBoardIdentifier + "_topics.csv";
CsvParser parser = CsvUtils.getMyParser();
try {
List<String[]> allRows = parser.parseAll(context.getAssets().open(filename));
for (String[] line : allRows) {
int id = Integer.parseInt(line[0]);
topics.add(new CourseTopic(id, line[1], line[2], this));
}
} catch (IOException e) {
e.printStackTrace();
}
return topics;
}
...
protected Course(Parcel in) {
mSubjectIdentifier = in.readString();
mBoardIdentifier = in.readString();
mCourseType = in.readString();
mRevisionGuide = in.readString();
}
public static final Creator<Course> CREATOR = new Creator<Course>() {
@Override
public Course createFromParcel(Parcel in) {
return new Course(in);
}
@Override
public Course[] newArray(int size) {
return new Course[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mSubjectIdentifier);
dest.writeString(mBoardIdentifier);
dest.writeString(mCourseType);
dest.writeString(mRevisionGuide);
}
}
私はここで何かを疑う問題を引き起こしている可能性、そして私のシナリオは、他の質問のものと異なっている理由である:ここにあります。
正直に答えにおける説明と指導をいただければ幸いですので、私は、エラーの原因となることができるものを正確にはわかりません。
編集:
デビッドワッサーの提案をした後、私はそうのように私のコードの一部を更新しました:
FlashCardActivity.java - onCreate(...)
:
Bundle extras = getIntent().getExtras();
extras.setClassLoader(Topic.class.getClassLoader());
mTopic = extras.getParcelable(EXTRA_TOPIC);
Course.java - writeToParcel(...)
:
dest.writeString(mSubjectIdentifier);
dest.writeString(mBoardIdentifier);
dest.writeString(mCourseType);
dest.writeInt(mRevisionGuide == null ? 0 : 1);
if (mRevisionGuide != null) dest.writeString(mRevisionGuide);
Course.java - Course(Parcel in)
:
mSubjectIdentifier = in.readString();
mBoardIdentifier = in.readString();
mCourseType = in.readString();
if (in.readInt() != 0) mRevisionGuide = in.readString();
私は、任意の変数がnullの場合writeToParcel(...)
に渡されるときに表示するLog.d(...)
を使用してログメッセージを追加し、適切にデビッドワッサーの方法を使用しましたこれを対応して。
ただし、同じエラーメッセージが表示されます。
'Intent'に入れられている実際のクラスのパーセル化とアンパイリングに関するコードを投稿してください。 –
@DavidWasser 'Intent'に入れられたクラスのコードを表示するための答えを更新しました(提供されているGitHubリンクを通して完全に見ることができます)。 –