0

My issue seems to be similar to this question and this one but it is a bit different.

I am making an AIDL service that is in a Library project and using it in my application. I have a class Vehicle that is in my application that I have made parcelable so that I can use it in my interface. (I would like to get a List of vehicles from my service that is in the library to my application)

Do I need a Vehicle.java in both the application and the library?

Do I need a Vehicle.aidl in both?

I had Vehicle.java AND Vehicle.aidl in both application and library and I began running into a problem in my application that when I called a method from my interface eclipse wanted me to define it as the Vehicle of the library class and not the application(although they are the same and both parcelable).

public List<Vehicle> getVehicles(){...code... }

In an effort to resolve this, I tried to make it the application's vehicle class rather than the library's vehicle class in my IRemoteInterface.aidl(in the listed variation below, i get an error that it can't find the import. In other variations like having it be List and no import, it says unknown return type).

  package LIBRARY;


import LIBRARY.RelPoint;
import LIBRARY.IRemoteServiceCallback;
import LIBRARY.FleetStatus;
import APPLICATION.Vehicle;


interface IRemoteInterface {

    int getPid();

    void registerCallback(IRemoteServiceCallback callback);
    void unregisterCallback(IRemoteServiceCallback callback);

    List<Vehicle> getVehicles();

}

Here is my parcelable Vehicle class from the application :

package APPLICATION;

import java.util.Date;

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


public class Vehicle implements Parcelable {
    public static final String TAG = "Vehicle";

    long vehicleID;
    long trackID;
    String vehicleName;



     public static final Parcelable.Creator<Vehicle> CREATOR = new Parcelable.Creator<Vehicle>() {

            public Vehicle createFromParcel(Parcel src) {
                return new Vehicle(src);
            }

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

        };



        public Vehicle(Parcel src) {
            readFromParcel(src);
        }

        public void writeToParcel(Parcel dest, int flags) {
            dest.writeLong(vehicleID);
            dest.writeLong(trackID);
            dest.writeString(vehicleName);
        }

        public void readFromParcel(Parcel src) {
            vehicleID = src.readLong();
            trackID   = src.readLong();
            vehicleName = src.readString();

        }

        public int describeContents() {
            // nothing special
            return 0;
        }


    public Vehicle() {

    }

    //getter and setter methods below that I removed



}
Community
  • 1
  • 1
benzabill
  • 259
  • 1
  • 8
  • 21

2 Answers2

4

I'm reasonably certain you need to have the Parcelable classes in the same package on both ends (which is what you end up with by using the one from APPLICATION on the library side, I would just do it the other way around). This package has to also be the one declared in the corresponding aidl file.

I'd suggest to use a subpackage like com.example.interop to make this cleaner (i.e., separate the shared objects in their own package). Both sides should then have a Java file in that package + an aidl file that declares it.

Delyan
  • 8,881
  • 4
  • 37
  • 42
  • Thanks for coming here! Remove Vehicle class from application? I need to use Vehicle there for other things so does that mean I need to reference Vehicle as LIBRARY.Vehicle? Is there no way for the Vehicle in Library to use the Vehicle in Application?(I am getting a vehicle from the service and I want to put that vehicle into an SQLite database that I have setup) – benzabill Jul 30 '13 at 19:58
  • When you say "library", do you mean Android Library or a library package that gets installed? I.e., how many apks does this setup produce? – Delyan Jul 30 '13 at 19:59
  • A library package that gets installed. It is my boss's code and I am altering it for what I need. I have it set as a dependency or whatever(I have successfully used the library previously for other things) – benzabill Jul 30 '13 at 20:01
  • So ideally any reference in LIBRARY to Vehicle is APPLICATION's Vehicle – benzabill Jul 30 '13 at 20:02
  • Can you explain the second part a bit more? Create a package that has Vehicle.java and Vehicle.aidl? Where does this package go(Inside application, library or a new place?) – benzabill Jul 30 '13 at 20:12
  • Well, either that or use the package from the library on the application side. It really doesn't matter if it's a new package or an existing one as long as it's the same on both ends (and is declared that way in the aidl). – Delyan Jul 30 '13 at 20:13
  • So I should make a package and put it in both Application and Library? Then I import Vehicle and then use it? – benzabill Jul 30 '13 at 20:16
  • Cleanest solution IMO, as it's super clear on both sides which objects will get shared through services, so it's easier to think about security, too. – Delyan Jul 30 '13 at 20:16
  • That makes sense. On the topic of repeating files in both locations... IRemoteInterface.aidl and IRemoteServiceCallback.aidl, should they be in both or only the service? – benzabill Jul 30 '13 at 20:18
  • Both, since both parties need to know what the interface of the exported service is. – Delyan Jul 30 '13 at 20:20
  • I have to say @Delyan, you have been beyond helpful once again! – benzabill Jul 30 '13 at 20:28
  • One more thing! I am getting a "type mismatch" where it is cannot convert from "Vehicle" to "MainActivity.Vehicle" (mainactivity is my main in application) – benzabill Jul 30 '13 at 20:40
  • SORRY, I did not notice that I had a Fleet.java leftover in my library – benzabill Jul 30 '13 at 20:48
  • I am stuck by an issue that I am hoping you can help me with. Could you take a look at the SO? http://stackoverflow.com/questions/18448216/unable-to-execute-dex-multiple-dex-files-define-lcom-shared-classes Thank you! – benzabill Aug 26 '13 at 16:07
0

I had the same issue and got it working with the following folder and file structure:

  1. Under src/main create a directory named "aidl". This is where Android by default looks for .aidl files
  2. Under "aidl/" create a directory "com/mypackage/util"
  3. Then under "src/main/aidl/com/mypackage/util" put the .aidl file of your service and a separate .aidl file of your Parcelable. If the service is called IGetCards then the aidl file must be named IGetCards.aidl and if you Parcelable is called Cards then it must be in its own file named Cards.aidl.

In src/main/aidl/com/mypackage/util/IGetCards.aidl:

package com.mypackage.util;

import com.mypackage.util.Cards;

/** Example service interface */
interface IGetCards {

    /** Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    Cards getCards();
}

In src/main/aidl/com/mypackage/util/Cards.aidl:

package com.mypackage.util;

parcelable Cards;
  1. Check each file has a package statement at the top and that the service file IGetCards has an import statement at the top importing the Cards class.
  2. Now in the Java directory src/main/java/com/mypackage/util, put a corresponding Cards.kt file which implements the interface. Make sure Cards.kt has a package statement at the top that matches Cards.aidl.

In src/main/java/com/mypackage/util/Cards.kt:

package com.mypackage.util;

class Cards() : Parcelable {
//implement members
...
}

zetatlas
  • 320
  • 2
  • 8