2011-12-14 3 views
8

ユーザーが選択したアイテムの内容で新しいアクティビティを開いた後、元のListActivityに戻るときにこの例外が発生します。アイスクリームサンドイッチでのみ発生します。 このExceptionインスタンスをトリガーするもの: "java.lang.IllegalArgumentException:オブザーバーがヌルです。"どのように避けることができますか?

この

はトレースです:

java.lang.IllegalArgumentException: The observer is null. 
    at android.database.Observable.unregisterObserver(Observable.java:59) 
    at android.widget.BaseAdapter.unregisterDataSetObserver(BaseAdapter.java:42) 
    at android.widget.AbsListView.onDetachedFromWindow(AbsListView.java:2373) 
    at android.view.View.dispatchDetachedFromWindow(View.java:9756) 
    at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2274) 
    at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2272) 
    at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2272) 
    at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2272) 
    at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2272) 
    at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2272) 
    at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2272) 
    at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2272) 
    at android.view.ViewRootImpl.dispatchDetachedFromWindow(ViewRootImpl.java:2227) 
    at android.view.ViewRootImpl.doDie(ViewRootImpl.java:3679) 
    at android.view.ViewRootImpl.die(ViewRootImpl.java:3667) 
    at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:320) 
    at android.view.WindowManagerImpl$CompatModeWrapper.removeViewImmediate(WindowManagerImpl.java:139) 
    at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3144) 
    at android.app.ActivityThread.access$1200(ActivityThread.java:122) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1179) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:4340) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:511) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
    at dalvik.system.NativeStart.main(Native Method) 

私のコードのいずれもが、それは本当に私を不可解ですので、スタックに言及されていないと私はイベントが汚れてキャッチすることができません:私は登録しています/

を匿名DataSetObserverアクティビティが作成されたときのみ。また、アクティビティはActivityGroup内に埋め込まれています(4.0では廃止予定ですが、まだそれをサポートしているはずです)。

誰かが新しいOSでこの問題を抱えていましたか?

ありがとうございます。


更新:

[OK]を、それを解決する方法がわからないが、私は、問題の原因を見つけたと思います。 AbsListView.onDetachedFromWindow()インサイド

我々はこれを持っている:観察者が未登録であると、それは無効ます、

if (mAdapter != null) { // Android code added on ICS 
    mAdapter.unregisterDataSetObserver(mDataSetObserver); 
    mDataSetObserver = null; 
} 

。問題は何らかの理由でICSで2回呼び出されるということです。私はそれは、彼らがObservableクラスで行うよう削除操作の内側にはnullパラメータをチェックするために少し愚かだと思う:

public void unregisterObserver(T observer) { // Android code 
    if (observer == null) { 
     throw new IllegalArgumentException("The observer is null."); 
    } 
    synchronized(mObservers) { 
     int index = mObservers.indexOf(observer); 
     if (index == -1) { 
      throw new IllegalStateException("Observer " + observer + " was not registered."); 
     } 
     mObservers.remove(index); 
    } 
} 

彼らはそれを無視しないのはなぜ¬¬彼らは、この操作を行うだけの可能性があり、働くだろう同様に(またはそれ以上):

public void unregisterObserver(T observer) { // Android code 
    synchronized(mObservers) { 
     mObservers.remove(observer); 
    } 
} 
+0

あなたのアクティビティコードを投稿することはできますか?戻るに戻るボタンを押したとすると、アクティビティコードを投稿できますか? – zode64

+0

ええ、戻って、私は戻るボタンを押すことを意味します。以下はアクティビティのコードです(http://pastebin.com/68BzJcc1)が、私が言及したように、私のコードはスタックに表示されていません。 – pablisco

+0

私はバグレポートに記入しました:http://code.google.com/p/android/issues/detail?id=22946解決策が必要ですが、 – pablisco

答えて

11

この問題は、Android 4.0.3で導入し、観察可能クラスは時にオブザーバーに例外をスローするように変更されました複数回リリースされました。これはバグとして報告されており、ここで読むことができます:http://code.google.com/p/android/issues/detail?id=22946

この問題を回避する最も簡単な方法は、基になるアダプターをラップし、複数のリリースを避けることです。

@Override 
public void unregisterDataSetObserver(DataSetObserver observer) { 
    if (observer != null) { 
    super.unregisterDataSetObserver(observer); 
    } 
} 

しかし、これはすべての場合に機能しません。 ExpandableListViewにはアクセスできない内部アダプタがあります。別の解決策は、ExpandableListViewをラップして例外をキャッチすることです。このソリューションは私のために働いた、と私はまだ副作用が見つかりませんでした。

public class PatchedExpandableListView extends ExpandableListView { 

    public PatchedExpandableListView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    } 

    @Override 
    protected void onDetachedFromWindow() { 
    try { 
     super.onDetachedFromWindow(); 
    } catch(IllegalArgumentException iae) { 
     // Workaround for http://code.google.com/p/android/issues/detail?id=22751 
    } 
    } 
} 
3

私は私のクラスのいずれも微量で言及されなかったことを考えるの愚かなミスを犯したが、LoadingDataViewはそのうちの一つです。元のトレースには表示されませんが、関連する別のトレースに表示されます。

事件はので、私は周りの仕事としてこれを追加起こっているところだった匿名ArrayAdapterがあり、そのクラス内:

@Override 
public void unregisterDataSetObserver(DataSetObserver observer) { 
    if (observer != null) { 
     super.unregisterDataSetObserver(observer); 
    } 
} 

そして、それは私はまだ、なぜこのわからないが、今で動作しているようですメソッドが2回呼び出されました。

、が、私は同じくらい私ができるようにフラグメントを使用するつもりで、今のところ;)

関連する問題