最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android基于Aidl的跨進(jìn)程間雙向通信管理中心

 更新時(shí)間:2018年11月23日 11:16:57   作者:何浪  
這篇文章主要為大家詳細(xì)介紹了Android基于Aidl的跨進(jìn)程間雙向通信管理中心,類似于聊天室,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

得益于最近有點(diǎn)時(shí)間和精力,我想起來(lái)了一件事。那就是在上家公司,公司要求做一個(gè)APP進(jìn)程間的通信的功能,并不是APP對(duì)APP的直接跨進(jìn)程通信,而是通過(guò)一個(gè)服務(wù)中心,做接收,然后,再轉(zhuǎn)發(fā),避免應(yīng)用之間耦合性高,不然的話,新增一個(gè)APP,其他APP也要進(jìn)行升級(jí)更新(類似于有服務(wù)中心的聊天室)。

我就花幾個(gè)小時(shí)寫點(diǎn)東西吧,順便記錄一下

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

廣播:

廣播有缺陷,就是效率不高,有時(shí)候會(huì)遇到廣播丟失,或者說(shuō)廣播的隊(duì)列過(guò)長(zhǎng),導(dǎo)致消息發(fā)送慢;

共享內(nèi)存:

共享內(nèi)存沒(méi)有安全性可言,而且多線程讀寫數(shù)據(jù)的話,會(huì)無(wú)法控制

socket:

socket耦合度較高,內(nèi)存需要拷貝兩次,適用于跨網(wǎng)絡(luò)

AIDL:

基于binder,效率高;基于C/S架構(gòu),分層清晰,功能明確;有Linux的進(jìn)程ID概念,更加安全等優(yōu)點(diǎn)

流程圖

很簡(jiǎn)單的架構(gòu),所有的APP消息傳遞都通過(guò)Server來(lái)做,工程結(jié)構(gòu)如下,center(消息中心),app1,app2都依賴于lib(aidl接口庫(kù))

利用aidl中的RemoteCallbackList類(原理和源碼我就不多說(shuō)了,其實(shí)Client調(diào)用Server是大同小異的,只不過(guò)是反者來(lái)了一次),來(lái)實(shí)現(xiàn)client中的接口回調(diào),這樣才能從server主動(dòng)給client發(fā)消息,一般我們都是client主動(dòng)調(diào)用Server,現(xiàn)在輪到Server主動(dòng)調(diào)用client

服務(wù)端的代碼如下,你可以按照你項(xiàng)目的要求來(lái)做

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;
 
/**
 * 消息服務(wù)中心(記得在 manifest.xml 加上 android:exported="true")
 */
public class MyService extends Service {
  private final static String TAG = MyService.class.getSimpleName();
  private RemoteCallbackList<IMyAidlCallBackInterface> callbackList = new RemoteCallbackList<>();//回調(diào)的關(guān)鍵(API>=17,才能使用)
 
  @Override
  public void onCreate() {
    super.onCreate();
  }
 
  @Nullable
  @Override
  public IBinder onBind(Intent intent) {
    return iBinder;
  }
 
  /**
   * 實(shí)現(xiàn)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);//注冊(cè)回調(diào)listener
      Log.d(TAG,"registerListener");
    }
 
    @Override
    public void unregisterListener(IMyAidlCallBackInterface listener) throws RemoteException {
      callbackList.unregister(listener);//取消回調(diào)listener
      Log.d(TAG,"unregisterListener");
    }
  };
 
  /**
   * 發(fā)送消息給全部的client(你也可以指定發(fā)送給某個(gè)client,也可
   * 以根據(jù)自己的業(yè)務(wù)來(lái)封裝一下Bean,記得要實(shí)現(xiàn)Parcelable接口來(lái)序列化
   * @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代碼是一樣的,就是相互發(fā)消息:

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);//開(kāi)啟遠(yuǎn)程服務(wù)
    bindService(intent,myServiceConnection,BIND_AUTO_CREATE);//綁定服務(wù)
 
  }
 
  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() {
          //注冊(cè)回調(diào)
          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)發(fā)消息給Client1(app1)

順便說(shuō)一句,提前打開(kāi)Center服務(wù),因?yàn)閍ndroid 8.0之后的版本直接遠(yuǎn)程開(kāi)啟其他App后臺(tái)進(jìn)程服務(wù),是行不通了,可以綁定一個(gè)前臺(tái)進(jìn)程,網(wǎng)上方法有很多,我這里就簡(jiǎn)單處理了

源碼我都放在github:MessageCenter

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

波密县| 长垣县| 清远市| 甘谷县| 曲水县| 衡山县| 宝鸡市| 莫力| 越西县| 渭源县| 大兴区| 旬阳县| 乌拉特前旗| 湖南省| 枝江市| 孟连| 九龙城区| 新河县| 盐源县| 综艺| 施甸县| 保靖县| 大田县| 呈贡县| 桓台县| 布尔津县| 长白| 秭归县| 尉氏县| 行唐县| 延庆县| 航空| 民和| 郁南县| 若羌县| 洞口县| 明光市| 永顺县| 孝义市| 改则县| 台东市|