我在服务器和服务器之间通过AIDL传输parcelable对象时收到对象Marshall错误客户端作为两个不同的Xamarin Android应用程序(或者具有不同的服务流程):
07-11 17:30:35.971 I/mono-stdout(23384):
Java.Lang.IllegalStateException: Bad magic number for Bundle: 0x610072
Java.Lang.IllegalStateException: Bad magic number for Bundle: 0x610072
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <3fd174ff54b146228c505f23cf75ce71>:0
at Java.Interop.JniEnvironment+InstanceMethods.CallObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo
method, Java.Interop.JniArgumentValue* args) [0x00069] in
<bd30a18775d94dc8b6263aecd1ca9077>:0
at Android.Runtime.JNIEnv.CallObjectMethod (System.IntPtr jobject, System.IntPtr jmethod, Android.Runtime.JValue* parms)
[0x0000e] in <9ab9faae1b4b4f0da28e7c4ac61e2c78>:0
at Android.OS.IParcelableCreatorInvoker.CreateFromParcel (Android.OS.Parcel source) [0x0005a] in
<9ab9faae1b4b4f0da28e7c4ac61e2c78>:0
at AIDLBindingServer.IAdditionServiceStub+Proxy.GetParcelableObj () [0x0002f] in
C:\Projects\xn\aidl\AIDLBindingLib\AIDLBindingServer\AIDLBindingServer\obj\Release\aidl\IAdditionService.cs:124
at Xamarin.AidlDemo.Activity1.<OnStart>b__10_0 (System.Object sender, System.EventArgs e) [0x000c5] in
C:\Projects\xn\aidl\AIDLDemoClient\AIDLDemoClient\Activity1.cs:53
--- End of managed Java.Lang.IllegalStateException stack trace ---
java.lang.IllegalStateException: Bad magic number for Bundle: 0x610072
07-11 17:30:35.976 I/mono-stdout(23384): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()
[0x0000c] in <3fd174ff54b146228c505f23cf75ce71>:0
at android.os.BaseBundle.readFromParcelInner(BaseBundle.java:1443)
at android.os.BaseBundle.<init>(BaseBundle.java:128)
at android.os.Bundle.<init>(Bundle.java:69)
at android.os.Parcel.readBundle(Parcel.java:1879)
at android.os.Parcel.readBundle(Parcel.java:1863)
at android.os.Bundle$1.createFromParcel(Bundle.java:1127)
at android.os.Bundle$1.createFromParcel(Bundle.java:1126)
at mono.android.view.View_OnClickListenerImplementor.n_onClick(Native
Method)
at mono.android.view.View_OnClickListenerImplementor.onClick(View_OnClickListenerImplementor.java:30)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
07-11 17:30:35.976 I/mono-stdout(23384): at Java.Interop.JniEnvironment+InstanceMethods.CallObjectMethod
(Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo
method, Java.Interop.JniArgumentValue* args) [0x00069] in
<bd30a18775d94dc8b6263aecd1ca9077>:0
07-11 17:30:35.976 I/mono-stdout(23384): at Android.Runtime.JNIEnv.CallObjectMethod (System.IntPtr jobject,
System.IntPtr jmethod, Android.Runtime.JValue* parms) [0x0000e] in
<9ab9faae1b4b4f0da28e7c4ac61e2c78>:0
07-11 17:30:35.976 I/mono-stdout(23384): at Android.OS.IParcelableCreatorInvoker.CreateFromParcel
(Android.OS.Parcel source) [0x0005a] in
<9ab9faae1b4b4f0da28e7c4ac61e2c78>:0
07-11 17:30:35.976 I/mono-stdout(23384): at AIDLBindingServer.IAdditionServiceStub+Proxy.GetParcelableObj ()
[0x0002f] in
C:\Projects\xn\aidl\AIDLBindingLib\AIDLBindingServer\AIDLBindingServer\obj\Release\aidl\IAdditionService.cs:124
07-11 17:30:35.976 I/mono-stdout(23384): at Xamarin.AidlDemo.Activity1.<OnStart>b__10_0 (System.Object sender,
System.EventArgs e) [0x000c5] in
C:\Projects\xn\aidl\AIDLDemoClient\AIDLDemoClient\Activity1.cs:53
07-11 17:30:35.976 I/mono-stdout(23384): --- End of managed Java.Lang.IllegalStateException stack trace ---
07-11 17:30:35.977 I/mono-stdout(23384): java.lang.IllegalStateException: Bad magic number for Bundle: 0x610072
07-11 17:30:35.977 I/mono-stdout(23384): at android.os.BaseBundle.readFromParcelInner(BaseBundle.java:1443)
07-11 17:30:35.977 I/mono-stdout(23384): at android.os.BaseBundle.<init>(BaseBundle.java:128)
07-11 17:30:35.977 I/mono-stdout(23384): at android.os.Bundle.<init>(Bundle.java:69)
07-11 17:30:35.977 I/mono-stdout(23384): at android.os.Parcel.readBundle(Parcel.java:1879)
07-11 17:30:35.977 I/mono-stdout(23384): at android.os.Parcel.readBundle(Parcel.java:1863)
07-11 17:30:35.977 I/mono-stdout(23384): at android.os.Bundle$1.createFromParcel(Bundle.java:1127)
07-11 17:30:35.977 I/mono-stdout(23384): at android.os.Bundle$1.createFromParcel(Bundle.java:1126)
07-11 17:30:35.977 I/mono-stdout(23384): at mono.android.view.View_OnClickListenerImplementor.n_onClick(Native
Method)
07-11 17:30:35.977 I/mono-stdout(23384): at mono.android.view.View_OnClickListenerImplementor.onClick(View_OnClickListenerImplementor.java:30)
07-11 17:30:35.977 I/mono-stdout(23384): at android.view.View.performClick(View.java:5637)
07-11 17:30:35.977 I/mono-stdout(23384): at android.view.View$PerformClick.run(View.java:22429)
07-11 17:30:35.977 I/mono-stdout(23384): at android.os.Handler.handleCallback(Handler.java:751)
07-11 17:30:35.978 I/mono-stdout(23384): at android.os.Handler.dispatchMessage(Handler.java:95)
07-11 17:30:35.978 I/mono-stdout(23384): at android.os.Looper.loop(Looper.java:154)
07-11 17:30:35.978 I/mono-stdout(23384): at android.app.ActivityThread.main(ActivityThread.java:6119)
07-11 17:30:35.978 I/mono-stdout(23384): at java.lang.reflect.Method.invoke(Native Method)
07-11 17:30:35.978 I/mono-stdout(23384): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
07-11 17:30:35.978 I/mono-stdout(23384): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
IAdditionService.aidl
package AIDLBindingServer;
interface IAdditionService {
int add(in int value1, in int value2);
ParcelableObj getParcelableObj();
}
ParcelableObj.aidl
package AIDLBindingServer;
parcelable ParcelableObj;
ParcelableObj.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.OS;
using Android.Runtime;
using Java.Interop;
using Java.Lang;
using Object = Java.Lang.Object;
namespace AIDLBindingServer
{
[Register("AIDLBindingServer.ParcelableObj", DoNotGenerateAcw = false)]
public class ParcelableObj : Object, IParcelable
{
/*private static readonly long serialVersionUID = -3892107077759983950L;*/
// static readonly int BUNDLE_MAGIC = 0x4C444E42;
[ExportField ("CREATOR")]
public static ParcelableObjCreator InitializeCreator()
{
return new ParcelableObjCreator();
}
public ParcelableObj()
{
}
public string Name
{
get;
set;
}
public ParcelableObj(string Name)
{
this.Name = Name;
}
#region IParcelable implementation
public int DescribeContents()
{
return 0;
}
public void WriteToParcel(Parcel dest, ParcelableWriteFlags flags)
{
dest.WriteString(this.Name);
}
#endregion
}
[Register("AIDLBindingServer.ParcelableObjCreator", DoNotGenerateAcw = false)]
public sealed class ParcelableObjCreator : Object, IParcelableCreator
{
public Object CreateFromParcel(Parcel source)
{
return new ParcelableObj(source.ReadString());
}
public Object[] NewArray(int size)
{
return new Java.Lang.Object[size];
// throw new UnsupportedOperationException();
}
}
}
AdditionService.cs
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
namespace Xamarin.AidlDemo
{
[Service(Process = "com.xamarin.additionservice")]
[IntentFilter(new String[] {"com.xamarin.additionservice"})]
public class AdditionService: Service
{
private static readonly string Tag = "AdditionService";
private AdditionServiceBinder _binder;
public override void OnCreate ()
{
base.OnCreate ();
Log.Debug (Tag, "Addition Service created.");
}
public override IBinder OnBind (Intent intent)
{
_binder = new AdditionServiceBinder();
return _binder;
}
public override void OnDestroy ()
{
base.OnDestroy ();
Log.Debug (Tag, "Addition service stopped.");
}
}
}
AdditionServiceBinder.cs
using Android.Util;
using System;
using AIDLBindingServer;
namespace Xamarin.AidlDemo
{
public class AdditionServiceBinder: IAdditionServiceStub, IAdditionService
{
public static readonly string Tag = "AdditionServiceBinder";
public override int Add (int value1, int value2)
{
Log.Debug (Tag, "AdditionService.Add({0}, {1})", value1, value2);
return value1 + value2;
}
public override ParcelableObj GetParcelableObj()
{
/*throw new NotImplementedException();*/
return new ParcelableObj("raheem"/*,"32"*/);
}
}
}
AdditionServiceConnection.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AIDLBindingCLib;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace Xamarin.AidlDemo
{
class AdditionServiceConnection : Java.Lang.Object, IServiceConnection
{
Activity1 _activity;
public AdditionServiceConnection (Activity1 activity)
{
_activity = activity;
}
public IAdditionService Service
{
get; private set;
}
public void OnServiceConnected (ComponentName name, IBinder service)
{
Service = IAdditionServiceStub.AsInterface(service);
_activity.Service = (IAdditionService) Service;
_activity.IsBound = Service != null;
}
public void OnServiceDisconnected (ComponentName name)
{
_activity.Service = null;
_activity.IsBound = false;
}
}
}
Activity1.cs
using System;
using AIDLBindingCLib;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Util;
using Android.Widget;
using Android.OS;
using Java.Interop;
namespace Xamarin.AidlDemo
{
[Activity (Label = "AIDL Demo Server", MainLauncher = true)]
public class Activity1 : Activity
{
public static readonly String Tag = "Activity1";
private AdditionServiceConnection _serviceConnection;
public IAdditionService Service { get; set; }
public bool IsBound { get; set; }
protected override void OnStart ()
{
base.OnStart ();
InitService ();
var button1 = FindViewById<Button> (Resource.Id.buttonCalc);
button1.Click += (sender, e) => {
if (IsBound) {
var text1 = FindViewById<EditText> (Resource.Id.value1);
var text2 = FindViewById<EditText> (Resource.Id.value2);
var primitive_result = FindViewById<TextView> (Resource.Id.primitive_result);
var parcelable_result = FindViewById<TextView> (Resource.Id.parcelable_result);
var connection_result = FindViewById<TextView> (Resource.Id.connection_result);
int v1;
int v2;
int v3;
if(Int32.TryParse (text2.Text, out v2) && Int32.TryParse (text1.Text, out v1)) {
v3 = Service.Add (v1, v2);
} else {
v3 = 0;
var builder = new AlertDialog.Builder(this);
builder.SetMessage("Spaces or special character are not allowed");
builder.SetNeutralButton("OK", (source, eventArgs) => {});
builder.Show();
}
primitive_result.Text = v3.ToString();
try
{
ParcelableObj obj = Service.GetParcelableObj();
parcelable_result.Text= "parcelable_result:"+ obj.Name;
}
catch (Exception exception)
{
Console.WriteLine(exception);
parcelable_result.Text = "parcelable_result:" + exception.Message;
}
} else {
Log.Warn (Tag, "The AdditionService is not bound");
}
};
}
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.main);
}
protected override void OnDestroy ()
{
base.OnDestroy ();
ReleaseService ();
}
private void InitService ()
{
_serviceConnection = new AdditionServiceConnection (this);
var additionServiceIntent = new Intent ("com.xamarin.additionservice");
additionServiceIntent.SetPackage("AIDLDemo.AIDLDemo");
bool ret = BindService (additionServiceIntent, _serviceConnection, Bind.AutoCreate);
Log.Debug (Tag, "Service initialized:"+ret);
try
{
var connection_result = FindViewById<TextView>(Resource.Id.connection_result);
connection_result.Text = "Service initialized:" + ret;
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private void ReleaseService ()
{
if (IsBound) {
ApplicationContext.UnbindService (_serviceConnection);
IsBound = false;
_serviceConnection = null;
Log.Debug (Tag, "Service released.");
}
}
}
}
生成IAdditionServiceStub
// This file is automatically generated and not supposed to be modified.
using System;
using Boolean = System.Boolean;
using String = System.String;
using List = Android.Runtime.JavaList;
using Map = Android.Runtime.JavaDictionary;
namespace Xamarin.AidlDemo
{
public interface IAdditionService : global::Android.OS.IInterface
{
int Add (int value1, int value2);
global::Xamarin.AidlDemo.ParcelableObj GetParcelableObj ();
}
public abstract class IAdditionServiceStub : global::Android.OS.Binder, global::Android.OS.IInterface, Xamarin.AidlDemo.IAdditionService
{
const string descriptor = "Xamarin.AidlDemo.IAdditionService";
public IAdditionServiceStub ()
{
this.AttachInterface (this, descriptor);
}
public static Xamarin.AidlDemo.IAdditionService AsInterface (global::Android.OS.IBinder obj)
{
if (obj == null)
return null;
var iin = (global::Android.OS.IInterface) obj.QueryLocalInterface (descriptor);
if (iin != null && iin is Xamarin.AidlDemo.IAdditionService)
return (Xamarin.AidlDemo.IAdditionService) iin;
return new Proxy (obj);
}
public global::Android.OS.IBinder AsBinder ()
{
return this;
}
protected override bool OnTransact (int code, global::Android.OS.Parcel data, global::Android.OS.Parcel reply, int flags)
{
switch (code) {
case global::Android.OS.BinderConsts.InterfaceTransaction:
reply.WriteString (descriptor);
return true;
case TransactionAdd: {
data.EnforceInterface (descriptor);
int arg0 = default (int);
arg0 = data.ReadInt ();
int arg1 = default (int);
arg1 = data.ReadInt ();
var result = this.Add (arg0, arg1);
reply.WriteNoException ();
reply.WriteInt (result);
return true;
}
case TransactionGetParcelableObj: {
data.EnforceInterface (descriptor);
var result = this.GetParcelableObj ();
reply.WriteNoException ();
if (result != null) { reply.WriteInt (1); result.WriteToParcel (reply, global::Android.OS.ParcelableWriteFlags.ReturnValue); } else reply.WriteInt (0);
return true;
}
}
return base.OnTransact (code, data, reply, flags);
}
public class Proxy : Java.Lang.Object, Xamarin.AidlDemo.IAdditionService
{
global::Android.OS.IBinder remote;
public Proxy (global::Android.OS.IBinder remote)
{
this.remote = remote;
}
public global::Android.OS.IBinder AsBinder ()
{
return remote;
}
public string GetInterfaceDescriptor ()
{
return descriptor;
}
public int Add (int value1, int value2)
{
global::Android.OS.Parcel __data = global::Android.OS.Parcel.Obtain ();
global::Android.OS.Parcel __reply = global::Android.OS.Parcel.Obtain ();
int __result = default (int);
try {
__data.WriteInterfaceToken (descriptor);
__data.WriteInt (value1);
__data.WriteInt (value2);
remote.Transact (IAdditionServiceStub.TransactionAdd, __data, __reply, 0);
__reply.ReadException ();
__result = __reply.ReadInt ();
} finally {
__reply.Recycle ();
__data.Recycle ();
}
return __result;
}
public global::Xamarin.AidlDemo.ParcelableObj GetParcelableObj ()
{
global::Android.OS.Parcel __data = global::Android.OS.Parcel.Obtain ();
global::Android.OS.Parcel __reply = global::Android.OS.Parcel.Obtain ();
global::Xamarin.AidlDemo.ParcelableObj __result = default (global::Xamarin.AidlDemo.ParcelableObj);
try {
__data.WriteInterfaceToken (descriptor);
remote.Transact (IAdditionServiceStub.TransactionGetParcelableObj, __data, __reply, 0);
__reply.ReadException ();
__result = __reply.ReadInt () != 0 ? (global::Xamarin.AidlDemo.ParcelableObj) global::Android.OS.Bundle.Creator.CreateFromParcel (__reply) : null;
} finally {
__reply.Recycle ();
__data.Recycle ();
}
return __result;
}
}
internal const int TransactionAdd = global::Android.OS.Binder.InterfaceConsts.FirstCallTransaction + 0;
internal const int TransactionGetParcelableObj = global::Android.OS.Binder.InterfaceConsts.FirstCallTransaction + 1;
public abstract int Add (int value1, int value2);
public abstract global::Xamarin.AidlDemo.ParcelableObj GetParcelableObj ();
}
}
让我知道如何使用Xamarin Android中的两个应用程序或进程之间的parcellable对象修复此编组错误
答案 0 :(得分:1)
似乎Xamarin AIDL生成器中存在错误。
请注意IAdditionServiceStub中的这一行(在嵌套类Proxy
内):
__result = __reply.ReadInt () != 0 ? (global::Xamarin.AidlDemo.ParcelableObj) global::Android.OS.Bundle.Creator.CreateFromParcel (__reply) : null;
看起来完全是胡说八道:代码使用Android.OS.Bundle.Creator.CreateFromParcel
将IPC响应解码为Bundle
的实例,然后尝试将结果转换为ParcelableObj
。
您的ParcelableObj
当然不是Bundle
的实例。事件(如果是,代码仍然不正确) - 创建Parcelable类的唯一合适方法是使用该类的CREATOR
字段,例如ParcelableObj.Creator.CreateFromParcel
。使用相同的* .aidl文件创建一个Java项目,并尝试将Google的 aidl 工具生成的代码与您在上面发布的IAdditionServiceStub进行比较, - 您将自己看到问题。
我没有足够精通C#来确定错误原因,但您应该尝试升级Xamarin安装。也许错误已经修复了。如果不是,请尝试在Xamarin bugtracker上创建一个问题(如果还没有问题)。
与此同时,在Xamarin方面解决错误之前,您有几个选择。