這兩個apk 是在兩個進程裏的,(或許可以配置成壹個進程。不過如何直接操作這個沒有試過。)
所以壹般的有兩種方法:
1、RPC
2、通過 BroadcastRecever 或 Service
第二種方法比較簡單壹些。
比如B 控制 A的話,
A定義Service ,比如com.my.ServerA .自定義actionFilter “com.my.serverA.action"
B中調用Intent it = newIntent("com.my.serverA.action");
it.putExtra(....);// 傳遞妳的自定義控制指令。
B.startService(it);
在A中ServerA的 onStartService(Intent it) 。解析這個控制指令,做相應操作就可以了。
用BroadcastRecever 的道理壹樣。
Aidl,android平臺的IPC方式之壹,基於系統的Ibinder機制。
網上大多數例子都是在壹個apk下來測試調用service,現在我在兩個project下面來調用。
壹個是server project,壹個是client project
首先我們建立的是server project,這裏面要實現aidl文件和壹個service,activity只是用來啟動service的,當然,妳也可以通過發廣播的形式來啟動service。
首先看IAidlService.aidl文件:
Java代碼
package com.ds.server;
interface IAidlService {
int getType();
}
這樣在eclipse裏面自動編譯的時候會在gen下面生成IAidlService.java文件(燈下我們的client project要用)。
然後新建壹個service,這個service裏面has a IAidlService的stub對象,service具體代碼如下:
Java代碼
package com.ds.server;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class AidlService extends Service {
private IAidlService.Stub mBinder = new IAidlService.Stub() {
@Override
public int getType() throws RemoteException {
// TODO Auto-generated method stub
return 5;
}
};
private void Log(String str) {
Log.d("AidlService", "------ " + str + "------");
}
@Override
public void onCreate() {
Log("service create");
}
@Override
public void onStart(Intent intent, int startId) {
Log("service start id=" + startId);
}
@Override
public IBinder onBind(Intent t) {
Log("service on bind");
return mBinder;
}
@Override
public void onDestroy() {
Log("service on destroy");
super.onDestroy();
}
@Override
public boolean onUnbind(Intent intent) {
Log("service on unbind");
return super.onUnbind(intent);
}
public void onRebind(Intent intent) {
Log("service on rebind");
super.onRebind(intent);
}
}
這裏壹定要實現onBind方法,並返回壹個IAidlService.Stub對象。
再去AndroidManifest.xml註冊這個service:
Xml代碼
<service
android:name=".AidlService"
android:enabled="true"
android:process=":remote" >
<intent-filter>
<action android:name="com.ds.server.IAidlService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
android:enabled="true"
android:process=":remote"這兩個標簽可有可無。
只要註冊了這個service就行。
好了,到此,服務端已經完成。
-------------------華麗的分割線-----------------------------------------
下面我們開始client project。
client project比較簡單,需要註意的地方是,首先需要把server project中gen文件夾中aidl生成的那個IAidlService.java類以及包都拷貝到我們的client project中。
(註意:client project的包名為com.ds.client;另外壹個包名com.ds.server以及這個server包下面的IAidlService.java類都是從server project的gen文件夾拷貝過來的,至於gen文件夾的其他文件就不需要拷貝過來。)。
好了,這樣的話,client project只要從activity去遠程調用service就好了,實現代碼如下:
Java代碼
package com.ds.client;
import com.ds.server.IAidlService;
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 android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class AidlClientActivity extends Activity {
IAidlService iservice;
private ServiceConnection connection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
// 從遠程service中獲得AIDL實例化對象
iservice = IAidlService.Stub.asInterface(service);
Log.i("Client","Bind Success:" + iservice);
}
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
iservice = null;
Log.i("Client","onServiceDisconnected");
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView tv = (TextView) findViewById(R.id.tv);
Button bt = (Button) findViewById(R.id.bt);
bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent service = new Intent(IAidlService.class.getName());
bindService(service, connection, BIND_AUTO_CREATE);
if (iservice != null) {
try {
tv.setText("" + iservice.getType());
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
});
}
}
註意幾點:
1,import com.ds.server.IAidlService;使用的是我們拷貝過來的IAidlService.java類
2,需要壹個ServiceConnection對象
3,通過Intent service = new Intent(IAidlService.class.getName());
bindService(service, connection, BIND_AUTO_CREATE);來bind service。這樣就可以調用aidl中定義的接口來獲取service中的值了。
唉,由於在使用中沒有註意拷貝server project中gen文件夾下面的包和IAidlService.java,老是出現Unable to start service Intent這樣的錯誤。搞了好久。
附件是源碼。註意使用的時候,先要運行server project,啟動服務,然後再運行client project。