友盟安卓推送的“多包名”使用方式解決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程序可以正常接收到消息推送啦

友盟文檔對此方法的解釋:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章