欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

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

廣播:

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

共享內(nèi)存:

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

socket:

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

AIDL:

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

流程圖

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

利用aidl中的RemoteCallbackList類(原理和源碼我就不多說了,其實Client調(diào)用Server是大同小異的,只不過是反者來了一次),來實現(xiàn)client中的接口回調(diào),這樣才能從server主動給client發(fā)消息,一般我們都是client主動調(diào)用Server,現(xiàn)在輪到Server主動調(diào)用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<>();//回調(diào)的關鍵(API>=17,才能使用)
 
  @Override
  public void onCreate() {
    super.onCreate();
  }
 
  @Nullable
  @Override
  public IBinder onBind(Intent intent) {
    return iBinder;
  }
 
  /**
   * 實現(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);//注冊回調(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ā)送給某個client,也可
   * 以根據(jù)自己的業(yè)務來封裝一下Bean,記得要實現(xiàn)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代碼是一樣的,就是相互發(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);//開啟遠程服務
    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() {
          //注冊回調(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)

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

源碼我都放在github:MessageCenter

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Android開發(fā)入門之Appwidget用法分析

    Android開發(fā)入門之Appwidget用法分析

    這篇文章主要介紹了Android開發(fā)入門之Appwidget用法,較為詳細的分析了App Widget的概念、功能、創(chuàng)建、使用方法與相關注意事項,需要的朋友可以參考下
    2016-07-07
  • ListView異步加載圖片實現(xiàn)思路

    ListView異步加載圖片實現(xiàn)思路

    用到ListView去加載數(shù)據(jù),加載圖片和文字是比較常見的,文字還好,圖片從網(wǎng)絡請求加載速度比較慢,以下是一個我在項目中使用到的異步加載圖片的解決方案
    2013-04-04
  • Android提高之SurfaceView的基本用法實例分析

    Android提高之SurfaceView的基本用法實例分析

    這篇文章主要介紹了Android提高之SurfaceView的基本用法,非常實用的功能,需要的朋友可以參考下
    2014-08-08
  • Android編程實現(xiàn)向SD卡寫入數(shù)據(jù)的方法

    Android編程實現(xiàn)向SD卡寫入數(shù)據(jù)的方法

    這篇文章主要介紹了Android編程實現(xiàn)向SD卡寫入數(shù)據(jù)的方法,涉及Android針對SD卡狀態(tài)判斷,文件及權(quán)限操作等相關技巧,需要的朋友可以參考下
    2016-04-04
  • Android ApiDemo示例工程的創(chuàng)建

    Android ApiDemo示例工程的創(chuàng)建

    本文主要介紹Android ApiDemo示例工程的創(chuàng)建,這里SDK中的示例工程做了大致介紹,并說明如何創(chuàng)建ApiDemo 示例工程,有需要看自帶代碼的朋友可以參考下
    2016-09-09
  • Android實現(xiàn)定時任務及鬧鐘

    Android實現(xiàn)定時任務及鬧鐘

    這篇文章主要為大家詳細介紹了Android實現(xiàn)定時任務及鬧鐘,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • Android Scroll滑動效果實例

    Android Scroll滑動效果實例

    這篇文章主要為大家分享了Android Scroll滑動效果實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-04-04
  • Android跳轉(zhuǎn)到通訊錄獲取用戶名稱和手機號碼的實現(xiàn)思路

    Android跳轉(zhuǎn)到通訊錄獲取用戶名稱和手機號碼的實現(xiàn)思路

    這篇文章主要介紹了Android跳轉(zhuǎn)到通訊錄獲取用戶名稱和手機號碼的實現(xiàn)思路,當用戶點擊跳轉(zhuǎn)到通訊錄界面 并取通訊錄姓名和手機號碼 ,實現(xiàn)代碼簡單易懂,非常不錯感興趣的朋友一起看看吧
    2016-10-10
  • Android使用Dialog風格彈出框的Activity

    Android使用Dialog風格彈出框的Activity

    這篇文章主要為大家詳細介紹了Android使用Dialog風格彈出框的Activity,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 全面解析Android之ANR日志

    全面解析Android之ANR日志

    不論從事安卓應用開發(fā),還是安卓系統(tǒng)研發(fā),應該都遇到應用無響應(簡稱ANR)問題,當應用程序一段時間無法及時響應,則會彈出ANR對話框,讓用戶選擇繼續(xù)等待,還是強制關閉。本文將帶你全面解析Android之ANR日志
    2021-06-06

最新評論