1. 程式人生 > >Android 小米推送(MiPush)的化簡深入理解

Android 小米推送(MiPush)的化簡深入理解

      小米推送(MiPush)是小米公司向開發者提供的訊息推送服務,總的流程如官方文件所示:

     由圖可知,推送是雙向的:

     1.推送是可以由app的後臺端發起,應用伺服器的後臺會先將訊息傳給小米的訊息雲伺服器(MiPush Server),然後MIPush雲伺服器再把訊息送達到app客戶端。

     2.推送是可以由app客戶端發起,app Client先將訊息傳送到MiPush Server,經MiPush Server中轉把訊息再推到後臺。

    推送其實底層本質上還是socket通訊。一般Android開發過程中,即時通訊都會自己引socketIo寫socket的方式來做,但可能因為種種原因,比如通訊太頻繁,socket的長連線太久導致出現了訊息送達率偏低不理想(傳丟了的情況多到難以忍受),socket接收端響應太慢的問題(根本說還是送達的慢),用推送來實現就是最理想的選擇,國內Android其他的三方訊息推送都是跟小米推送相似的推送業務邏輯,像極光推送,小米推送都是很好的開發選擇標的,但是小米推送最大的好處是對MIUI系統的裝置有得天獨厚的支援,如果裝置的系統是MIUI,那麼推送的長連線是由MIUI系統來維持的

,而在非MIUI系統,維護小米推送服務的長連線Service的任務就交給app來辦了,系統級的維護和app維護這種常規操作來比較,不必多言。在MIUI上不管需要推送的Client數量再多,訊息的送達率,傳達的速度都是優於其他的推送。

     小米推送的訊息總共有兩種:透傳訊息和通知欄訊息,對於他們倆的介紹和區別官網說的已經很好了,下為原文摘錄:

基本上實際開發很少應用原生的通知欄訊息,都是自己繪製通知欄介面佈局,後臺傳送透傳訊息,app端在透傳的廣播接受器拿到訊息json後反序列化,然後彈出自己的自定義通知欄。

       關於整合小米推送,小米給的sdk Demo已經很簡單了,稍微看看就能輕易的嵌入到自己的專案中,一言以蔽之:DemoMessageReceiver一個嵌進專案就妥了,在專案中註冊小米推送服務和接收服務的廣播都由它來接收。註冊操作成功後會得到regId,這個是裝置標識用來發給伺服器後臺為下一步通訊用的,當訊息送達的廣播被捕獲到後,就能在廣播接收器的相應回撥取寫邏輯了,網上已經有很詳細的教程:

https://www.jianshu.com/p/b1134bebc2d4。下面只列出收到透傳訊息後彈出通知欄的核心程式碼:

   //方法用來接收伺服器向客戶端傳送的透傳訊息
    @Override
    public void onReceivePassThroughMessage(Context context, MiPushMessage message) {
        if (!TextUtils.isEmpty(message.getTopic())) {
            mTopic = message.getTopic();
        } else if (!TextUtils.isEmpty(message.getAlias())) {
            mAlias = message.getAlias();
        }

        bean = gson.fromJson(message.getContent(), EventInfoBean.class);
        showNotification(App.getInst(),bean);
        RxBus.getDefault().post(100, "");  //100   重新渲染介面

    }




   //自定義的彈窗訊息
    private void showNotification(Context context,EventInfoBean bean) {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
        String content = "";
        if (bean.getYjType() == 1) {
            content = bean.getDeviceName() + "有一個" + bean.getEventTypeName() + bean.getEventStatusName() + ",點選檢視";
        } else {
            content = bean.getDeviceName() + "報警已解除點選檢視";
        }
        builder.setAutoCancel(true);//點選後消失
        builder.setSmallIcon(R.mipmap.ic_launcher);//設定通知欄訊息標題的頭像
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);//設定通知鈴聲
        builder.setTicker(content);
        builder.setContentText(content);//通知內容
        builder.setContentTitle(bean.getEventTypeName());
        builder.setPriority(Notification.PRIORITY_MAX);
        //利用PendingIntent來包裝我們的intent物件,使其延遲跳轉
        if (bean.gettClass() != null){
            Intent intent = new Intent(context, bean.gettClass());//將要跳轉的介面
            intent.putExtra("bean",bean);
            PendingIntent intentPend = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
            builder.setContentIntent(intentPend);
        }

        NotificationManager manager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
        manager.notify(0, builder.build());

    }