Asynchronous programming best practices
我最近写了我的第一个Android应用程序,大约有8000-10000行代码。有一件事一直阻碍我使用正常的设计模式,那就是Android大量使用异步调用(打开对话框、活动等)。由于这个原因,我的代码很快开始看起来像"意大利面",我最终开始不喜欢看某些课程。
是否有特定的设计模式或编程方法适用于任何人都会推荐的系统?对于编写可管理的异步代码有什么建议吗?
- 使用全局变量
如果您不想用简单的
- 使用风格
在制作第一个Android应用程序时,一个常见的错误是通常只需开始编写XML视图。XML文件将(毫无问题且速度非常快)扩展到非常多的代码行。在这里,您可以有一个解决方案,您只需使用
值/样式.xml:
1 2 3 4 5 6 7 | <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> |
布局/main.xml:
现在,如果你有两个
1 2 3 4 5 6 7 8 9 10 11 | <!--- ... --> <TextView android:id="@+id/textview_one" style="@style/TitleText" /> <TextView android:id="@+id/textview_two" style="@style/TitleText" /> <!--- ... --> |
简单,不需要重复代码。如果您真的想进一步了解这个特定主题,请看一下布局技巧:创建可重用的UI组件。
- 使用字符串
这一点很简短,但我认为提及这一点很重要。开发人员可能会犯的另一个错误是跳过strings.xml,只在代码中编写UI消息(和属性名)(在他需要的地方)。为了使应用程序更易于维护,只需在strings.xml文件中定义消息和属性。
- 创建和使用全局工具类
当我编写第一个应用程序时,我只是在需要的地方编写(和复制)方法。结果如何?许多方法在不同的活动之间具有相同的行为。我学到的是做一个工具班。例如,假设您必须在所有活动中发出Web请求。在这种情况下,跳过在实际的
1 2 3 4 5 6 7 8 9 10 11 |
现在,您只需在需要向服务器发送数据的
1 | Tools.sendData("www.www.www","user","pass"); |
不过,你明白了。在你需要的地方使用这个"模式",它可以防止你弄乱你的代码。
- 让自定义类定义用户需要与应用程序交互的行为
这可能是最有用的一点。为了定义"用户需要在哪里与您的应用程序交互",假设您有一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | @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); } |
重新设计成这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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); } |
例如,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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. } } |
你看这是怎么回事。你可以把这个应用到很多事情上,比如
最后一句话:保持代码的整洁,以逻辑的方式命名变量和方法,尤其是以正确的方式。始终,始终理解代码中的位置-这非常重要。
从一个业余的角度来看,我不希望我的第一次尝试是一个干净的,生产就绪的应用程序。有时我会吃意大利面,意大利肉饼甚至意大利饺子。在这一点上,我试图重新思考我最不喜欢的代码是什么,并寻找更好的替代方案:
- 重新考虑类以更好地描述对象,
- 将每个方法中的代码保持在最低限度,
- 尽可能避免依赖于静态变量,
- 将线程用于昂贵的任务,不要将其用于快速过程,
- 将UI与应用程序逻辑分离(将其保留在类中)。
- 尽可能保留私有字段:当您想更改类时,这将很有帮助,
- 重复这些代码,直到您喜欢代码为止
我在异步方法中看到的最常见的错误之一是在创建一个或多个线程的循环中使用静态变量,而不考虑值可能在另一个线程中更改。避免静力学!
正如OceanBlue指出的那样,从这一点上可能不清楚
希望你能从比我经验丰富的人那里得到建议。祝你好运!
如果处理UI是您最大的问题,那么您将需要掌握事件驱动的编码。事件驱动编码背后的思想是所有现代用户界面系统的背后,并且在各种各样的事情中都很有用(不仅仅是用户界面)。
当我学习的时候,最简单的方法就是把每一个组件和事件当作是独立的。您只需要担心传递到事件方法中的事件对象。如果你习惯于编写基本上从头到尾都在运行的应用程序,这是一个有点思想上的转变,但是实践会很快让你达到目的。
使用模型视图控制器模式怎么样?
至少你必须在"模型"中隔离(对象或对象集)所有的状态及其逻辑管理一个单独的班级(可能是活动班)所有与视图、侦听器、回调等相关的内容)