中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android基于Aidl的跨進程間雙向通信管理中心

發布時間:2020-10-25 22:06:06 來源:腳本之家 閱讀:124 作者:何浪 欄目:移動開發

得益于最近有點時間和精力,我想起來了一件事。那就是在上家公司,公司要求做一個APP進程間的通信的功能,并不是APP對APP的直接跨進程通信,而是通過一個服務中心,做接收,然后,再轉發,避免應用之間耦合性高,不然的話,新增一個APP,其他APP也要進行升級更新(類似于有服務中心的聊天室)。

我就花幾個小時寫點東西吧,順便記錄一下

大家都知道在Android設備上,有很多方式,比如,廣播,socket,共享內存,aidl等,其中廣播和aidl都是基于android中iBinder機制

廣播:

廣播有缺陷,就是效率不高,有時候會遇到廣播丟失,或者說廣播的隊列過長,導致消息發送慢;

共享內存:

共享內存沒有安全性可言,而且多線程讀寫數據的話,會無法控制

socket:

socket耦合度較高,內存需要拷貝兩次,適用于跨網絡

AIDL:

基于binder,效率高;基于C/S架構,分層清晰,功能明確;有Linux的進程ID概念,更加安全等優點

流程圖

Android基于Aidl的跨進程間雙向通信管理中心

很簡單的架構,所有的APP消息傳遞都通過Server來做,工程結構如下,center(消息中心),app1,app2都依賴于lib(aidl接口庫)

Android基于Aidl的跨進程間雙向通信管理中心

利用aidl中的RemoteCallbackList類(原理和源碼我就不多說了,其實Client調用Server是大同小異的,只不過是反者來了一次),來實現client中的接口回調,這樣才能從server主動給client發消息,一般我們都是client主動調用Server,現在輪到Server主動調用client

服務端的代碼如下,你可以按照你項目的要求來做

package com.helang.messagecenterdemo;
 
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;
 
import com.helang.lib.IMyAidlCallBackInterface;
import com.helang.lib.IMyAidlInterface;
 
/**
 * 消息服務中心(記得在 manifest.xml 加上 android:exported="true")
 */
public class MyService extends Service {
  private final static String TAG = MyService.class.getSimpleName();
  private RemoteCallbackList<IMyAidlCallBackInterface> callbackList = new RemoteCallbackList<>();//回調的關鍵(API>=17,才能使用)
 
  @Override
  public void onCreate() {
    super.onCreate();
  }
 
  @Nullable
  @Override
  public IBinder onBind(Intent intent) {
    return iBinder;
  }
 
  /**
   * 實現iBinder
   */
  private IMyAidlInterface.Stub iBinder = new IMyAidlInterface.Stub() {
    @Override
    public void sendMessage(String tag, String message) throws RemoteException {
      callbackList.beginBroadcast();
      sendMessageToAllClient(tag,message);
      Log.d(TAG,"tag="+tag+" message="+message);
      callbackList.finishBroadcast();
    }
 
    @Override
    public void registerListener(IMyAidlCallBackInterface listener) throws RemoteException {
      callbackList.register(listener);//注冊回調listener
      Log.d(TAG,"registerListener");
    }
 
    @Override
    public void unregisterListener(IMyAidlCallBackInterface listener) throws RemoteException {
      callbackList.unregister(listener);//取消回調listener
      Log.d(TAG,"unregisterListener");
    }
  };
 
  /**
   * 發送消息給全部的client(你也可以指定發送給某個client,也可
   * 以根據自己的業務來封裝一下Bean,記得要實現Parcelable接口來序列化
   * @param tag
   * @param message
   */
  private void sendMessageToAllClient(String tag,String message){
    for (int i = 0 ; i < callbackList.getRegisteredCallbackCount();i++){
      try {
        callbackList.getBroadcastItem(i).callback(tag,message);
      } catch (RemoteException e) {
        e.printStackTrace();
      }
    }
  }
}

Client1和Client2代碼是一樣的,就是相互發消息:

package com.helang.app2;
 
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
 
import com.helang.lib.IMyAidlCallBackInterface;
import com.helang.lib.IMyAidlInterface;
 
public class MainActivity extends AppCompatActivity {
  private EditText editText;
  private Button bt_send;
  private TextView text;
 
  private IMyAidlInterface iMyAidlInterface;
  private ServiceCallBack serviceCallBack;
 
  private MyServiceConnection myServiceConnection;
 
  private Handler handler = new Handler();
 
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    bt_send = findViewById(R.id.bt_send);
    editText = findViewById(R.id.editText);
    text = findViewById(R.id.text);
 
    bt_send.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        if (iMyAidlInterface != null){
          try {
            iMyAidlInterface.sendMessage("app2",editText.getText().toString().trim());
          } catch (RemoteException e) {
            e.printStackTrace();
          }
        }
      }
    });
 
    bindService();
  }
 
  @Override
  protected void onDestroy() {
    super.onDestroy();
    unbindService();
  }
 
  private void bindService(){
    myServiceConnection = new MyServiceConnection();
    serviceCallBack = new ServiceCallBack();
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("com.helang.messagecenterdemo",
        "com.helang.messagecenterdemo.MyService"));
    startService(intent);//開啟遠程服務
    bindService(intent,myServiceConnection,BIND_AUTO_CREATE);//綁定服務
 
  }
 
  private void unbindService(){
    if (myServiceConnection != null){
      try {
        iMyAidlInterface.unregisterListener(serviceCallBack);
      } catch (RemoteException e) {
        e.printStackTrace();
      }
      unbindService(myServiceConnection);
    }
  }
 
  /**
   * 連接Service
   */
  class MyServiceConnection implements ServiceConnection {
 
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
      iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);
 
      handler.post(new Runnable() {
        @Override
        public void run() {
          //注冊回調
          if (iMyAidlInterface != null){
            try {
              iMyAidlInterface.registerListener(serviceCallBack);
            } catch (RemoteException e) {
              e.printStackTrace();
            }
          }
        }
      });
 
    }
 
    @Override
    public void onServiceDisconnected(ComponentName componentName) {
 
    }
  }
 
  /**
   * service回到client的類
   */
  class ServiceCallBack extends IMyAidlCallBackInterface.Stub{
 
    @Override
    public void callback(final String tag, final String message) throws RemoteException {
      runOnUiThread(new Runnable() {
        @Override
        public void run() {
          text.append("tag="+tag+" message="+message);
        }
      });
    }
  }
}

看看效果吧,Client2(app2)發消息給Client1(app1)

Android基于Aidl的跨進程間雙向通信管理中心

Android基于Aidl的跨進程間雙向通信管理中心

順便說一句,提前打開Center服務,因為android 8.0之后的版本直接遠程開啟其他App后臺進程服務,是行不通了,可以綁定一個前臺進程,網上方法有很多,我這里就簡單處理了

源碼我都放在github:MessageCenter

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

措美县| 荆州市| 苏州市| 玛多县| 渭源县| 江山市| 无锡市| 喀什市| 吉首市| 绥中县| 福安市| 巴中市| 城步| 黄浦区| 巴塘县| 中超| 柘荣县| 武汉市| 大渡口区| 壤塘县| 苗栗县| 房山区| 临西县| 汉中市| 江津市| 抚顺县| 长治县| 清水县| 福泉市| 涟源市| 冀州市| 横山县| 博爱县| 泽普县| 来安县| 稻城县| 霍林郭勒市| 循化| 郯城县| 民勤县| 辉南县|