在上一節中,我介紹了Android中Service的生命周期以及一些有關知識。在這一節中,我采用代碼編寫的方式來介紹一下不同程序之間也就是不同進程之間通信采用AIDL方式。
首先我需要解釋一下,不同程序進程間采用AIDL方式啟動服務,我們可以看作成client客戶端與server服務端之間的通信,無非c/s都是安裝在了我們的智能手機設備Android系統之上。好了,理解到這里我們就可以繼續往下介紹了。
首先我們編寫server服務端程序:
1)我們新建一個應用程序S,它的應用程序架構如下:

2)我們在com.lgy.s包下編寫S.aidl文件,具體代碼如下:(aidl編碼格式不再敘述)
package com.lgy.s;
interface S{
String getStr(String name);
}
編寫好S.aidl文件我們就可以使用S.stub類下的相關方法。
3)我們可以自定義我們的Service了,具體代碼如下:
package com.lgy.s;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class MyService extends Service {
private static final String TAG = "MyService";
private S.Stub server;
@Override
public void onCreate() {
Log.i(TAG, "onCreate");
server = new S.Stub() {
@Override
public String getStr(String name) throws RemoteException {
Log.i(TAG, name);
return name;
}
};
super.onCreate();
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "onUnbind");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
Log.i(TAG, "onDestroy");
server = null;
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind");
return server;
}
}
4)我們進行服務端Server最后一步,在AndroidManifest.xml文件中注冊服務Service
<service android:name="com.lgy.s.MyService">
<intent-filter >
<action android:name="android.lgy.myService" />
</intent-filter>
</service>
-----------到此我們服務器端就編寫完畢------------------------
下面我們編寫客戶端client應用程序:
1)我們新建一個應用程序C,具體應用架構如下:

2)我們將在服務器端S寫的aidl原封不動的移到客戶端C上來(注包文件名都原封不動),移動后架構如下圖:

3)我們就可以在客戶端MainActivity中直接調用綁定服務器上的服務,具體代碼如下:
package com.lgy.c;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import com.lgy.s.S;
public class MainActivity extends Activity {
protected static final String TAG = "MainActivity";
private S s;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
s = S.Stub.asInterface(service);
Log.i(TAG, "onServiceConnected client");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void bindBtn(View v){
Intent mIntent = new Intent("android.lgy.myService");
bindService(mIntent, conn, BIND_AUTO_CREATE);
}
public void greetBtn(View v){
try {
Log.i(TAG, s.getStr("client"));
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void unbindBtn(View v){
unbindService(conn);
}
}
4)MainActivity對應的布局文件代碼如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.lgy.c.MainActivity" >
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:onClick="bindBtn"
android:text="綁定服務器Service" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/button1"
android:layout_below="@+id/button1"
android:onClick="greetBtn"
android:text="傳遞參數給服務器獲取返回的數據" />
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/button2"
android:layout_below="@+id/button2"
android:onClick="unbindBtn"
android:text="解除綁定服務" />
</RelativeLayout>
至此為止客戶端代碼我們已經編寫完畢。
下面我們開始測試:
我們不運行服務器端,而是直接運行客戶端的話,相對應的效果會怎么樣呢?具體效果如下解析:
第一、我們點擊綁定服務的話,系統程序無任何反應,這個時候在客戶端服務已經綁定,但是沒有連接到服務端。接著我們再次點解讀取數據的話,系統將會崩潰。因為沒有連接到服務器端方法沒有具體實現。
第二、我們點擊綁定服務的話,系統程序無任何反應,這個時候在客戶端服務已經綁定,但是沒有連接到服務端,接著我們點擊解除服務綁定的話,系統仍然沒有任何反應,我們要是再接著點擊解除服務綁定的話,系統就會崩潰,這也就從而再次證明了服務只會綁定一次,多次綁定的話服務不會做出任何反應;服務解除綁定只能僅只能解除綁定一次,多次解除綁定服務的話,系統就會崩潰。
第三、我們直接點擊接受數據,系統程序也會崩潰,原因就是在于服務沒有綁定,服務端根本就沒有連接,相當于數據讀取方法沒有實現。
第四:我們直接點擊解除綁定的話,系統程序也會崩潰,原因就是在于服務一次也沒有綁定。
我們現在運行服務器,相對應的效果又會怎么樣呢?具體效果如下解析:
第一、我們點擊綁定服務,可以觀察到后臺logcat日志信息:


從日志我們可以看出在客戶端C綁定服務同時連接服務端,可以看到服務端Service的啟動onCreate和服務Service綁定onBind。
第二、我們點擊獲取數據,可以觀察到后臺logcat日志信息:


從日志圖中我們可以看出客戶端將client字符串數據傳遞給服務器端,服務器端接受并返回一個字符串數據。
第三、我們點擊解除綁定服務,具體logcat如下:

第四:如果我們不點擊綁定服務,而是直接點獲取數據,或者解除綁定的話,系統都將會崩潰,具體原因前面已經解釋清楚,在此不作過多重復。
以上就是AIDL在多進程中通信調用的簡單應用(C應用程序啟動S應用程序服務Service)。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。