不可解な結末
AIDLのパラメタとして定義したBundle型にParcelableとして定義したクラスのインタンスをセットして、Service側のメソッドを呼ぶとBadParcelableExceptionがスローされる件だったが、
Bundle bundle = new Bundle(); BaseInfo baseInfo = new BaseInfo(); bundle.putParcelable("baseInfo", baseInfo);
: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: attendroid.model.BaseInfo: at android.os.Parcel.readException(Parcel.java:1249) : at android.os.Parcel.readException(Parcel.java:1235) : at attendroid.service.IWebScrapingService$Stub$Proxy.scrape(IWebScrapingService.java:125) : at attendroid.CalendarActivity$CalendarSelectAction.getModel(CalendarActivity.java:123) : at java.lang.reflect.Method.invokeNative(Native Method) : at java.lang.reflect.Method.invoke(Method.java:521)
昨日エントリで書いた通り、エミュレータをワイプしたらトレースできない不具合が直る所か、上記例外まで発生しなくなってしまった。
試しに、Serviceのメソッドを呼ぶ直前と、Serviceメソッド中で同様にBundleにBaseInfoクラスのインスタンスを生成しても全く問題無し。
public boolean scrape(String siteurl, Bundle bundle) throws RemoteException { BaseInfo baseInfo = bundle.getParcelable("baseInfo"); if ( baseInfo == null) { baseInfo = new BaseInfo(); bundle.putParcelable("baseInfo", baseInfo); //問題無し! }
昨日あれだけ苦労したのはなんだったんだろう..
冷静に考えると、なんらかの原因でエミュレータ上のパッケージが破損して、その後同例外が発生するようになったということだろうか。下のエントリの現象を見ると破損は一様ではなく様々な不具合を起こすようだ。
何はともあれ、BundleにParcelableを詰め込んだ状態で渡し、Service側でBundleとその内部のParcelableを復旧する、いわゆるマーシャル/アンマーシャル(シリアライズ/デシリアライズ)は上手く動くことが解った。
ふと思ったんだが、なんらかの理由でActivity側とService側のどちらかのパッケージが置き換わらない現象が発生し、その結果不整合が生じて互いの型を参照できなくなった、ような気がするが検証できた訳ではないのでまた次回再現した際にはいろいろと試してみよう。(現在はどんなことをしても再現しなくなってしまった)