是什么触发此异常情况:" java.lang.IllegalArgumentException:如果观察者为空"。怎么可能它被避免? [英] What is triggering this Exception instance: "java.lang.IllegalArgumentException: The observer is null." and how could it be avoid?

查看:264
本文介绍了是什么触发此异常情况:" java.lang.IllegalArgumentException:如果观察者为空"。怎么可能它被避免?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在与用户所选项目的内容打开一个新的活动后返回到原来的 ListActivity 获得此异常。它只发生在冰淇淋三明治。

这是跟踪:

  java.lang.IllegalArgumentException:如果观察者为空。
    在android.database.Observable.unregisterObserver(Observable.java:59)
    在android.widget.BaseAdapter.unregisterDataSetObserver(BaseAdapter.java:42)
    在android.widget.AbsListView.onDetachedFromWindow(AbsListView.java:2373)
    在android.view.View.dispatchDetachedFromWindow(View.java:9756)
    在android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2274)
    在android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2272)
    在android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2272)
    在android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2272)
    在android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2272)
    在android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2272)
    在android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2272)
    在android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2272)
    在android.view.ViewRootImpl.dispatchDetachedFromWindow(ViewRootImpl.java:2227)
    在android.view.ViewRootImpl.doDie(ViewRootImpl.java:3679)
    在android.view.ViewRootImpl.die(ViewRootImpl.java:3667)
    在android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:320)
    在android.view.WindowManagerImpl $ CompatModeWrapper.removeViewImmediate(WindowManagerImpl.java:139)
    在android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3144)
    在android.app.ActivityThread.access $ 1200(ActivityThread.java:122)
    在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1179)
    在android.os.Handler.dispatchMessage(Handler.java:99)
    在android.os.Looper.loop(Looper.java:137)
    在android.app.ActivityThread.main(ActivityThread.java:4340)
    在java.lang.reflect.Method.invokeNative(本机方法)
    在java.lang.reflect.Method.invoke(Method.java:511)
    在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:784)
    在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    在dalvik.system.NativeStart.main(本机方法)
 

没有我的code中提到的栈,所以它实在令人费解了我,我不能做的事件一个肮脏的陷阱:/

我注册一个匿名 DataSetObserver 创建活动,只有当。同时该活动已经被嵌入一个的ActivityGroup内(这是pcated在4.0代$ P $,但还是应该询问服务的话,我希望)。

有没有人有这个问题与新的操作系统?

在此先感谢。


更新:

好,想我找到了问题的根源,虽然不知道如何解决它。

AbsListView.onDetachedFromWindow()我们有这样的:

 如果(mAdapter!= NULL){//安卓code加在ICS
    mAdapter.unregisterDataSetObserver(mDataSetObserver);
    mDataSetObserver = NULL;
}
 

,一旦观察者未注册的,它被废止。问题就来了,由于某种原因,在ICS中它被称为两次。我认为这是一个有点傻检查null参数的删除操作在的,因为他们做的观测类:

 公共无效unregisterObserver(T观察者){//安卓code
    如果(观察员== NULL){
        抛出新抛出:IllegalArgumentException(观察者为空);
    }
    同步(mObservers){
        INT指数= mObservers.indexOf(观察员);
        如果(指数== -1){
            抛出新IllegalStateException异常(观察家报+观察+没有注册。);
        }
        mObservers.remove(指数);
    }
}
 

为什么他们不只是忽略它¬¬其实他们完全可以做到这一点,将工作和(或更好):

 公共无效unregisterObserver(T观察者){//安卓code
    同步(mObservers){
        mObservers.remove(观察员);
    }
}
 

解决方案

这个问题被引入的Andr​​oid 4.0.3,并观测类被改为抛出当观察者被释放不止一次例外。它已被报告为一个错误,可以在这里显示为:<一href="http://$c$c.google.com/p/android/issues/detail?id=22946">http://$c$c.google.com/p/android/issues/detail?id=22946.

要解决这个问题,最简单的方法是包装底层接口,避免多个版本。

  @覆盖
公共无效unregisterDataSetObserver(DataSetObserver观察者){
  如果(观察者!= NULL){
    super.unregisterDataSetObserver(观察员);
  }
}
 

但是,这不会在所有情况下,例如ExpandableListView具有不能访问内部衔接头。这里有一个替代解决方案是包裹ExpandableListView和捕获异常。该解决方案为我工作,我还没有没有发现任何副作用。

 公共类PatchedExpandableListView扩展ExpandableListView {

  公共PatchedExpandableListView(上下文的背景下,ATTRS的AttributeSet){
    超(背景下,ATTRS);
  }

  @覆盖
  保护无效onDetachedFromWindow(){
    尝试 {
      super.onDetachedFromWindow();
    }赶上(抛出:IllegalArgumentException IAE){
      //解决方法对于http://$c$c.google.com/p/android/issues/detail ID = 22751
    }
  }
}
 

I'm getting this exception when returning to the original ListActivity after opening an new activity with the content of the item selected by the user. It only occurs on Ice Cream Sandwich.

This is the trace:

 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)

None of my code is mentioned in the stack so it's really puzzling me and I can't event do a dirty catch :/

I am registering an anonymous DataSetObserver only when the activity is created. Also the activity is embedded inside an ActivityGroup (which is deprecated in 4.0 but should still suport it, I was hoping).

Has anybody had this problem with the new OS?

Thanks in advance.


Update:

Ok, think I found the source of the problem although not sure how to resolve it.

Inside AbsListView.onDetachedFromWindow() We have this:

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

Which, once the observer is unregistered, it gets nullified. The problem comes that, for some reason, in ICS it gets called twice. I think it's a bit silly to check for null parameters inside a delete operation as they do in the Observable class:

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);
    }
}

Why don't they just ignore it ¬¬ They could just do this and would work as well (or better):

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

解决方案

This problem was introduced in Android 4.0.3, and the Observable class was changed to throw an exception when an observer was released more than once. It has been reported as a bug and can be read here: http://code.google.com/p/android/issues/detail?id=22946.

The easiest way to work around this problem is to wrap the underlying adapter and avoid multiple releases.

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

But that will not work in all cases, e.g. ExpandableListView has an internal adapter that cannot be accessed. An alternative solution here is to wrap the ExpandableListView and catch the exception. This solution worked for me, and I have yet not found any side effects.

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
    }
  }
}

这篇关于是什么触发此异常情况:&QUOT; java.lang.IllegalArgumentException:如果观察者为空&QUOT;。怎么可能它被避免?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆