alibaba / freeline

A super fast build tool for Android, an alternative to Instant Run
https://www.freelinebuild.com/
BSD 3-Clause "New" or "Revised" License
5.48k stars 623 forks source link

[兼容性问题] 使用 animated-vector 或者 design-support 25.1.+ 遇见 public symbol drawable/xxxx_1 declared here is not defined #539

Closed lomanyong closed 6 years ago

lomanyong commented 7 years ago

现象

典型的现象,使用了compile 'com.android.support:design:25.1.0',全量编译后,增量编译资源时出现错误提示:

xxx/app/build/freeline/app/backup/res/values/freeline_id_keeper_public.xml:1709: error: Public symbol drawable/avd_hide_password_1 declared here is not defined.
xxx/app/build/freeline/app/backup/res/values/freeline_id_keeper_public.xml:1711: error: Public symbol drawable/avd_hide_password_2 declared here is not defined.
xxx/app/build/freeline/app/backup/res/values/freeline_id_keeper_public.xml:1713: error: Public symbol drawable/avd_hide_password_3 declared here is not defined.
xxx/app/build/freeline/app/backup/res/values/freeline_id_keeper_public.xml:1715: error: Public symbol drawable/avd_show_password_1 declared here is not defined.
xxx/app/build/freeline/app/backup/res/values/freeline_id_keeper_public.xml:1717: error: Public symbol drawable/avd_show_password_2 declared here is not defined.
xxx/app/build/freeline/app/backup/res/values/freeline_id_keeper_public.xml:1719: error: Public symbol drawable/avd_show_password_3 declared here is not defined.

原因

经过查阅 aapt 源码会发现出错的原因:

/**
 * Detects use of the `bundle' format and extracts nested resources into their own top level
 * resources. The bundle format looks like this:
 *
 * <!-- res/drawable/bundle.xml -->
 * <animated-vector xmlns:aapt="http://schemas.android.com/aapt">
 *   <aapt:attr name="android:drawable">
 *     <vector android:width="60dp"
 *             android:height="60dp">
 *       <path android:name="v"
 *             android:fillColor="#000000"
 *             android:pathData="M300,70 l 0,-70 70,..." />
 *     </vector>
 *   </aapt:attr>
 * </animated-vector>
 *
 * When AAPT sees the <aapt:attr> tag, it will extract its single element and its children
 * into a new high-level resource, assigning it a name and ID. Then value of the `name`
 * attribute must be a resource attribute. That resource attribute is inserted into the parent
 * with the reference to the extracted resource as the value.
 *
 * <!-- res/drawable/bundle.xml -->
 * <animated-vector android:drawable="@drawable/bundle_1.xml">
 * </animated-vector>
 *
 * <!-- res/drawable/bundle_1.xml -->
 * <vector android:width="60dp"
 *         android:height="60dp">
 *   <path android:name="v"
 *         android:fillColor="#000000"
 *         android:pathData="M300,70 l 0,-70 70,..." />
 * </vector>
 */

animated-vector 是一个混合的资源 bundle,会在 aapt 编译的处理期间被抽离分解,生成类似 bundle_1.xml、bundle_2.xml 的资源,且 id 会加入 resource table 中,但是没有实际的生成产物出来,导致在增量编译的时候如果没有将 animated-vector 资源加入编译的话,就会出现上面所说的编译出错日志。

这个并不是配置资源路径的问题,是一个特殊 case,已经解决。

解决方案

升级 gradle 插件版本:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.antfortune.freeline:gradle:0.8.5'
    }
}

更新 Freeline:

Windows: gradlew initFreeline -Pmirror
Linux/Mac: ./gradlew initFreeline -Pmirror

重新编译即可解决。

目前,Windows 暂时还未解决。

遇见类似问题的相关 issue:#503 与 #507

lomanyong commented 7 years ago

已 fix,有需要的可以先按上面所述方式进行优先体验。

r17171709 commented 7 years ago

win上面是不是还没有修复,我看mac可以解决,但是win上面还是不行的

lomanyong commented 7 years ago

@r17171709 win上还是提示同样的错误日志?你可以执行一下freeline/release-tools/FreelineAapt.exe v看下版本信息吗?

loongwind commented 7 years ago

@lomanyong win 0.8.6版本还是会出现这个问题: xxx\build\freeline\assemble\backup\res\values\freeline_id_keeper_public.xml:2715: error: Public symbol drawable/avd_hide_password_1 declared here is not defined. xxx\build\freeline\assemble\backup\res\values\freeline_id_keeper_public.xml:2717: error: Public symbol drawable/avd_hide_password_2 declared here is not defined. xxx\build\freeline\assemble\backup\res\values\freeline_id_keeper_public.xml:2719: error: Public symbol drawable/avd_hide_password_3 declared here is not defined. xxx\build\freeline\assemble\backup\res\values\freeline_id_keeper_public.xml:2721: error: Public symbol drawable/avd_show_password_1 declared here is not defined. xxx\build\freeline\assemble\backup\res\values\freeline_id_keeper_public.xml:2723: error: Public symbol drawable/avd_show_password_2 declared here is not defined. xxx\build\freeline\assemble\backup\res\values\freeline_id_keeper_public.xml:2725: error: Public symbol drawable/avd_show_password_3 declared here is not defined.

javaczhang commented 7 years ago

我用的windows,都不敢加design包,一直在静候佳音

lomanyong commented 7 years ago

@javaczhang @ch331917692 抱歉...windows因为aapt出问题,暂时未部署,目前解决的是linux/mac版本的问题。

@javaczhang design包可以暂时用低版本的,如果高版本需求不大的话...

bq1122 commented 7 years ago

win下有什么办法可以绕开这个兼容性的问题.继续使用吗

lomanyong commented 7 years ago

@bq1122 暂时降低design包的版本,如果没有特殊需求的话

wziwen commented 7 years ago

经过大半天的查找(和脑洞?), 终于找到一个Win上可以跳过这个问题, 实现resource的方法.

  1. 在项目的values文件下建立一个drawable.xml文件
  2. drawable.xml内部添加代码:
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <drawable name="avd_show_password_1">#ffffffff</drawable>
    <drawable name="avd_show_password_2">#ffffffff</drawable>
    <drawable name="avd_show_password_3">#ffffffff</drawable>
    <drawable name="avd_hide_password_1">#ffffffff</drawable>
    <drawable name="avd_hide_password_2">#ffffffff</drawable>
    <drawable name="avd_hide_password_3">#ffffffff</drawable>
    </resources>
  3. 重新打包(clean build):
    python freeline.py -f
  4. 修改layout文件, 打增量包:
    python freeline.py

可能存在问题: 第一次执行时发现除了了图片资源的错位(要显示的A.png, 打增量包后界面上显示B.png(不是自己修改的). 发现可能是改了freeline_core文件下面相关的脚本. 删除freeline和freeline_core文件夹后重新执行 gradlew initFreeline 后问题解决

RockyQu commented 7 years ago

@lomanyong design包的版本最高支持多少?

XiaoSeee commented 7 years ago

这个问题有计划解决吗?

wenwenwen888 commented 7 years ago

+1windows出现了

lvtanxi commented 7 years ago

+1windows出现了 0.8.7上也是出现这个问题

luckbing commented 6 years ago

windows下的freeline0.8.8版还是会报这个错,要绕过这个问题,design.support要降到多少