我希望使用AIDL获得一些使用android IPC的经验。我想看看是否可以在两个不同的Android应用程序之间进行通信。
我的问题是在第二个应用中调用bindService
,与第一个应用的FactorialService
进行通信,服务总是失败。我尝试调用MainActivity
的第一个应用活动bindService
始终记录bindService
返回false
的事实。加上MainActivity
(实现ServiceConnection
)第二个应用程序(客户端应用程序)永远不会调用它的回调方法onServiceConnected
。
因此,在运行名为FactorialService
我定义了一个
界面,IFactorialService.aidl
:
package com.simonlbc.factorialcommon;
import com.simonlbc.factorialcommon.FactorialRequest;
import com.simonlbc.factorialcommon.FactorialResponse;
interface IFactorialService {
FactorialResponse fact(in FactorialRequest r);
}
FactorialRequest
包含输入数字(比如n)。 fact
会返回n!
以及其他信息。
在同一个应用程序中,我创建了一个类IFactorialServiceImplem
实现该aidl接口。
package com.example.simonlbc.factorialservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.SystemClock;
import com.simonlbc.factorialcommon.FactorialResponse;
import com.simonlbc.factorialcommon.FactorialRequest;
public class IFactorialServiceImplem extends com.simonlbc.factorialcommon.IFactorialService.Stub {
public long recursiveFact(int n) {
if (n < 0)
throw new IllegalArgumentException("input fa");
if (n == 1 || n == 0)
return 1;
else {
return n * recursiveFact(n-1);
}
}
public long iterativeFact(int n) {
long res = 1;
for (int i = 1; i <= n; i++)
res *= i;
return res;
}
public FactorialResponse fact(FactorialRequest r) {
long timeInMillis = SystemClock.uptimeMillis();
long result = 0;
switch(r.getChoice()) {
case RECURSIVE:
result = recursiveFact(r.getInNb());
break;
case ITERATIVE:
result = iterativeFact(r.getInNb());
}
timeInMillis = SystemClock.uptimeMillis() - timeInMillis;
return new FactorialResponse(result, timeInMillis);
}
}
然后我创建了一个Service
,用于将IFactorialService
实例传达给可能的客户:
package com.example.simonlbc.factorialservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import com.simonlbc.factorialcommon.IFactorialService;
public class FactorialService extends Service {
private IFactorialServiceImplem s = null;
private static final String TAG = "FactorialService";
@Override
public void onCreate() {
super.onCreate();
s = new IFactorialServiceImplem();
Log.d(TAG, "onCreate'd");
}
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind()'d");
return this.s;
}
@Override
public boolean onUnbind(Intent intent) {
Log.d(TAG, "onUnbind()'d");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy()'d");
s = null;
super.onDestroy();
}
}
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<service
android:name=".FactorialService">
<!--
android:enabled="true"
android:exported="true"
android:process=":remote"
-->
<intent-filter>
<action android:name="com.example.simonlbc.factorialservice.FactorialService" />
</intent-filter>
</service>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
第一个应用包含一个Launcher活动,它只是启动服务:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service);
curPackage = getString(R.string.packageService);
MainActivity.this.startService(
new Intent()
.setAction(curPackage + ".FactorialService")
.setPackage(curPackage)
);
}
我的第二个应用的启动器活动如下:
public class MainActivity extends Activity implements View.OnClickListener, ServiceConnection
我想要第二个应用的MainActivity
来
与第一个应用IFactorialService
进行通信。在onResume我
尝试绑定第一个应用程序的服务:
@Override
protected void onResume() {
super.onResume();
Intent i = new Intent();
i.setAction("com.example.simonlbc.factorialservice.FactorialService");
i.setPackage("com.example.simonlbc");
if (!super.bindService(i, this, BIND_AUTO_CREATE))
Log.w(TAG, "Failed to bind our service!!!");
}
但似乎bindService
失败了。确实每次我暂停应用程序并返回它,或启动它。 “无法绑定我们的服务!!!”显示。
请注意,这两个应用程序共享一个Android库模块,其中包含所需的aidl文件的定义。
你看到任何允许bindService()
工作的东西吗?
答案 0 :(得分:1)
您为什么使用super.bindservice()
?相反,你可以尝试这个getApplicationContext().bindservice()
此外,如果这也不起作用,请尝试以下修改代码:
Intent i = new Intent("com.example.simonlbc.factorialservice.FactorialService");
if(getApplicationContext().startService(i) != null){
if (!getApplicationContext().bindService(i, serviceConnection, 0))
Log.w(TAG, "Failed to bind our service!!!");
}
其中seriveConnection
是服务连接的对象(我不想将this
用于ServiceConnection
)。此外,您的服务应该具有正确的Action
设置,否则它将无法启动