阿里雲移動研發平台體驗報告

今天,我們來聊聊移動端原生開發。本篇文章涉及Android/iOS兩大移動端,將從產品優勢和使用方式兩大角度解讀阿里雲移動研發平台(EMAS)。

一、產品優勢

阿里雲平台所提供的移動研發平台,英文簡稱為EMAS,意為Enterprise Mobile Application Studio。從名稱上看,該能力有企業級的運行承載能力。官網上對其定義描述如下:

移動研發平台(Enterprise Mobile Application Studio,簡稱EMAS),面向企業服務市場,期望把阿里巴巴近十年在移動互聯網行業沉澱的DevOps研發支撐能力、移動APP基礎中間件能力開放給客戶,幫助傳統企業快速完成業務移動化的轉型升級目標。

我自己體驗後,得到的結論是:和傳統移動開發產品相比,該平台可以使企業級移動客戶端的開發過程大大簡化。我們先來看看它到底都能做些什麼吧。
EMAS主要能力有以下七個:

  • 移動推送
    在實現高效、精確、實時的移動推送的同時,極大地降低了開發成本。

  • HTTPDNS
    面向移動開發者推出的一款域名解析產品,具有域名防劫持、精準調度的特性。

  • 移動熱修復
    阿里巴巴首創Hotpatch技術,提供細粒度熱修復能力,無需等待,實時修復應用線上問題。

  • 移動測試
    幫助客戶發現APP中的各類隱患,減少用戶流失,提高APP品質和市場競爭力。

  • 移動數據分析
    移動開發者實現基於大數據技術的精細化運營、提升產品品質和體驗、增強用戶黏性。

  • 移動用戶回饋
    可以快速發送文字、圖片、語音進行意見回饋和報告Bug。

  • 移動崩潰分析
    將Android和iOS平台常見APP的崩潰問題進行歸類分析,幫助企業快速發現定位問題。

看到這,您可能會有疑問:現有的產品已經有這些能力了,比如友盟可以做推送和用戶分析,騰訊Bugly可以做崩潰回饋……
可是,集成多個SDK勢必造成產品安裝包大小的增加,不同平台在實際使用時也較為分散,寫程式碼的程式設計師的工作量也會隨之增加……這其實都還是次要的。
下面從移動推送能力為切入視角,我們做一次平台間的對比。首先來看極光推送。

可以看到,相較免費版,不僅無法享受廠商通道,而且推送次數被限制在一天10條內。
再來看騰訊的信鴿推送,和極光推送類似地,廠商通道也只有付費版才可以享受,免費試用將會受到如下圖所示的限制:

最後,我們來看看EMAS的收費標準:

  • 對於免費的用戶:

注意:這裡說的是每個月,對於每個App去重設備數小於5萬台的情況,都是免費使用的。

  • 對於收費用戶,預付費和後付費兩種方式,具體如下:

再說產品功能,獨有的簡訊補發特性可以在推送無法到達時,切換為簡訊下發,進一步確保消息送達。此外,集成EMAS推送能力的App將和阿里系的App共享推送通道。無需新啟動常駐記憶體進程,只要淘寶、天貓能收到消息,我們的App就也可以正常收到推送。不僅保證了消息送達率,還優化了App的記憶體佔用率。
最後,由於EMAS不僅有移動推送的能力,還涵蓋了前文中提到的諸多能力,從集成方式上看,可以說是一次集成,能力全能。解放開發者的同時減少App安裝包大小。
下面,我們就來看看怎樣集成EMAS能力。

二、集成EMAS

集成EMAS的方法非常簡單,在阿里雲控制台添加產品後,根據指導可以下載一個名為aliyun-emas-services.json的文本文件,這個文件中包含了各種能力的使能開關和appKey等配置資訊,其片段如下所示:

{
  "config": {
	"emas.appKey":"xxxxxx",
	"emas.appSecret":"xxxxxx",
	"emas.packageName":"com.example.demo",
	"hotfix.idSecret":"xxxxxx",
	"hotfix.rsaSecret":"xxxxxx",
	"httpdns.accountId":"xxxxxx",
	"httpdns.secretKey":"xxxxxx",
	"appmonitor.tlog.rsaSecret":"xxxxxx"
},
  "services": {
	"hotfix_service":{
		"status":1,
		"version":"3.2.14"
	},
	"ha-adapter_service":{
		"status":1,
		"version":"1.1.3.2-open"
	},
	"feedback_service":{
		"status":1,
		"version":"3.3.1"
	},
...

傳統集成方式中,AndroidManifest.xml中的各種meta標籤數據現在改由這個json文件配置,且各種key是自動填好的,下載後就能直接用,一般不用做任何修改;下面的services節點是每個能力的開關,當status為1時為啟用相應的能力,言簡意賅。
接著,創建一個繼承自Application類的Java類,對要使用的能力進行初始化。這一步驟需要查閱相應的能力的產品文檔。比如,我們要集成推送能力,相應程式碼如下:

private void initPushService(final Context applicationContext) {
    PushServiceFactory.init(applicationContext);
    final CloudPushService pushService = PushServiceFactory.getCloudPushService();
    pushService.register(applicationContext, new CommonCallback() {
        @Override
        public void onSuccess(String response) {
            Log.d(TAG, "初始化推送能力成功");
        }

        @Override
        public void onFailed(String errorCode, String errorMessage) {
            Log.d(TAG, "初始化推送能力失敗,錯誤碼:" + errorCode + ",詳細資訊:" + errorMessage);
        }
    });
}

接著,在創建一個繼承自MessageReceiver類的Java類,用於處理收到的推送消息。這裡我們將這個類命名為EmacReceiver.java,完整程式碼如下:

public class EmacReceiver extends MessageReceiver {

    public static final String TAG = EmacReceiver.class.getName();

    @Override
    public void onNotification(Context context, String title, String summary, Map<String, String> extraMap) {

        Log.d(TAG, "Receive notification, title: " + title + ", summary: " + summary + ", extraMap: " + extraMap);
    }

    @Override
    public void onMessage(Context context, CPushMessage cPushMessage) {
        Log.d(TAG, "onMessage, messageId: " + cPushMessage.getMessageId() + ", title: " + cPushMessage.getTitle() + ", content:" + cPushMessage.getContent());
    }

    @Override
    public void onNotificationOpened(Context context, String title, String summary, String extraMap) {
        Log.d(TAG, "onNotificationOpened, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap);
    }

    @Override
    protected void onNotificationClickedWithNoAction(Context context, String title, String summary, String extraMap) {
        Log.d(TAG, "onNotificationClickedWithNoAction, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap);
    }

    @Override
    protected void onNotificationReceivedInApp(Context context, String title, String summary, Map<String, String> extraMap, int openType, String openActivity, String openUrl) {
        Log.d(TAG, "onNotificationReceivedInApp, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap + ", openType:" + openType + ", openActivity:" + openActivity + ", openUrl:" + openUrl);
    }

    @Override
    protected void onNotificationRemoved(Context context, String messageId) {
        Log.d(TAG, "onNotificationRemoved");
    }
}

最後,在AndroidManifest.xml中聲明這個Receiver即可:

<receiver
    android:name=".EmacReceiver"
    android:exported="false"> 
    <intent-filter>
        <action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" />
    </intent-filter>
    <intent-filter>
        <action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED" />
    </intent-filter>
    <intent-filter>
        <action android:name="com.alibaba.sdk.android.push.RECEIVE" />
    </intent-filter>
</receiver>

到此,設備就可以正常收到消息了。當然,我們還可以進一步配置,以便支援各廠商自有推送通道。這裡就不再贅述了,具體請各位移步阿里雲EMAS官網查看文檔。官網鏈接://www.aliyun.com/product/emas

文章的最後,放一張EMAS的產品架構全圖(其中的某些功能將在未來逐步可用)。
EMAS產品架構