【问题标题】:Is there any way to avoid the use of instanceOf in Android?有什么办法可以避免在 Android 中使用 instanceOf 吗?
【发布时间】:2015-12-17 15:05:00
【问题描述】:

我们都同意使用 instanceOf 通常不是最好的解决方案。网络上有很多例子。

但是让我们考虑一下下面的例子,我们需要从一个片段调用一个方法到它的活动:

public class BaseActvity extends FragmentActivity implements ISomething {
    @Override
    public void doSomething();
}

然后假设我们在应用中有一个片段需要调用doSomething()

public MyFragment extends Fragment() {

public void onCreate() {
    public void onResume() {
        Activity activity = getActivity();
        if (activity != null && activity instanceOf ISomething) {
            ISomething something = (ISomething) activity;
            something.doSomething();
        }
    }
}

public interface ISomething {
    void doSomething();
}

如您所见,我们不能保证 getActivity() 将返回 ISomething 的对象,因此我们检查类型。一个改进是添加一个接口,但我们仍然会检查 getActvity() 返回类型以保护我们的代码。

由于 Android 框架的性质和 getActivity() 调用,我找不到更好的解决方案。也许有人可以提供一些意见..

注意:我添加了一个界面来遵循访问者模式。请注意,我仍然必须使用 instanceOf 来确保父 Activity 正在实现它。

谢谢。

加斯帕·德·埃莱斯

【问题讨论】:

  • 你可以使用 EventBus: github.com/greenrobot/EventBus
  • '我们都同意使用 instanceOf 通常不是最好的解决方案。 '。 ?不,我没有。
  • @greenapps 在过去,使用 instanceOf 有两个缺点:1.效率不高,2.如果我们忘记在某个类中实现某些接口,您可能会导致崩溃或隐藏问题。问题 #1 已通过现代 JVM/JIC 优化 (stackoverflow.com/questions/103564/…) 解决,但 #2 仍然是一个问题。如果可能,一个好的设计可以在编译时检测到 #2,比如使用访问者模式:stackoverflow.com/questions/8841577/…

标签: android instanceof


【解决方案1】:

您是对的,最好在您的Fragment 中定义一个接口并要求Activity 来实现它。然后,在您的onAttach() 中,您将您的Activity 转换为try/catch 中的接口,如果它抛出ClassCastException,您可以抛出您自己的异常。

public MyFragment extends Fragment {
    private Callback  mCallback;

    public interface Callback {
        void doSomething();
    }
    ...

    @Override
    public void onAttach(Activity activity) {
        try {
            mCallback = (Callback)activity;
        } catch (ClassCastException e) {
            throw new IllegalArgumentException("Activity must implement Callback");
        }
    }
}

事实上,这就是主要 Android 开发者网站上的 Fragment 页面中推荐/描述的内容:http://developer.android.com/training/basics/fragments/communicating.html

【讨论】:

  • 谢谢,我已经添加了一个接口,但仍在使用 instanceOf。从您的角度来看,捕获异常与 instanceOf 的优势是什么?效率?代码易读性?抛出 RuntimeException 似乎会影响恕我直言。
  • 通过使用异常,您正在执行您的意图:任何使用此FragmentActivity 必须支持该接口。你可以对instanceOf 做同样的事情,如果失败就抛出一个异常。在性能方面,两者都使用反射形式,但例外情况更昂贵,因为它必须创建新对象。就可读性而言,恕我直言,这是预期的使用模式。
  • 你是对的,你在 onAttach 中抛出异常,这是有道理的,谢谢。我会将问题标记为已回答。干杯。
【解决方案2】:

您可以查看访问者模式。 Here是一个解释和一些Java代码。

【讨论】:

  • 不幸的是,对于这种特殊情况,Activity 类是 System 类,并且引用是通过调用 getActivity() 获得的,因此无法避免 instanceOf // 或 ClassCastException 捕获块。如您所见,我已经更新了代码,以便使用接口 ISomething 使用访问者模式,但我们仍然存在转换问题。
猜你喜欢
  • 2014-02-07
  • 2014-05-25
  • 2017-08-30
  • 1970-01-01
  • 1970-01-01
  • 2021-11-22
  • 2022-07-01
  • 2012-04-18
  • 2022-11-15
相关资源
最近更新 更多