App工程从Eclipse迁移到Android Studio的问题总结

2019-01-18 15:17:31 浏览数 (1)

这段时间把一个App工程从原来的ADT环境(即Eclipse)迁移到Android Studio环境,发现并处理了一系列迁移问题,兹记录如下。把ADT工程迁移到AS,通常的做法是打开Android Studio,依次选择菜单“File”——“New”——“Import Module”,然后点击窗口右边的浏览按钮选择ADT工程的路径,点击“Finish”按钮,等待Android Studio识别并导入ADT工程。一般导入成功的话,接下来便能按照正常操作步骤来编译和运行了;可是老大难的旧工程往往会产生这样那样的错误,需要逐一进行格式转换或者配置调整工作。

转换代码文件格式

注意Android Studio对文件格式的校验要比Eclipse严格,不符合AS要求的文件格式将导致编译错误,下面是两种常见的问题格式: 1、JAVA代码文件为ASCII编码,编译时报错,提示“File is loaded in the wrong encoding: 'UTF-8'” 解决办法:打开Windows的记事本,把该文件另存为UTF8编码的格式。 2、JAVA代码的文件格式是“UTF带BOM”,编译时报错“Error:(1, 1) 错误: 非法字符: 'ufeff'”。编译jni代码的mk文件,如果文件格式是“UTF带BOM”,就无法正常编译jni代码。 解决办法:使用UEStudio等文本编辑软件,把文件另存为“UTF无BOM”的格式。

优化运行配置文件AndroidManifest.xml

1、要去掉重复的权限声明,否则编译时提示警告“duplicated with element declared at AndroidManifest.xml” 2、去掉不存在的组件声明,包括activity、service、receiver等等,否则编译时报错“Unresolved class ***”

适配Gradle与SDK版本

1、关于minSdkVersion

最低支持的SDK版本为9,如果minSdkVersion小于9,则编译时报错“uses-sdk:minSdkVersion 8 cannot be smaller than version 9 declared in library [com.android.support:appcompat-v7:25.2.0]”

2、关于compileSdkVersion

如果代码用到了httpclient库(如微信支付),则编译会报错“程序包org.apache.http.client不存在”。此时需要修改build.gradle,在该文件的dependencies节点下增加以下依赖库:

代码语言:javascript复制
    compile 'org.apache.httpcomponents:httpcore:4.4.1'
    compile 'org.apache.httpcomponents:httpclient:4.5'

如果SDK的编译版本compileSdkVersion大于等于23,则因为6.0以上(含6.0)的SDK不再包含httpclient库,故而还要在android节点补充下面一行:

代码语言:javascript复制
    useLibrary 'org.apache.http.legacy'

3、关于buildToolsVersion

注意Gradle版本与编译工具版本号buildToolsVersion的对应关系,比如Gradle3.2要求的最低编译版本号为19.1.0,否则编译器会报错“Error:The SDK Build Tools revision (18.1.1) is too low for project ':app'. Minimum required is 19.1.0”。而Gradle3.3要求的最低编译版本号为25.0.0,否则编译器会报错“Error:The SDK Build Tools revision (19.1.0) is too low for project ':app'. Minimum required is 25.0.0” Gradle版本与编译工具版本号对应关系表如下:

Gradle版本

Gradle库的路径

编译工具的最小支持版本号

3.2

classpath com.android.tools.build:gradle:2.2.3

buildToolsVersion "19.1.0"

3.3

classpath com.android.tools.build:gradle:2.3.0

buildToolsVersion "25.0.0"

修改代码与SDK提供的API保持一致

1、有的类和函数在Android5.0之后才提供,个别迟至Android6.0之后才提供,此时要注意在代码中增加对Build.VERSION.SDK_INIT的版本号判断。具体的新增类参见博文《Android5.0和6.0之后新增的控件说明》。 2、Android6.0之后取消了部分类和函数,所以如果compileSdkVersion和buildToolsVersion大于等于23的话,需要把已取消的类和函数按建议修改代码。举例如下: a. Android6.0之后取消FloatMath类,相关代码需要使用Math代替; b. Android6.0之后Notification取消了setLatestEventInfo方法,此时需要使用Notification.Builder来构造通知内容;

解决合并依赖库打包的问题

1、关于重复引用jar包或依赖库的问题

如果发现打包时报错“com.android.dex.DexException: Multiple dex files define Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompatIcs;”,则表示库工程与主工程同时引用了support-v4包,此时要采取以下措施: a. 删除库工程与主工程两个libs目录下的android-support-v4.jar b. 修改库工程的build.gradle,在dependencies下增加以下依赖库:

代码语言:javascript复制
    compile 'com.android.support:appcompat-v7:21.0.3'

c. 修改主工程的build.gradle,在dependencies节点下增加依赖库(注意把compile改为provided,表示这个库已经提供了):

代码语言:javascript复制
    provided 'com.android.support:appcompat-v7:21.0.3'

之所以不在库工程添加v4库的依赖“compile 'com.android.support:support-v4:21.0.3'”,是因为appcompat-v7库默认包含了v4库。所以如果库工程添加v4库,而主工程添加appcompat-v7库,则打包时依然报错(v7库自带的v4库与库工程添加的v4库冲突了)。

2、关于方法数超出64K上限的问题

如果发现打包时报错“Error:The number of method references in a .dex file cannot exceed 64K.”,则表示这个App工程包括所有jar在内的方法总数太多了,超过了一个dex文件允许的65536上限个数。因此必须拆分打包生成的dex文件,把一个文件拆为两个甚至更多,以规避65536个数的限制,主要步骤如下: a. 修改主工程的build.gradle,在dependencies节点下增加多dex支持的依赖库:

代码语言:javascript复制
    compile 'com.android.support:multidex:1.0.1'

b. 修改主工程的build.gradle,在“android”——“defaultConfig”节点下补充一行“multiDexEnabled = true”,具体结构如下:

代码语言:javascript复制
android {
   defaultConfig {
       ...
       multiDexEnabled = true
   }
}

c. 自定义的Application类从原来的继承Application类改为继承MultiDexApplication类,并增加下面代码:

代码语言:javascript复制
     @Override
     protected void attachBaseContext(Context base) {
          super.attachBaseContext(base);
          MultiDex.install(this);
     }

如果没有自定义Application,则修改AndroidManifest.xml,增加android:name的属性声明,举例如下:

代码语言:javascript复制
     <application
         ...
         android:name="android.support.multidex.MultiDexApplication">
         ...
     </application>

3、关于JAVA堆内存溢出的问题

如果发现打包时报错“Error:java.lang.OutOfMemoryError: GC overhead limit exceeded”,则表示当前默认的java堆太小了,需要增大这个堆容量的上限。此时需要修改主工程的build.gradle,在android节点下面增加如下配置:

代码语言:javascript复制
    dexOptions {
//        incremental true // 编译提示这个属性已经废弃,因此可不加这句
        javaMaxHeapSize "4g" //关键是这句增大容量的上限
        preDexLibraries = false //delete the already predexed libraries
    }

0 人点赞