App ID 还是 Package Name

 

App ID 还是 Package Name

android 项目有两个属性:application id 和 package name,很多人以为是一样的东西,其实有区别。

appliciation id 用于在市场和手机里标识应用,同样 app id 的应用在市场只能有一份,在手机里只能有一个,这也是通常对 app id 的正常理解。

package name 指的是在 manifest文件里指定的package 值:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.company.packagename">  
    ...

package name 用于生成R文件,如果这个值和 appid 不一致,R 文件的包名以 package name 为准:

import com.company.packagename.R;  
...  

针对于使用 android studio 打包来说:

  1. 多个flavor之间appid可以不一致(在gradle里配置)。
  2. 如果一个 flavor 有多个 manifest,这几个manifest 的 package name 必须一致。
    常见的情况就是:多个 flavor 有共享的主 manifest,那么主 manifest 的package name 就是所有包的 package name,子manifest 不应该设置package name,即使要设置也必须跟主manifest 保持一致(所以推荐子manifest里就不要设置)。
  3. 这样设计的优点是:app id 和 package name 解耦,多个flavor修改app id时不需要修改代码(R文件包名)去配合包名修改,代码里引用R文件时,永远只有一个固定的包。
  4. 如果打包成库给别人用,因为每个库有自己的manifest,所以只要在自己代码里引用自己的package name就好了。
  5. 如果一定要在 flavor 之间使用不同的 package name ,只能每个flavor单独配置 manifest 文件了。 或者每次打包只打一个flavor,打包之前按照所选的flavor手动修改package name。

但是 安卓一如既往的预留了各种惊(da)喜(keng):
坑1:context.getPackageName() 返回的是 app id ! app id !!
所以如果用 context.getPackageName() + 反射去调用R文件,是可能找不到的!可能找不到的!!
找不到就发生在 app id 和 package name 不一致的时候

坑2:如果你没有在 gradle 里单独设置 app id,AS会在打包时候用 package name 作为 app id,但是参考优点第三条,这样做是不推荐的。
但是 如果你设置了app id,AS打包时候就会用appid修改manifest 里的 package name,之后再拆包看到的 package name 实际上是 app id,此时貌似没有任何办法得知实际上的 package name,也就无法通过反射动态引用R文件。