Android 遠程Service

遠程Servicejava

在清單文件中給Service添加屬性process 爲:remoteandroid

<service  
        android:name="com.example.servicetest.MyService"  
        android:process=":remote" >  
    </service>  

使用遠程Service,MyService將在另外一個進程中運行,只會阻塞所在進程中的主線程,不會當前應用程序。ide

遠程Service會在應用包名加上:remote;spa

 

遠程Service的弊端:線程

開啓多進程時 Application會運行兩次 (初始化數據時不穩當 : 須要判斷進程名與當前應用的的進程名)
code

使用bind方式與Activity創建鏈接時 程序會崩潰。
對象

由於Service與Activity 運行在兩個不一樣的進程中 ,不能使用傳統的創建鏈接方式,須要引入AIDL;blog

 

Activity與遠程Service 創建關聯, 使用AIDL 進行跨進程通訊(IPC)接口

AIDL(Android Interface Definition Languge) android接口定義語言 進程

AIDL的做用: 用於Service與多個應用程序組件之間進行跨進程通訊 ,實現多個應用程序共享一個Service的功能

 

使用跨進程通訊的步驟

1. 首先新建一個AIDL文件  進行文件MyAIDLService.aidl文件

package com.example.service.remote;

interface MyAIDLService
{
    int plus(int a, int b);  
    String toUpperCase(String str);  

}

//保存後,gen目錄下會生產一個對應的java文件 ;

  //編寫Aidl文件時,須要注意下面幾點:

 
 

  1.接口名和aidl文件名相同。

 
 

  2.接口和方法前不用加訪問權限修飾符public,private,protected等,也不能用final,static。

 
 

  3.Aidl默認支持的類型包話java基本類型(int、long、boolean等)和(String、List、Map、 CharSequence),使用這些類型時不須要import聲明。對於List和Map中的元素類型必須是Aidl支持的類型。若是使用自定義類型做 爲參數或返回值,自定義類型必須實現Parcelable接口。

 
 

  4.自定義類型和AIDL生成的其它接口類型在aidl描述文件中,應該顯式import,即使在該類和定義的包在同一個包中。

 
 

  5.在aidl文件中全部非Java基本類型參數必須加上in、out、inout標記,以指明參數是輸入參數、輸出參數仍是輸入輸出參數。

 
 

  6.Java原始類型默認的標記爲in,不能爲其它標記。

 

 

 

二、而後修改MyService中的代碼   實現剛定義好的MyAIDLService接口  而且在onBInd中返回對象

   @Override  
    public IBinder onBind(Intent intent) {  
        return mBinder;  
    }  
  
    MyAIDLService.Stub mBinder = new Stub() {  
  
        @Override  
        public String toUpperCase(String str) throws RemoteException {  
            if (str != null) {  
                return str.toUpperCase();  
            }  
            return null;  
        }  
  
        @Override  
        public int plus(int a, int b) throws RemoteException {  
            return a + b;  
        }  
    };  

// Stub是Binderd的子類

 

三、在MainActivity中寫實現代碼

  private MyAIDLService myAIDLService;  
  
      //建立 ServiceConnection對象 並實現MyAIDLeService中的方法
private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) {
        // 獲取MyAIDLService對象 myAIDLService
= MyAIDLService.Stub.asInterface(service); try { int result = myAIDLService.plus(3, 5); String upperStr = myAIDLService.toUpperCase("hello world"); Log.d("TAG", "result is " + result); Log.d("TAG", "upperStr is " + upperStr); } catch (RemoteException e) { e.printStackTrace(); } } };

 

4.在其餘應用程序中調用MyService的方法  

4.一、在清單文件中給MyService 添加隱式Intent; 用於其餘應用程序調用

<service android:name="com.example.service.remote.MyService"
                 android:process=":remote"
            >
            <intent-filter>
                <action android:name="com.example.service.remote.MyService.MyAIDLService"></action>
            </intent-filter>
            
        </service>
//MyService能夠響應這個action的Intent

4.2.而後在一個新的項目中,把MyAIDLService.aidl文件拷貝過來(要將原有的包路徑一塊兒拷貝過來)

 

4.3 而後在MainActivity中  加入MyService創建關聯的代碼

  private MyAIDLService myAIDLService;  
  
      //建立 ServiceConnection對象    並實現MyAIDLeService中的方法
    private ServiceConnection connection = new ServiceConnection() {  
  
        @Override  
        public void onServiceDisconnected(ComponentName name) {  
        }  
  
        @Override  
        public void onServiceConnected(ComponentName name, IBinder service) {  
        // 獲取MyAIDLService對象
            myAIDLService = MyAIDLService.Stub.asInterface(service);  
            try {  
                int result = myAIDLService.plus(3, 5);  
                String upperStr = myAIDLService.toUpperCase("hello world");  
                Log.d("TAG", "result is " + result);  
                Log.d("TAG", "upperStr is " + upperStr);  
            } catch (RemoteException e) {  
                e.printStackTrace();  
            }  
        }  
    };  

4.4 bindService  經過隱式意圖

case R.id.btn_bind:
            Intent intent1 = new Intent("com.example.service.remote.MyService.MyAIDLService");
            bindService(intent1, conn , BIND_AUTO_CREATE);
            break;

實現不一樣應用程序跨進程通訊功能。

相關文章
相關標籤/搜索