Android - 如何避免活动之间重复代码
这是一个有点笼统的问题,但我会给你举一个具体的例子。
我的应用程序中有很多活动。在所有活动中,都有一个 Facebook 按钮。当您单击该按钮时,您将进入特定的 Facebook 页面。我希望按钮在每个页面上的行为都完全相同。
现在,在每个 Activity 中,我为 Facebook 按钮创建一个 onClickListener()
并制定意图并启动该 Activity。每个活动中的代码都是相同的。
编写一次此代码并将其包含在多个活动中的最佳方法是什么?是否可以包含其他 .java 文件?
我知道可行的一种解决方案是创建一个扩展 Activity
的基 CustomActivity
类,然后让所有活动都扩展 CustomActivity
。然后将我的 onClickListener()
代码放入 CustomActivity
中。虽然我是 Java 新手,但我不确定这是否是最好的方法。我的一些活动已经按原样扩展了其他自定义活动类,因此扩展扩展更多内容的内容可能会变得有点混乱,我不知道。
更新
在这里唱反调:假设我采用继承路线,并创建了一些我希望我的活动扩展的CustomActivity
。 CustomActivity
将包含一堆我需要用于所有活动的通用代码,包括但不限于 Facebook 按钮功能。当我需要使用 CustomActivity
中的通用代码但该特定 Activity 中没有 Facebook 按钮时,会发生什么情况?
This is a bit of a general question, but I will give a specific example for you.
I have a bunch of activities in an App. In all of the activities, there is a Facebook button. When you click the button it takes you to a specific Facebook page. I wish for the button to behave exactly the same way on every page.
Right now, in every single Activity, I create an onClickListener()
for the Facebook button and make the intent and start the activity. It's the same code in every single Activity.
What is the best way to write this code once and include it in multiple activities? Is there anyway to include other .java files?
One solution that I know would work, is to make a base CustomActivity
class that extends Activity
and then have all activities extend CustomActivity
. Then put my onClickListener()
code in CustomActivity
. I'm new to Java though and I wasn't sure if that was the best approach or not. Some of my Activities already extend other custom activity classes as is, so extending things that extend more things might get kinda messy, I dunno.
UPDATE
Playing the devil's advocate here: Lets say I went with the inheritance route and I create some CustomActivity
that I want my Activities to extend. CustomActivity
would contain a bunch of general code that I need to use for all Activities, including but not limited to the Facebook button functionality. What happens when there is an Activity that I need to use generic code from the CustomActivity
but there is no Facebook button in that specific Activity?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
公共基类也许是最好的方法。 (如果您的某些活动扩展了 Activity 并且某些扩展了 Activity 子类(例如 ListActivity),则效果不太好。
另一种方法是创建一个单独的类来实现单击侦听器的逻辑。这并不能消除所有重复的代码 - 每个活动仍然需要实例化并注册一个侦听器 - 但要做的事情的逻辑只需要在侦听器类中编写一次
在任一替代方案中,您可以考虑分配
android:onClick< /code> 按钮的属性。您不需要注册点击侦听器;您只需要在每个活动中实现目标方法,这对于
更新
假设您采用继承路线 。想要一个没有 Facebook 按钮的活动。如果您使用
android:onClick
技术,那么您不必在代码中做任何不同的事情 - 因为没有按钮会调用您的 onClick 方法,该方法只会坐在那里什么也不做。如果您在代码中安装 OnClickListener,则只需在注册侦听器之前测试该按钮是否存在(即findViewById()
未返回null
)。A common base class is perhaps the best approach. (It doesn't work quite so well if some of your activities extend Activity and some extend Activity subclasses (such as ListActivity).
An alternate approach is to create a separate class that implements the logic of your click listener. This doesn't eliminate all duplicate code — each activity still needs to instantiate and register a listener — but the logic for what to do will only need to be written once in the listener class.
In either alternative, you might consider assigning the
android:onClick
attribute to the button. That way you don't need to register a click listener; you just need to implement the target method in each activity. This is particularly useful with the base class approach.UPDATE
Suppose you go the inheritance route and you want an activity with no Facebook button. If you are using the
android:onClick
technique, then you don't have to do anything different in your code — since no button will invoke your onClick method, the method will just sit there doing nothing. If you are installing an OnClickListener in code, then you just need to test that the button exists (i.e., thatfindViewById()
did not returnnull
) before registering the listener.一般来说,公共基类不是最好的方法(尽管它肯定是有效的)。
这花了我(以及我所知道的每个“了解”OO 的 OO 程序员)一段时间才真正理解,但是您应该尽可能少地使用继承。每次你这样做时,你都应该问自己是否真的没有其他方法可以做到这一点。
找出答案的一种方法是非常严格地进行“is-a”测试——如果您将基本活动称为“Facebook 活动”,您真的可以说每个孩子“是”一个 Facebook 活动吗?可能不会。另外,如果您决定将 Twitter 添加到某些页面(但不添加其他页面),您该如何执行此操作?
并不是说继承就完全消失了!一个很好的解决方案可能是扩展一个控件来启动您的 Facebook 活动,并将其称为 Facebook 按钮 - 让它封装连接到 Facebook 所需执行的所有操作。现在,您只需将其拖动即可将其添加到您想要的任何页面(我很确定 Android 工具可以让您将新组件添加到托盘中)。这不像延长你的活动课程那样“免费”,但从长远来看,它会减轻你的压力。
您现在可能不会相信我,我们都需要从自己的经验中学习,只需记住这一点,并在您随着时间的推移改进代码时用它来评估您的代码。
--编辑,评论回复--
您可以将您认为会在自己的类中经常使用的任何Facebook活动封装起来--将其保持在最低限度,这样您就可以将其添加到任何类中。
然而,在某些时候,您可能会认为它仍然是太多的样板,我完全理解。那时,您可以像您建议的那样使用抽象基本活动,但我不会对其进行硬编码以显式处理 facebook,而是让它支持 facebook(也许还有其他)等行为,并打开这些行为所期望的行为。然后,如果您愿意,您可以告诉它不要将 Facebook 行为添加到给定屏幕,或者将 Twitter 添加到其中一些屏幕。
您可以使这个样板文件最小化,例如,如果您想要“标准”功能,则不必做任何特别的事情,如果您希望禁用 facebook,您可以使用以下内容启动您的构造函数:
如果您想要一个也启用 Twitter 的函数,您可以可以使用:
使用像 AbstractAction(BehaviorEnum...behaviors) 这样的构造函数。
这更加灵活,您实际上可以说,如果您的每项活动都是问心无愧的“行为支持活动”。
当然,这是一种非常好的方法,一开始不太灵活,稍后当您需要时重构为这样的模式,只需留意您的继承模型是否会导致问题,这样您就不会让它变得混乱在你修复它之前你已经准备了太久了。
Generally a common base class is NOT the best approach (although it's certainly valid).
This took me (and every OO programmer who "gets" OO that I know of) a while to really grok, but you should use inheritance as sparingly as you possibly can. Every time you do it you should ask yourself if there is REALLY no other way to do this.
One way to find out is to be very strict with the "is-a" test--if you call your base activity a "Facebook Activity", could you really say that each child "is" a Facebook activity? Probably not. Also if you decided to add in Twitter to some of the pages (but not others), how do you do this?
Not that inheritance is completely out! A great solution might be to extend a control to launch your facebook activity and call it a facebook button--have it encapsulate all the stuff you need to do to connect to facebook. Now you can add this to any page you want by simply dragging it on (I'm pretty sure android tools let you add new components to the pallet). It's not "Free" like extending your activity class, but in the long run it will cost you a lot less stress.
You probably won't believe me now, we all need to learn from our own experience, just keep this in mind and use it to evaluate your code as you evolve it over time.
--edit, comment response--
You can encapsulate any facebook activity you think you will use a lot in it's own class--get it to a bare minimum so you can just add it to any class in a one-liner.
At some point, however, you may decide that it's STILL too much boilerplate, I totally understand. At that point you COULD use an abstract base activity like you suggest, but I wouldn't hard-code it to handle facebook explicitly, instead I'd have it support behaviors such as facebook (and maybe others), and turn-on these behaviors as desired. You could then tell it NOT to add the facebook behavior to a given screen if you like, or add in Twitter to some of them.
You can make this boilerplate minimum, for instance if you want "Standard" functionality, you shouldn't have to do anything special, if you wish to disable facebook you might start your constructor with:
and if you want one that also enables Twitter you could use:
with a constructor like AbstractAction(BehaviorEnum... behaviors).
This is more flexible and you actually can say that each if your activities IS-A "behavior supporting activity" with a clear conscience.
It is, of course, a perfectly good approach to be less flexible at first and refactor into a pattern like this later when you need to, just be on the look-out for your inheritance model causing problems so you don't let it mess you up for too long before you fix it.
嗯,扩展事物是 OOP 的原则,所以我不认为拥有多于一层的子类是一个问题。我认为您想到的解决方案是最好的。
Well, extending things is the principle of OOP, so I don't think this is a problem to have more than one level of subclasses. The solution you thought about is in my opinion the best.
绝对地。使用继承来获得一定的可重用性,就像使用 OOP 一样。随着您的进步,您会发现您想要在活动中重用的东西会越来越多——比 FB 按钮的 onClickListener 更复杂的东西——所以开始构建一个不错的、可重用的“超级”活动,您可以从中继承。
Absolutely. Use inheritance to gain some reusability as you should with OOP. You'll find, as you progress, that there are gonna be more and more things you'd like to reuse in your activities -- things more complex than an onClickListener for a FB button -- so it's a great idea to start building a nice, reusable "super" activity that you can inherit from.