Question

So, Here is my scenario: I have two activity and one service --> all three(classes) requires a return type value from another service(so total 2 activity, 2 service in the application).

i.e: Activity A, starts --> an Activity B and a Service I.

Activity B, starts --> a Service II.

Thereafter, Activity A, B and Service II has to communicate with Service I. Service I is always running behind and never stops once started.

My approach of doing that was as follows:

  1. Write three .aidl files that declares the interface between the four communicating classes.

  2. Create Activity A, then create Service I, Activity B;and from Activity B create Service II.

  3. As Service I can have only one onBind() method, for communicating with the 3 classes at any time, what i'm doing is that all intent from 3 classes are differentiated by assigning different value using setType() property.

  4. Connection is built between each two classes when communication has to be done using initService() and released soon after that using releaseService().

  5. At Service I, the onBind() method has to first check from which of the 3 classes the intent is coming, using getType() property, and return the respective IBinder type.

Now, my problem is at step 5. in which the onBind() method can't perform the operation of checking the getType() of every intents and give the respective return type. Here is my code, for onBinder() method in Service I:

@Override
public IBinder onBind(final Intent intent){
    Log.d(Main_Service.TAG,"it got connected");
    if(intent.getType=="Activity_A")
    {
        return new Activity_A_aidl.Stub() {
            public void function1(int u1,String p1,String p2) throws RemoteException{
                //do something
            }
        };}

    if(intent.getType=="Activity_B"){
        return new Activity_B_aidl.Stub() {
            public int function2() throws RemoteException{//do something
                return some_integer_values;
            }
        };} 
    if(intent.getType()="Service_II"){
        return new Service_II_aidl.Stub(){
            public boolean function3(String u,String p) throws RemoteException{
                //do something

            return boolean_type_variable;
            }
        };}
}

error: as show in LogCat: java.lang.NullPointerException

from all 3 classes(Activity A,B & Service II) where-ever i'm calling one of the functions within try-catch block.

Can anyone tell me where am i going wrong.

-Kishore Debnath, (3rd yr, CSE Student).

Was it helpful?

Solution

Without commenting on your overall design, I would add that the way for the service to differentiate between callers is to use the 'action' property. I don't know what initService() is but when I bind to a remote service, I simply use bindService(). So in your activities have something like:

bindService(new Intent("com.mypackage.myService.ACTION_1"), this,
                Context.BIND_AUTO_CREATE);

or .ACTION_2 or .ACTION_3.

Then in your services manifest have an intent filter:

<intent-filter>
   <action  android:name="com.mypackage.myService.ACTION_1" />
   <action  android:name="com.mypackage.myService.ACTION_2" />
   <action  android:name="com.mypackage.myService.ACTION_3" />
</intent-filter>

Then in the service's onBind(), use intent.getAction() to return a String, identifying the caller. (Use the proper .equals() method to match the String!) and return the appropriate IBinder

I don't think extras on the Intent get passed through to the service. I've never bound to service from another service but I suppose it might work.

As a final point, I only use AIDL and a remote service because for commercial reasons I need the functionality to be split between two separate .apks. There is no good technical reason for me to use it, in fact quite the opposite.

OTHER TIPS

Can anyone tell me where am i going wrong

Well, you asked...

  • It is very unlikely that you need two services, even less likely that you need one service to communicate with another, and even less likely that you need one service to bind to another.

  • It is very unlikely that you need AIDL.

  • It is very unlikely that you really need a service that "is always running behind and never stops once started".

  • Do not use the type property of an Intent for anything but a MIME type. Use an Intent extra for other data you wish to attach to an Intent.

  • Do not compare strings with =, as you are in your third if() statement above.

  • Do not paste code into a StackOverflow question with obvious typos, such as the = one above, or missing the () in calls to getType() as you have in the first two if() statements. If it will not compile, it is not a good sample to demonstrate your understanding of the situation.

Your actual problem most likely comes from code not shown here. You are probably trying to call methods on your Binder objects before the connection has been bound (e.g., before onServiceConnected() is called). Or, possibly, you just have bugs in the implementations of your Binder methods, which you also do not show here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top