友盟安卓推送的“多包名”使用方式解决R文件报错问题

前言:App开发者为什么会有多包名的需求?
  • 首先我们先来说说包名(一般是http://com.company.xxx的形式),包名这个概念是出现在Android生态系统里面的,对于Android系统来说,包名是App的唯一标识。这个对技术人员来说很好理解,对于非技术人员,稍微再啰嗦一下: 如果两个安卓App,A和B包名一样的话,如果先安装A,再安装B,那么会出现B覆盖A的情况,最终只会是B会安装在系统上,即使这是两个完全不同的App。其实在安卓设备上一个App的升级过程就是包名相同,覆盖安装的例子。
  • 接着我们来聊聊多包名的需求,对于一些游戏App来说,如果他们要和市场渠道(诸如91,安智、豌豆荚,360等)做联运的话,那么就必须得使用不同的包名来做区分了,这个其实也是渠道强制要求的,因为这要涉及到最终的流量推广、下载结算等。感兴趣的读者可以看一下我之前回答过的一个问题: 为什么有的安卓App在不同市场渠道发版的时候使用不同的包名呢? - 沙漠的回答, 解释的比较详细。这种场景占绝大多数,所以我们网站的用户引导语也说得是“若一个APP针对不同渠道有不同的包名,则可通过开通多包名支持一个appkey对应多个包名发送消息
  • 最后,再补充一种小众的需求,这种场景不是太常见,但是和我们在下文提出的友盟推送提供“多包名”关系比较大,所以还是提一下。有些App是系列App,比如小说类的,或者明星类App。开发者在开发这些App的时候其实是有一个代码模板的,大部分时候只需要改改App的Icon,Name等就可以生成一个新的App,但是既然是不同的App,那么包名部分还是要去变换一下的(包名是安卓系统上对App的唯一标识)。这种场景大多出现在一些外包类的公司里面。

我们公司的项目是因为后期开发的第二个项目完全包含于之前的一个项目,所以就是两个项目是融合在一起的,这样我们只在build.gradle里配置不同的applicationId就可以打出不同的包了。我们这里简称为项目a(为被包含的项目),项目b

 productFlavors {
        a{
            versionCode 100
            versionName "1.0.0"
            //无需变更信息 
            applicationId "com.test.a"
            manifestPlaceholders = [
                    app_lable: "@string/app_name",
                    app_logo: "@drawable/logo",
                    welcome_splash: "@style/AppSplash",
                    key_weixin: "",
                    key_amap: "",
                    umeng_app_key: "a项目对应友盟的key",
                    umeng_message_secret: "a项目对应友盟推送的key",
            ]
        }
        b{
            versionCode 100
            versionName "1.0.0"
            //无需变更信息
            applicationId "com.test.a.b"
            manifestPlaceholders = [
                    app_lable: "@string/app_name_insurance",
                    app_logo: "@drawable/logo_insurance",
                    welcome_splash: "@style/AppSplashInsurance",
                    key_weixin: "",
                    key_amap: "",
                    umeng_app_key: "b项目对应友盟的key",
                    umeng_message_secret: "b项目对应的友盟推送的key",
            ]
        }
    }

但是测试的时候就会发现,a项目可以正常接收推送,但是b项目没有反应。打印日志会发现友盟找不到资源文件的错误。
经过阅读友盟的集成文档注意到

3.2.5  配置build.gralde

  1. 在Application Module的build.gradle文件的dependencies下添加compile project(':PushSDK')
  2. 请确保Application Module的build.gradle文件中的applicationId与应用包名package一致。
appliactionId与引用的package要一致,然后注意到 项目中的package的名字是com.test.a

之后在运行程序的时候打印package的名字会发现在打包的时候 package的名字已经根据applicationId变成对应的package的名字。
也就是applicationId:com.test.a 的package就是 com.test.a
applicationId:com.test.a.b 的package就是 com.test.a.b 
那么友盟特意强调名字一致一定是有道理的。http://bbs.umeng.com/thread-9613-1-1.html

里面也有人问相同的问题。友盟解释为:
在Android Studio的Gradle构建系统中,applicationId是设备上的这个应用程序的唯一标识,也是在Google Play上的唯一标识,package是用来引用R类的。Android Studio这样做对多渠道打包提供了很好的支持。如果你用到了多渠道打包,那么你需要在推送初始化的时候自定义资源包名,mPushAgent.setResourcePackageName(String packageName),保证你的代码是通过package来引用R类的。

之后我便在程序启动友盟的地方加了以下操作:

  mPushAgent.setResourcePackageName("com.test.a");

之后测试b程序可以正常接收到消息推送啦

友盟文档对此方法的解释:

友盟安卓推送的“多包名”使用方式解决R文件报错问题_第1张图片

你可能感兴趣的:(友盟安卓推送的“多包名”使用方式解决R文件报错问题)