Android - 如何避免在活动之间重复使用代码

3
这是一个比较普遍的问题,但我将为您举个具体的例子。在我的应用程序中有很多活动,所有的活动都有一个Facebook按钮。当你点击这个按钮时,它会带你到一个特定的Facebook页面。我希望每个页面上的按钮行为都完全相同。
目前,在每个Activity中,我都要创建一个onClickListener()来处理Facebook按钮的点击事件,并启动一个新的Activity。在每个Activity中都有相同的代码。
如何只编写一次此代码并将其包含在多个Activity中?是否有办法包含其他.java文件?
一个我知道可以解决这个问题的方法是,创建一个基本的CustomActivity类,扩展自Activity,然后让所有的Activity都扩展自CustomActivity。然后把我的onClickListener()代码放在CustomActivity里。不过我刚开始学Java,不确定这是否是最好的方法。我的一些Activities已经扩展了其他自定义activity类,所以扩展更多的类可能会变得有点混乱,我不知道。
更新: 如果我采用继承的方式并创建了一些CustomActivity,我希望我的Activities都能够扩展该类。CustomActivity将包含一些通用的代码,其中包括但不限于Facebook按钮功能。如果有一个Activity需要使用CustomActivity中的通用代码,但该特定Activity中没有Facebook按钮,那会发生什么呢?
4个回答

6
一种常见的基类可能是最好的方法。(如果您的一些活动扩展了Activity并且一些扩展了Activity子类(如ListActivity),则不会起作用。)
另一种方法是创建一个单独的类来实现单击侦听器的逻辑。这并不能消除所有重复代码,因为每个活动仍然需要实例化和注册侦听器,但是只需要在侦听器类中编写一次执行操作的逻辑。
在任何一种替代方案中,您可以考虑将android:onClick属性分配给按钮。这样,您就不需要注册单击侦听器;您只需要在每个活动中实现目标方法。这在使用基类方法时特别有用。
更新
假设您采用继承路线,并且您想要一个没有Facebook按钮的活动。如果您使用android:onClick技术,则您不需要在代码中进行任何不同的操作——因为没有按钮会调用您的onClick方法,该方法将坐在那里什么也不做。如果您正在安装一个OnClickListener,则只需要在注册侦听器之前测试按钮是否存在(即findViewById()没有返回null)。

有趣的方法。谢谢! - Jake Wilson

6
通常来说,使用一个共同的基类并不是最好的方法(尽管它肯定是有效的)。
这需要我(以及我所知道的所有“掌握”面向对象编程的程序员)一段时间才真正理解,但你应该尽可能地少用继承。每次使用时,你都应该问自己是否真的没有其他方法可以做到这一点。
找出答案的一种方法是非常严格地进行“is-a”测试--如果你将基本活动称为“Facebook Activity”,那么每个子项是否真的“是”一个Facebook活动?可能不是。另外,如果你决定在某些页面中添加Twitter而在其他页面中不添加,你该怎么做?
并不是说继承完全被排除了!一个很好的解决方案可能是扩展一个控件以启动你的facebook活动并将其称为facebook按钮--将它封装到连接到Facebook所需的所有内容中。现在,你可以通过简单地拖动它来将它添加到任何你想要的页面上(我相信android工具允许你向工具栏添加新组件)。这不像扩展活动类那样“免费”,但从长远来看,它会给你带来更少的压力。
你可能现在不会相信我,我们都需要从自己的经验中学习,只需记住这一点,并将其用于随着时间推移对你的代码进行评估即可。
-编辑,评论回复-
你可以封装任何你认为会经常使用的Facebook活动到它自己的类中--将其最小化,以便你可以在一行代码中将其添加到任何类中。
但是在某些时候,你可能会决定它仍然有太多的样板文件,我完全理解。此时,你可以使用一个抽象基本活动,就像你所建议的那样,但我不会将其硬编码为明确处理Facebook,而是使其支持诸如Facebook(和可能的其他)行为,并根据需要打开这些行为。然后,如果你希望,在给定的屏幕上不添加Facebook行为,或者在其中添加Twitter。
你可以使这个样板文件最少化,例如,如果你想要“标准”功能,则不必做任何特殊处理,如果你想要禁用Facebook,你可以从你的构造函数开始:
super(DISABLE_FACEBOOK_BEHAVIOR);

如果你想要一个同时支持 Twitter 的,你可以使用:

super(DISABLE_FACEBOOK_BEHAVIOR, ENABLE_TWITTER_BEHAVIOR);

使用类似于AbstractAction(BehaviorEnum... behaviors)的构造函数更加灵活,你可以毫无顾忌地说每个活动都是一个“支持行为”的活动。
当然,一开始不那么灵活也是完全可行的方法。当需要时再重构为这种模式,只需警惕继承模型会导致问题,以免在修复之前让其破坏你太久。

1
你提出了一些好的观点。我最初对继承的事情有所担忧,因为如果在某个活动中没有Facebook按钮,但我仍然需要使用FacebookActivity类的其他方面,会发生什么... - Jake Wilson

3

扩展是面向对象编程的原则,因此我认为有多个子类级别并不是问题。在我看来,您考虑的解决方案是最好的。


0
绝对没错。在面向对象编程中,使用继承来提高一些可重用性是必须的。随着你的进步,你会发现在你的活动中有越来越多的东西需要被重复使用,这些东西可能比一个为FB按钮设置的onClick监听器更加复杂,因此建议开始构建一个好的、可重复使用的"超级"活动,以便可以继承使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接