2.3 迁移Android工程可能发生的错误
除了要自己编写程序外,还需要阅读大量别人写的程序,或是将其他机器上自己编写的源代码迁移到另一台机上。完成这些工作的第一步就是将工程导入到Eclipse中。如果包含源代码的Android工程在光盘中,建议先将其复制到硬盘上,然后在Eclipse中选择"File" > "Import" 菜单项,打开"Import"对话框,选中"Existing Projects into Workspace"节点,然后单击"Next"按钮,并按提示导入已存在的工程。
虽然导入过程并不复杂,但导入后的程序有可能会出现错误,也就是在工程图标上出现一个红叉。经笔者长时间测试和总结,出现这种情况的原因可能是以下一种或几种。
JDK名字不同。虽然在不同的电脑上都安装和配置了JDK,但在Eclipse中为JDK起的名字可能不同。在Eclipse中配置的JDK可以在"Preferences"对话框中的"Java" > "Installed JREs"节点对应的右侧列表中找到。如果发现和Android工程原来所有的Eclipse中的JDK名字不同,可以在这里修改一下。
引用的jar文件在目标机器上不存在。在Android工程中可能引用了第三方的jar包,而且这些jar包保存在其他目录中。在迁移Android工程时未将这些包也迁移过来。解决的方法很简单,只需要将这些jar文件复制到目标机器上与原机器相同的目录中,或在Android工程中重新引用这些jar文件即可。如果为了以后迁移Android工程更方便,可以直接将这些jar包放到Android工程中。最好不要放在像src、res这些需要同步的目录中,建议在Android工程中建立一个lib目录(也可以建立若干子目录),将所有的jar包都放在lib或其子目录中,然后直接引用工程中的jar包。由于这种引用方式使用了相对目录,因此只要复制了完整的Android工程目录,就绝对不会出现由于jar文件没找到或路径错误的异常情况。
跨工程引用的工程可能包含错误或不存在。在Eclipse中可以跨工程引用。例如,当很多Android工程都需要某个功能时,可以将这个功能单独封装在一个Eclipse工程中(Android和非Android工程都可以)。由于在开发过程中,Android工程和被引用的工程需要同时调试,因此,必须在Android工程中引用另外一个工程。如果我们在迁移Android工程的过程中未复制被引用的工程,那么Android工程就会由于未找到被引用的工程而产生错误,这个错误非常类似于未找到引用的jar文件所产生的错误,只是未找到的是Eclipse工程,而不是jar文件。如果被引用工程也同样复制并导入到了新的Eclipse环境中,Android工程仍然有错误,而Android工程中并未发现任何的出错迹象,可能是由于被引用工程的错误而导致Android工程产生错误。只要消除被引用工程中的错误,Android工程中的错误自然消失。本节介绍的几种可能性仍然可以应用在被引用工程中的错误排除上。
ADT或Android的版本太低。如果目标机器上所安装的ADT或Android的版本太低,例如,要迁移的程序最低的要求是Android SDK 2.2,而目标机器上最高的Android SDK版本只到2.1,则Android工程会发生错误。排除错误的唯一方法就是升级到更高的ADT或Android版本。
Android工程中突然多出了同名的图像文件。这个问题如果遇到了会很郁闷。如果目标机器上没有旧版本的同名Android工程就不可能发生这种情况。但不幸的是,往往在目标机器上会存在同名的旧版本Android工程。例如,我们可能在单位时编写了一个新版本的Android程序,而晚上要将程序拿回家继续做,但家里的电脑中同一个workspace(Eclipse保存工程的目录)中有一个同名的旧版本的Android工程。而且更不幸的是,这个旧版本的Android工程中的图像资源(drawable中的图像文件,将在后面详细介绍)在新版本的Android工程中换了扩展名。例如,旧版本中有一个abc.jpg,在新版本中变成了abc.png。而在粘贴新工程的过程中,并没有在删除旧工程后再粘贴,这时在新工程中就会出现两个同名(文件名相同,扩展名不同)的图像文件:abc.jpg和abc.png。这对于操作系统的文件系统是有效的,但对于Android的ADT却有大麻烦了。因为ADT会为每一个图像资源文件生成一个唯一的ID(静态变量),这个ID就是图像资源文件的文件名(不包括扩展名)。这时就会产生冲突,因为在Java语言中不允许在同一个作用域中包含两个或多个同名的变量。因此,在drawable目录中不允许出现主文件名相同,而扩展名不同的两个或多个文件。解决的方法就是只保留一个这样的文件,其他的全部删除或移到其他的目录中。除了drawable目录中的图像文件可能引起这样的错误,源程序文件或其他资源文件同样可能引起这样的错误。例如,某个旧Android工程的某个Java源文件引用了第三方jar包中的某个类,而在新Android工程中使用了其他的类来代替jar包中的这个类,并且在新的Android工程中已经将这个jar包移除,这时如果在迁移Android工程时仍然保留了这个引用jar包中相应类的Java文件,那么就会出现引用错误。只要Android工程中有任何错误,Android工程图标上就会显示一个红叉。因此,建议在复制新的Android工程之前先将旧Android工程完全删除,这样就不可能发生这样的情况了。
其他情况。如果读者已经将上述几种可能性一一排除后,Android工程仍然有错误,那么情况可能会有些微妙(有的情况可能是由于ADT或是Eclipse的Bug引起的)。读者不妨先选择"Project">"Clean"菜单项来清理一下Android工程,如果还没清除错误,可以将Android工程从"Package Explorer"视图中删除(不要彻底删除,只在工程列表中删除即可),然后再重新导入Android工程。当然,这些操作有可能仍然未解决读者的问题,这样情况就会显得更复杂了。当然,出现这种情况的可能性很小。但如果很不幸这种情况发生在你的身上,可以通过Google或其他搜索引擎来查找答案。只要这个问题你不是世界上第一个遇到的人,总会找到解决方法的。有时可能不是Android工程的问题,而是Google的事。例如,在Android SDK刚升级到2.3时,ADT发布了最新的8.0.0版。这个版本也没有太大问题,但由于笔者的一个项目引用了另一个项目(跨工程引用),可能在这一ADT版本中对跨工程引用支持得不好,使Android工程出现异常。估计是这个Bug引起了全球很多开发人员的关注,Google的反应也比较快,在发布ADT 8.0.0之后不到24小时就发布了ADT 8.0.1,经测试,已经修补了这个Bug。所以读者在遇到这些棘手的问题时,并不需要慌乱,在全世界的开发人员中总会有人捷足先登,最先遇到这个问题。因此,解决方法就在互联网的某处,只需要耐心寻找,总会有所收获。