ITEEDU

构建无缝的Android程序

不要使你的数据丢失

脑海里面要时刻保持这样一种看法:Android是一个移动的平台。这很明显,但是你也要注意:任何Activity(例如有人给你打电话)在你运行自己Activity的时候都有可能会突然弹出来,这将会调用onSaveInstanceState() 和onPause()方法,很有可能你的进程会终止(kill)。

如果用户正在编辑数据的时候,其他的Activity出现了,你的程序可能因为被终止而丢失一些数据。当然如果你事先保存了就不会丢失。Android的编程思路也是这样做的:那些接受或编辑输入的Android程序应该重载onSaveInstanceState()方法,把程序的当前状态保存下来。当第二次访问该程序的时候,就会使数据复原。

一个使用这的经典例子就是邮件程序。如果用户正在编辑一个信件,这个时候宁外一个Activity出现了,那么程序应该自动的把当前邮件保存到草稿本中。

没有人喜欢看你裸露的数据

你是不能穿着内裤在街上裸奔的,那么你的数据也同样是这样。你的程序有些东西是可能被其他程序访问的,那么这样做就不是很专业了。其他的程序很有可能看不懂那些暴露的原始数据,如果你可以改变数据形式,你的程序就会在这点上比那些不会升级的程序好得多。

Android的处理方法是:创建一个ContentProvider通过一个干净的深思熟虑的可维护的API把你的程序数据暴露给其他应用程序。使用一个ContentProvider就好象嵌入了一个Java的接口到两片代码之间,让它们能够相互交流。这意味着,你可以改变你内部的形式而不用修改ContentProvider暴露的接口,并且这不会影响应用程序的执行。.

不要打断正在说话的用户

如果你的用户正在运行一个程序(例如正在打电话),他肯定不要其他程序干扰。除了需要从当前Activity获得用户输入的Activity外,这就是为什么你应该避免缠身不恰当的Activity。

这就是说,不要从运行在后台的BroadcastReceivers或 Services中调用startActivity() ,这样做会打断任何当前运行的应用程序,就会使用户很不舒服。或许更糟糕的,你的Activity变成了一个“键盘强盗”,它会把一些用户原本准备给前一个Activity的输入截取过来。取决于你的应用程序做了些什么,反正这一般都不是一个好事情。

我们这里没有直接从后台运行Activity,而是使用NotificationManager去设置通告消息。这将会在状态栏中显示,用户有空时就会在能够点击它,看看程序要什么什么东西。

(注意:当你的Activity已经运行在前台,而用户想把当前输入给下一个Activity时,这种方法就不适用了。)

很复杂吗? 交给线程吧

如果你的应用程序有一些代价很大或者需要长时间运行的处理过程时,你应该把它们移到线程里面。这样就避免了弹出ANR对话框,让你的程序能够顺畅的运行。

一般来说,Activity中的所有代码和所有的View类都是运行在相同的线程下面。同时这个线程也会处理用户的输入。例如,用户按下一个按钮,一个按钮消息就会添加到Activity的主线程的消息列表中。这个事件消息需要从列表速度的提取出来处理,如果没有速度的处理掉,几秒钟之后,系统就会认为该应用程序挂起了,就会开始结束进程。

如果你有长时间运行的代码嵌入到你的Activity中,那么在事前处理的过程中会运行该代码,这样就会使事件处理阻塞,这样延缓了你的输入进程,并且导致ANR的产生。为了避免这些,将你的运算放入一个线程里面。点击这查看详情

避免Activity Screen杀手

任何有用的应用程序都会有几个不同的Screen对象。当切换你的用户界面是,确保你可以不受限制的使用Activity。

取决于你的开发背景,你可能认为Activity和Java Applet一样,在那里面它是你的程序入口。即使是这样,但这还不够准确:Applet的子类是Java Applet的唯一程序入口,而Activity只是一个潜在的程序入口之一。主Activity和其他Activity之间唯一的不同就是:在你的Android配置的XML文档中,主Activity有"android.intent.action.MAIN" 这样一项。

因此当你设计你的程序时,把你的程序当做是几个Activity的联合。这样会使你的代码在长期的运行中更容易维护,并且,通过利用Android程序的历史记录和 "backstack"模式,你的程序会更容易编写。

主题扩展

当我们开始观察和感觉用户界面的时候,一些细节作用很大。和他们期待的界面相比,用户会感到很震惊。在设计你的用户界面的时候,你应该尽量的避免使用你自己的方式,取而代之的是使用一个主题。再有必要的时候你能够重载或者扩展你的主题,但是你的主题扩展都要有一个同样的UI基础。如果详细的研究,请点击

Make Being Flexible part of your Resolutions

Different Android-powered devices will sport different resolutions. Some will even be able to change resolutions on the fly, such as by switching to landscape mode. It's important to make sure your layouts and drawables are flexible.

Fortunately, this is very easy to do. Check out Implementing a User Interface for the full details, but in brief what you must do is provide different versions of your artwork (if you use any) for the key resolutions, and then design your layout to accommodate various dimensions. (For example, avoid using hard-coded positions and instead use relative layouts.) If you do that much, the system handles the rest, and your application looks great on any device.

Assume the Network is Slow

Android devices will come with a variety of network-connectivity options. All will have some data-access provision, though some will be faster than others. The lowest common denominator, however, is GPRS, the non-3G data service for GSM networks. Even 3G-capable devices will spend lots of time on non-3G networks, so slow networks will remain a reality for quite a long time to come.

That's why you should always code your applications to minimize network accesses and bandwidth. You can't assume the network is fast, so you should always plan for it to be slow. If your users happen to be on faster networks, then that's great — their experience will only improve. You want to avoid the inverse case though: applications that are usable some of the time, but frustratingly slow the rest based on where the user is at any given moment are likely to be unpopular.

One potential gotcha here is that it's very easy to fall into this trap if you're using the emulator, since the emulator uses your desktop computer's network connection. That's almost guaranteed to be much faster than a cell network, so you'll want to change the settings on the emulator that simulate slower network speeds. You can do this in Eclipse, in the "Emulator Settings" tab of your launch configuration or via a command line option when starting the emulator.

Different Keystrokes for Different Folks

Android will support a variety of handset form-factors. That's a fancy way of saying that some Android devices will have full "QWERTY" keyboards, while others will have 40-key, 12-key, or even other key configurations. Similarly, some devices will have touch-screens, but many won't.

When building your applications, keep that in mind. Don't make assumptions about specific keyboard layouts -- unless, of course, you're really interested in restricting your application so that it can only be used on those devices.

Don't Assault the Battery

A wireless device isn't very wireless if it's constantly plugged into the wall. Handheld devices are battery-powered, and the longer we can make that battery last on a charge, the happier everyone is -- especially the user. Two of the biggest consumers of battery power are the processor, and the radio; that's why it's important to write your applications to do as little work as possible, and use the network as infrequently as possible.

Minimizing the amount of processor time your application uses really comes down to writing efficient code. To minimize the power drain from using the radio, be sure to handle error conditions gracefully, and only fetch what you need. For example, don't constantly retry a network operation if one failed. If it failed once, it's likely because the user has no reception, so it's probably going to fail again if you try right away; all you'll do is waste battery power.

Users are pretty smart: if your program is power-hungry, you can count on them noticing. The only thing you can be sure of at that point is that your program won't stay installed very long.