我试图将MainActivity绑定到前台服务,然后得到以下异常,已经搜索了一个多小时,不知道我做错了什么,请救我。
java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.leonard.sg.okcoin.service.SyncAndTradeService$SyncAndTradeBinder
at com.leonard.sg.okcoin.MainActivity$1.onServiceConnected(MainActivity.java:50)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1101)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1118)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5227)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
at dalvik.system.NativeStart.main(Native Method)
我的MainActivity中的代码:
private SyncAndTradeService syncAndTradeService;
private boolean hasBounded = false;
private Intent syncAndTradeServiceIntent;
private ServiceConnection syncAndTradeServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
SyncAndTradeService.SyncAndTradeBinder syncAndTradeBinder = (SyncAndTradeService.SyncAndTradeBinder) service;
syncAndTradeService = syncAndTradeBinder.getSyncAndTradeService();
hasBounded = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
syncAndTradeService = null;
hasBounded = false;
}
};
我尝试在onCreate方法中执行此操作:
syncAndTradeServiceIntent = new Intent(this, SyncAndTradeService.class);
bindService(syncAndTradeServiceIntent, syncAndTradeServiceConnection, Context.BIND_AUTO_CREATE);
这是我的服务代码:
public class SyncAndTradeService extends Service {
public static final int MY_FOREGROUND_SERVICE_START_ID = 996539;
private IBinder syncAndTradeBinder = new SyncAndTradeBinder();
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startSyncAndTradeService();
return Service.START_REDELIVER_INTENT;
}
@Override
public IBinder onBind(Intent intent) {
return syncAndTradeBinder;
}
@Override
public boolean onUnbind(Intent intent) {
return false;
}
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
}
public class SyncAndTradeBinder extends Binder {
public SyncAndTradeService getSyncAndTradeService() {
return SyncAndTradeService.this;
}
}
private void startSyncAndTradeService() {
startForeground(MY_FOREGROUND_SERVICE_START_ID, buildFixedNotification());
}
private Notification buildFixedNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new Notification.Builder(this)
.setContentTitle("OKCoin Robot")
.setContentText("OKCoin robot is running in background")
.setSmallIcon(R.drawable.bitcoin)
.setContentIntent(pendingIntent)
.build();
return notification;
}
}
这是我在Manifest.xml中声明我的服务
<service
android:name=".service.SyncAndTradeService"
android:exported="false"
android:icon="@drawable/bitcoin"
android:process=":SyncAndTrade">
</service>
答案 0 :(得分:16)
不能等待,所以一直保持研究我一整天都有空,幸运的是找到了解决方案,希望这可以帮助像我这样的初学者。
定义您的AIDL界面
package com.leonard.sg.okcoin.service.robot.aidl;
interface ISyncAndTradeService {
boolean startTradeEngine();
}
然后将您的服务中的onBind方法更改为:
@Override
public IBinder onBind(Intent intent) {
return new ISyncAndTradeService.Stub() {
@Override
public boolean startTradeEngine() throws RemoteException {
return false;
}
};
}
然后将构建服务连接类细化为:
private ISyncAndTradeService syncAndTradeService;
private boolean hasBounded = false;
private Intent syncAndTradeServiceIntent;
private ServiceConnection syncAndTradeServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
syncAndTradeService = ISyncAndTradeService.Stub.asInterface((IBinder) service);
hasBounded = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
syncAndTradeService = null;
hasBounded = false;
}
};
然后一切都会正常工作
但这引发了另一个问题,根据属性&#39; android:process&#39;的google文档。服务声明,我们可以这样做:
机器人:过程 要运行服务的进程的名称。通常,应用程序的所有组件都在为应用程序创建的默认进程中运行。它与应用程序包具有相同的名称。元素的process属性可以为所有组件设置不同的默认值。但组件可以使用自己的流程属性覆盖默认值,允许您跨多个流程分布应用程序。 如果分配给此属性的名称以冒号开头(&#39;:&#39;),则会在需要时创建一个专用于应用程序的新进程,并且该服务在该进程中运行。如果进程名称以小写字符开头,则服务将在该名称的全局进程中运行,前提是它具有此权限。这允许不同应用程序中的组件共享进程,从而减少资源使用。
但在实践中,如果我宣布&#39; android:process&#39;从字符开始,无论是小写还是大写,我都会收到此错误:
DEVICE SHELL COMMAND: pm install -r "/data/local/tmp/com.leonard.sg.okcoin"
pkg: /data/local/tmp/com.leonard.sg.okcoin
Failure [INSTALL_PARSE_FAILED_MANIFEST_MALFORMED]
唯一的选择是从&#39;开始:&#39;或&#39;。&#39;