asynchronous编程最佳实践
我最近写了我的第一个Android应用程序,大约是8000到10000行的代码。 有一件事不断阻碍我使用正常的devise模式,android是大量使用asynchronous调用(打开对话框,活动等)。 由于这个原因,我的代码很快就开始像“意大利面条”一样,最终我开始不喜欢看某些类。
是否有特定的devise模式或编程方法,对于任何人都会推荐的系统? 是否有任何build议编写可pipe理的asynchronous代码?
- 使用全局variables
如果你不想用简单的Intent.putExtra()
调用弄乱你的代码,并为每个独特的Activity
pipe理这些东西,你将不得不在应用程序中使用全局variables。 扩展Application
并存储您需要的数据,只要您的应用程序处于活动状态。 要真正实现它, 使用这个优秀的答案 。 这将使活动之间的依赖关系消失。 例如,假设您在应用程序的生命周期中需要一个“用户名”用于应用程序 – 这是一个很好的工具。 不需要肮脏的Intent.putExtra()
调用。
- 使用样式
制作第一个Android应用程序的一个常见错误是,通常只是开始编写XML视图。 XML文件将(无问题,非常快)走向很多代码行。 在这里,你可以有一个解决scheme,你只是使用style
属性来实现一个特定的行为。 例如,考虑这段代码:
values / styles.xml :
<style name="TitleText"> <item name="android:layout_height">wrap_content</item> <item name="android:layout_width">wrap_content</item> <item name="android:textSize">18sp</item> <item name="android:textColor">#000</item> <item name="android:textStyle">bold</item> </style>
layout / main.xml :
现在,如果你有,两个TextView
和他们两个应该有相同的行为,让他们使用TitleText
风格。 示例代码:
<!--- ... --> <TextView android:id="@+id/textview_one" style="@style/TitleText" /> <TextView android:id="@+id/textview_two" style="@style/TitleText" /> <!--- ... -->
简单,你不需要重复的代码。 如果你真的想进一步看看这个特定的主题,请看看布局技巧:创build可重用的UI组件 。
- 使用string
这一点很短,但我认为提及这一点很重要。 开发人员可能犯的另一个错误是跳过strings.xml,并在代码内部(他将需要它)编写UI消息(和属性名称)。 使您的应用程序更易于维护; 只需在strings.xml文件中定义消息和属性即可。
- 创build并使用全局工具类
当我写我的第一个应用程序时,我只是写了(和重复)的方法,我需要它。 结果? 许多方法在各种活动之间具有相同的行为。 我学到的是做一个工具类。 例如,假设您必须在所有活动中提出Web请求。 在这种情况下,请跳过在实际的Activity
定义它们,并为其创build一个静态方法。 示例代码:
public final class Tools { private Tools() { } public static final void sendData(String url, String user, String pass) { // URLConnections, HttpClients, etc... } }
现在,您可以在需要向服务器发送数据的Activity
中使用以下代码:
Tools.sendData("www.www.www", "user", "pass");
但是,你明白了。 在需要的地方使用这个“模式”,它会阻止你搞乱你的代码。
- 让自定义类定义用户需要与应用程序进行交互的行为
这可能是最有用的一点。 为了定义“ 用户需要与应用程序进行交互的位置 ”,假设您有一个Menu
,该行的行数很长,为什么我们将Menu
的计算放在同一个类中? 每个小项目都会让你的Activity
类变得更加痛苦 – 你的代码看起来像“意大利面条”。 例如,而不是像这样的东西:
@Override public boolean onPrepareOptionsMenu(Menu menu) { MenuItem item; item = menu.findItem(R.id.menu_id_one); if (aBooleanVariable) { item.setEnabled(true); } else { item.setEnabled(false); } // More code... return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem i) { // Code, calculations... // ... // ... return super.onOptionsItemSelected(i); }
重新devise它是这样的:
private MyCustomMenuInstance mMenuInstance; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mMenuInstance = new MyCustomMenuInstance(); } @Override public boolean onPrepareOptionsMenu(Menu menu) { mMenuInstance.onPrepareOptionsMenu(menu); return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem i) { mMenuInstance.onOptionsItemSelected(i); return super.onOptionsItemSelected(i); }
例如, MyCustomMenuInstance
:
public class MyCustomMenuInstance { // Member fields.. public MyCustomMenuInstance() { // Init stuff. } public void onPrepareOptionsMenu(Menu menu) { // Do things.. // Maybe you want to modify a variable in the Activity // class? Well, pass an instance as an argument and create // a method for it in your Activity class. } public void onOptionsItemSelected(MenuItem i) { // Do things.. // Maybe you want to modify a variable in the Activity // class? Well, pass an instance as an argument and create // a method for it in your Activity class. } }
你看看这是怎么回事 你可以把这个应用到很多东西上,比如onClick
, onClickListener
, onCreateOptionsMenu
,这个列表很长。 要了解更多“最佳实践”,您可以在这里看到来自Google的一些示例应用程序。 看看他们是如何以一种很好和正确的方式实现的。
遗言; 保持你的代码干净,以合理的方式命名你的variables和方法,特别是以正确的方式。 总是要明白自己在代码中的位置 – 这非常重要。
从业余的angular度来看,我不希望我的第一个尝试成为一个干净的,生产就绪的应用程序。 有时候我会吃意大利面,fettucini,甚至馄饨码。 在那个时候,我尝试重新思考我最不喜欢的代码是什么,并寻找一个更好的select:
- 重新思考你的课堂,以更好地描述你的对象,
- 保持每个方法中的代码最小化,
- 尽可能避免依赖于静态variables,
- 使用线程进行昂贵的任务,不要使用它们进行快速的程序,
- 将UI从应用程序逻辑中分离出来(保留在你的类中)
- 保持私人领域的任何地方你可以:这将有助于当你想改变你的class级,
- 遍历这些直到你喜欢的代码
我在asynchronous方法中看到的最常见的错误之一是在循环内部使用静态variables来创build一个或多个线程,而不考虑在另一个线程中该值可能会更改。 避免静态!
正如OceanBlue所指出的,由此可能并不清楚, final static
variables不会产生任何危险,而是可以改变的公共静态variables。 静力学本身并不是一个问题,而是有一个概念,即它们会有一个价值,然后发现价值已经改变了。 可能很难找出问题所在。 典型的例子是一个点击计数器或一个计时器的值,当可能有多个视图点击或多个计时器。
希望你会收到比我有更多经验的人的build议。 祝你好运!
如果处理用户界面是您最关心的问题,那么您将需要掌握事件驱动的编码。 事件驱动编码背后的思想是所有现代UI系统的背后,对于各种事物(不仅仅是UI)都是有用的。
学习时最简单的方法就是将每个组件和事件视为独立。 所有你需要担心的是事件对象传入你的事件方法。 如果你习惯于编写基本上从头到尾运行的应用程序,这是一个思维转变,但实践会让你很快。
怎么样使用模型视图控制器模式?
至less你必须在“模型”(对象或对象集合)中隔离所有的状态和逻辑pipe理,并且在一个单独的类(也许是Activity类)中包含所有与视图,侦听器,callback, …)