Tôi đang cố gắng phát triển thiết lập 2 ứng dụng (ứng dụng dịch vụ + ứng dụng khách) bằng AIDL. Tôi hiện đang có một thiết lập của 3 module:Dịch vụ AIDL không kết nối sau khi bindService()
- android-agent-framework (android Module thư viện tổ chức chỉ file AIDL)
- android-agent (dịch vụ)
- android-dụ-client (các khách hàng)
đại lý android và android-agent-framework có quyền phụ thuộc vào người đầu tiên truy cập vào giao diện.
Bất cứ khi nào khách hàng gọi bindService() nó bị sai khi trả về và trong ServiceConnection, onServiceConnected() không được gọi. Cũng trong việc thực hiện dịch vụ, onBind() không được gọi. Không có lỗi trong nhật ký.
Đây là mã:
hoạt động android-agent:
public class MyCompanyStartActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(MyCompanyStartActivity.class.toString(), "Create MyCompanyStartActivity");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ComponentName service = startService(new Intent(this, MyCompanyRequestService.class));
Log.i("tag", service.getClassName() + "::" + service.getPackageName());
}
}
dịch vụ android-agent:
public class MyCompanyRequestService extends Service {
@Override
public IBinder onBind(Intent intent) {
Log.i(MyCompanyRequestService.class.toString(), "Starting SmartRest Service");
return mBinder;
}
private final IMyCompanyRequestService.Stub mBinder = new IMyCompanyRequestService.Stub() {
@Override
public void sendData(String xid, String authentication, String data) throws RemoteException{
Log.i(MyCompanyRequestService.class.toString(), "sending data: " + data);
}
};
}
android-agent manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mycompany.android.agent" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MyCompanyStartActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Services -->
<service
android:name="com.mycompany.android.agent.framework.MyCompanyRequestService"
android:process=":remote"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="MyCompanyRequestService"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
<!-- Permissions -->
</application>
</manifest>
android hoạt động -example-client:
public class ClientStarter extends Activity {
protected IMyCompanyRequestService mycompanyRequestService = null;
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i("tag","create client");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
if (mycompanyRequestService == null) {
printServices();
Intent it = new Intent("MyCompanyRequestService");
it.setPackage("com.mycompany.android.agent.framework");
Log.i("tag","before binding service: " + it.getAction() + "::" + it.getPackage());
boolean serviceBinding = getApplicationContext().bindService(it, connection, Context.BIND_AUTO_CREATE);
Log.i("tag", "service is bound: " + serviceBinding);
}
Handler handler = new Handler();
handler.postDelayed(new Runner(), 10000);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(connection);
}
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("service", "Service connected");
mycompanyRequestService = IMyCompanyRequestService.Stub.asInterface(service);
Toast.makeText(getApplicationContext(), "Service Connected", Toast.LENGTH_SHORT).show();
Log.i("service", "Service connected");
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i("service", "Service disconnected");
mycompanyRequestService = null;
Toast.makeText(getApplicationContext(), "Service Disconnected", Toast.LENGTH_SHORT).show();
Log.i("service", "Service disconnected");
}
};
private void printServices() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
Log.d("service", service.service.getClassName());
}
}
private class Runner implements Runnable {
@Override
public void run() {
Log.i("tag","starting");
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location loc;
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
Log.e(ClientStarter.class.toString(), "Error", e);
} while(true) {
try {
if (mycompanyRequestService != null) {
loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Log.i(ClientStarter.class.toString(), loc.getLatitude() + " - " + loc.getLongitude() + " - " + loc.getAltitude());
mycompanyRequestService.sendData("test", "auth", String.valueOf(loc.getLatitude()) + "," + String.valueOf(loc.getLongitude()) + "," + String.valueOf(loc.getAltitude()));
} else {
Log.i(ClientStarter.class.toString(), "service not yet available");
}
Thread.sleep(5000);
} catch (InterruptedException e) {
Log.e(ClientStarter.class.toString(), "Error", e);
} catch (RemoteException e) {
Log.e(ClientStarter.class.toString(), "Error", e);
}
}
}
}
}
PrintServices() gọi trước khi cố kết nối dịch vụ thực sự liệt kê dịch vụ để dịch vụ đang chạy.
Nhật ký không chứa bất kỳ lỗi nào và máy khách đang ở cuối chạy trong vòng lặp nhưng dịch vụ vẫn không có giá trị.
Có thể ai đó đã gặp sự cố tương tự trước đây.
Trên Android 5.0+, bạn cần sử dụng 'Intent' rõ ràng để liên kết với dịch vụ. Tôi hoài nghi rằng 'setPackage()' là đủ. – CommonsWare
@CommonsWare Tôi thực sự đã thêm setPackage() sau khi tôi gặp sự cố về Android phàn nàn rằng Intent không rõ ràng. Tôi đã thử nghiệm một dự án ví dụ AIDL cũng sử dụng setPackage() trên cùng một điện thoại và nó hoạt động. Với setPackage(), lỗi cũng biến mất trong dự án của tôi – TyrManuZ