Android AIDL和Service and Activity parceable似乎传递了默认的类值

时间:2014-07-07 16:24:58

标签: android parcelable aidl

我有一个奇怪的问题,我创建了一个Android服务,以及一个消耗它的小部件。我有一些复杂的对象通过AIDL在两者之间发送。注册我的回调没有问题,服务正确地填充数据并将其发送到回调,但是当我在writeToParcel方法上放置一个断点,并在窗口小部件上激活我的调试器时,我注意到该方法正在序列化默认类值,而不是服务填充它的那些。有没有人有任何关于弄清楚发生了什么的建议。

这是我的目标:

Node.java:

package my.unique.package.name.service;


import java.util.ArrayList;
import java.util.HashMap;

import android.os.Parcel;
import android.os.Parcelable;

public class Node implements Parcelable {
    protected int mNodeId;
    protected double mBatteryLevel = -1;
    protected double mBatteryTemp;
    protected String mRadioName;
    protected String mIPAddress;
    protected String mFirmwareVersion;
    protected String mModel;
    protected String mSerialNumber;
    protected String mUptime;
    protected double mTemp;
    protected double mInputVoltage;
    protected double mBatteryClockVoltage;
    protected String mSource;
    protected double mLatitude;
    protected double mLongitude;
    protected double mAltitude;
    protected String mFixType;
    protected int    mSatellites;
    protected String mNTPServer;

    protected ArrayList<Neighbor> mNeighbors;
    protected HashMap<String, String> mManagedNodes;
    protected HashMap<String, String> mOtherNodes;

    public Node()
    {

    }
    /**
     * Node Constructor for Parcelable Interface
     * 
     * @param in
     *            Parcel in
     */
    public Node(Parcel in) {
        String[] data = new String[19];
        in.readStringArray(data);
        mNodeId = Integer.parseInt(data[0]);
        mBatteryLevel = Double.parseDouble(data[1]);
        mBatteryTemp = Double.parseDouble(data[2]);
        mRadioName = data[3];
        mIPAddress = data[4];
        mFirmwareVersion = data[5];
        mModel = data[6];
        mSerialNumber = data[7];
        mUptime = data[8];
        mTemp = Double.parseDouble(data[9]);
        mInputVoltage = Double.parseDouble(data[10]);
        mBatteryClockVoltage = Double.parseDouble(data[11]);
        mSource = data[12];
        mLatitude= Double.valueOf(data[13]);
        mLongitude = Double.valueOf(data[14]);
        mAltitude = Double.valueOf(data[15]);
        mFixType = data[16];
        mSatellites = Integer.valueOf(data[17]);
        mNTPServer = data[18];
    }

    //Removed public get/set methods...

    public static final Parcelable.Creator<Node> CREATOR = new Parcelable.Creator<Node>() {
        public Node createFromParcel(Parcel in) {
            return new Node(in);
        }

        public Node[] newArray(int size) {
            return new Node[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeStringArray(new String[] { String.valueOf(mNodeId),
                String.valueOf(mBatteryLevel), String.valueOf(mBatteryTemp),
                mRadioName, mIPAddress, mFirmwareVersion, mModel,
                mSerialNumber, mUptime, String.valueOf(mTemp),
                String.valueOf(mInputVoltage),
                String.valueOf(mBatteryClockVoltage),
                mSource, String.valueOf(mLatitude), String.valueOf(mLongitude), 
                String.valueOf(mAltitude), mFixType, 
                String.valueOf(mSatellites), mNTPServer});
    }
}

Node.aidl:

package my.unique.package.namespace.service;

parcelable Node;

这是服务通知回调的方式

private void notifyCallbacksOfUpdate(Node updated) {
        final int N = mNodeUpdatedCallbacks.beginBroadcast();
        for (int i = 0; i < N; i++) {
            try {
                mNodeUpdatedCallbacks.getBroadcastItem(i).NodeUpdated(updated);
            } catch (RemoteException e) {
                // The RemoteCallbackList will take care of removing
                // the dead object for us.
            }
        }
        mNodeUpdatedCallbacks.finishBroadcast();
    }

编辑:来自消费者的附加代码

MyApplication.java

public void bindConnection()
    {
        if (mServiceConnection == null) {
            // create connection to service
            mServiceConnection = new MyServiceConnection(this);
            Intent i = new Intent("my.unique.package.IService");
            boolean bound = bindService(i, mConnection,
                    Context.BIND_AUTO_CREATE);
            Log.v("Service Bound: ", String.valueOf(bound));
        }
    }

连接类

import my.unique.package.service.IService;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;

public class MyServiceConnection implements ServiceConnection {

    private IService service;
    private Context mContext;
    public MyServiceConnection(Context context)
    {
        mContext = context;
    }

    public void onServiceConnected(ComponentName name, IBinder boundService) {
      service = IService.Stub.asInterface(boundService);
      if(service != null)
      {
          mContext.sendBroadcast(new Intent(MyApplication.BOUND_TO_SERVICE));
      }
    }

    public void onServiceDisconnected(ComponentName name) {
      service = null;
    }

    protected IService getService()
    {
        return service;
    }
  }

在这里,我收到有关节点更新的通知,服务发送正确的信息,但这里是接收默认值的地方。节点对象类与服务和小部件在同一个jar中,只是不同的包,AIDL是否需要复制到所有包,或者它可以跨包引用它。

private INodeUpdatedCallback nodeUpdated = new INodeUpdatedCallback.Stub() {

@Override
public void NodeUpdated(Node nodeInfo) throws RemoteException {
    Log.v("Node Updated: ", nodeInfo.getRadioIP());
    if (nodeInfo.getIP().equalsIgnoreCase(mIp)
            && requestedLogin) {
        requestedLogin = false;
        ViewSwitcher vs = (ViewSwitcher) findViewById(R.id.vsSettings);
        if (vs.getDisplayedChild() != VIEW_SETTINGS) {
            vs.setInAnimation(AnimationUtils.loadAnimation(
                    WaveRelaySettingsActivity.this, R.anim.fade_in));
            vs.setOutAnimation(AnimationUtils.loadAnimation(
                    WaveRelaySettingsActivity.this, R.anim.fade_out));
            vs.setDisplayedChild(VIEW_SETTINGS);

        }
    }
}
};

Aidl for call stub of回调

package my.unique.namespace.service;
import my.unique.namespace.service.Node;

oneway interface INodeUpdatedCallback {
    void NodeUpdated(out Node nodeInfo);
}

1 个答案:

答案 0 :(得分:3)

我认为您需要在AIDL中将out更改为in

package my.unique.namespace.service;
import my.unique.namespace.service.Node;

oneway interface INodeUpdatedCallback {
    void NodeUpdated(in Node nodeInfo);
}