JBoss 的推播方案 - Unified Push Server(現在叫 AeroGearPush)

前言

2016年獨立開發者最慘痛的第一個消息,大概就是臉書併購的 Parse 要收起來不玩了,我手上的專案用到 Parse 的推播功能也中鏢了,想到要自己把 GCM 接起來真的是一個頭兩個大。

簡單說明一下 Parse 是一個 BaaS(Back end as Service) 服務,可以想成臉書幫你養了一台提供資料庫/會員註冊/排程工作/推播的雲端主機,對開發者來說省去了架設/部署的工作,能夠專注於開發。

Parse 預計明年一月要收掉,整個 Parse 也已經開源出來,如果你本身也熟悉 Node.js 的開發生態,基本上可以整包拿下來架站。我最終選擇是改用 JBoss 提供的推播方案,下文大概介紹一下架構、功能,詳細實作的程式碼因為會隨著改版而失效,這邊就不會寫上程式碼。

JBoss Unified Push 架構

JBoss 的推播方案一開始叫做 Unified Push,現在就整進 AeroGearPush 裡頭(算是其中一個子專案),整個程式碼也有開源出來,其實是一個跑在 JAVA EE Server 上的 war 檔。

因為我只有實作 Android Push 這一塊,以下就用 GCM 為例說明。Push Server 封裝了 GCM,如果沒有 Push Server,我們就必須自己去管理手機從 GCM 取得的註冊資訊。當有跨手機平台的推播需求的話,我們也只需與 Push Server 介接,Push Server 負責實作推播至不同手機平台的功能。

以下說明上圖每個元件的作用:

  • Push Server:收集所有手機傳回的註冊資訊。發送訊息給各平台的推播系統,再推播至手機上。
  • Application Backend Server:實作 APP 的後台邏輯,當有推播需求(ex:商品上架、有新事件)時透過 SDK 將訊息傳給 Push Server。
  • Push Networks:就是指 Android / iOS 原生的推播系統。
  • 手機:除了接收訊息外,最重要的將從原生推播系統取得註冊資訊傳給 Push Server。以 Android 來說,透過 SDK 將從 GCM 取得的 token 傳給 Push Server。


環境架設

除了把 Push Server 架起來外,上面可以看到手機 APP 和後台 Server 還會需要用到以下 SDK:
  • aerogear-android-push (用來跟 PushServer 註冊裝置)
  • unifiedpush-java-client (包裹 Web API 用來將要傳送的訊息交給 PushServer 推播)。
很多程式碼,名字變來變去,版號很多,這就代表有很多雷可以踩,建議先裝好 Push Server,裝好以後在 Web GUI 把推播相關的參數設定好,在 Web GUI 上有自動產生樣本程式碼的功能,這時候再來去抓最新 SDK,如果找不到類別或錯誤就降一版 SDK 試看看。我也是花了一點時間才找出來可以動的組合。

建議的步驟如下:

  1. 安裝 Push Server。
  2. 在 Push Server 上建立 Application。
  3. Application 下設定 variant,variant 主要用來介接 iOS/Android 推播系統,介接的資料欄位需要從 iOS/Android 推播系統後台得到。
  4. 此時,你 Push Server 上應該有一個 Application,一個以上的 variant。
  5. 利用 Push Server > Application > variant 產生回傳註冊資訊至 Push Server 的範例程式碼,整合至手機 APP 程式碼,看看與下載的 aerogear-android-push 相不相容,不相容就找別的版本。
    1. 開啟手機 APP,利用 Push Server 的 WEB GUI 觀察手機有無註冊成功。
    2. 利用 Push Server 的 WEB GUI 發送訊息,驗證 Push Server 可以將訊息推到手機上。
  6. 利用 Push Server > Application 產生推播訊息至 Push Server 的範例程式碼,整合 APP 後台程式碼,看看與下載的 unifiedpush-java-client 相不相容,不相容就找別的版本。
    1. APP 後台發訊息給 Push Server,驗證可以透過 Push Server 將訊息推到手機上。


其他

關於 Push Server 的註冊部分,看到的寫法是每次打開 APP 或是某個頁面就重新註冊,這部分觀察資料庫,除非重新安裝 APP 否則上傳的註冊資料(GCM token)都是一樣的。解除註冊部分,看到的寫法可能寫在使用者勾選的開關上(讓使用者決定要不要收到推播),或是離開某個頁面就解除註冊。以 GCM 來說,唯一知道這裝置已經解除 GCM 註冊的時機點是在推播的時候,然後如果是自己寫的 Push Server 就可以將這些裝置清掉,但 JBoss (我用的版本是1.0.0 beta 2)的做法是沒寫這塊邏輯,所以必須自己處理,我自己的做法是定時下 SQL 去清除一個月以上沒有向 Push Server 回傳註冊資訊的裝置。

最後還是想唸一下,紅帽的文件不是寫不好寫不夠多,是整理的很沒系統,這次找文件找 SDK 的時間大概比寫扣的時間還要多,只能說免費的最貴。

解譯 Android APK

前言

最近有個需求需要看一下別的 APK 是怎麼做的,原本以為有現成的工具應該蠻簡單的,沒想到命令列苦手跟一些不熟悉的技術問題還是把我弄的很慘,寫個筆記記錄一下。

透過本文,可以知道我用了哪些工具跟這些工具的功用,最後我把所有步驟寫成一個 Groovy Script ,我會簡單介紹用法,透過這個 Script 最終可以得到 APK 所有的資源檔案、java 檔案、或是一包 jar 檔案。

工具

透過我走過的流程順便帶出我使用的工具,APK 轉換的結果,對我來說重要的就是資源檔案(layout、語系...)和程式碼,我嘗試過的三個流程如下(最後當然是用最後一個流程):

APK -> 透過 Apktool 解出來 -> 可以取得資源檔案,但只有 Smali(VM 上的虛擬語言,語法介於 Java 和 組合語言之間) 可以看但要花很多時間看。

APK -> 透過 dex2jar 直接把 APK 轉成 jar -> 沒有資源檔案,當 APK 裡頭有不只一個 dex 檔案時它只會解第一個 dex 出來,代表原始碼會缺少。

APK -> 改副檔名為 zip 解壓縮 -> 可以取得資源檔案和 dex -> 透過 dex2jar 把所有 dex 檔轉成 jar -> 解壓縮所有 jar 檔會得到所有的 .class 檔案 -> 把所有 .class 組成一個單一 jar 檔就可以用 JD-GUI 來看原始碼,或是透過 JAD 將所有 .class 轉成 .java。

怎麼使用我的 Script 

問我為何不寫 linux script 就好,我是有寫一版 linux script,但條件判斷和檔案搜尋結果再利用在 linux script 下真的是很難拼出來,所以我讓 groovy 做他擅長的部分,但執行指令還是會用下指令的方式。為什麼不用 python,因為我主力寫 Java,Groovy 跟 Java 語法相容。

Script 放在 github,所有會用到的工具就直接包含在專案裡了,使用環境是在 MAC 上,當然要先裝好 groovy 環境,然後修改 script 中 APK 的指定路徑,執行完後所有結果都會放在桌面上的 output 資料夾。

資源檔可以去 output/apktool 下找到。最終完成的單一 jar 檔可以去 output/onejar 下找到,用 JD-GUI 直接開這個 jar 就能看到原始碼。所有轉出來的 .java 放在 output/jad 下,這樣就能用 IDE 或文字編輯器來看。