尝试与其他应用

时间:2017-01-02 21:55:25

标签: android aidl

我希望使用AIDL获得一些使用android IPC的经验。我想看看是否可以在两个不同的Android应用程序之间进行通信。

我的问题是在第二个应用中调用bindService,与第一个应用的FactorialService进行通信,服务总是失败。我尝试调用MainActivity的第一个应用活动bindService始终记录bindService返回false的事实。加上MainActivity(实现ServiceConnection)第二个应用程序(客户端应用程序)永远不会调用它的回调方法onServiceConnected

因此,在运行名为FactorialService

的服务的第一个应用程序
  • 我定义了一个 界面,IFactorialService.aidl

    package com.simonlbc.factorialcommon;
    
    import com.simonlbc.factorialcommon.FactorialRequest;
    import com.simonlbc.factorialcommon.FactorialResponse;
    
    interface IFactorialService {
        FactorialResponse fact(in FactorialRequest r);
    }
    

FactorialRequest包含输入数字(比如n)。 fact会返回n!以及其他信息。

  • 在同一个应用程序中,我创建了一个类IFactorialServiceImplem 实现该aidl接口。

    package com.example.simonlbc.factorialservice;
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.os.SystemClock;
    import com.simonlbc.factorialcommon.FactorialResponse;
    import com.simonlbc.factorialcommon.FactorialRequest;
    
    public class IFactorialServiceImplem extends com.simonlbc.factorialcommon.IFactorialService.Stub {
    
        public long recursiveFact(int n) {
            if (n < 0)
                throw new IllegalArgumentException("input fa");
            if (n == 1 || n == 0)
                return 1;
            else {
                return n * recursiveFact(n-1);
            }
        }
    
        public long iterativeFact(int n) {
            long res = 1;
            for (int i = 1; i <= n; i++)
                res *= i;
            return res;
        }
        public FactorialResponse fact(FactorialRequest r) {
            long timeInMillis = SystemClock.uptimeMillis();
            long result = 0;
    
            switch(r.getChoice()) {
                case RECURSIVE:
                    result = recursiveFact(r.getInNb());
                    break;
                case ITERATIVE:
                    result = iterativeFact(r.getInNb());
            }
            timeInMillis = SystemClock.uptimeMillis() - timeInMillis;
    
            return new FactorialResponse(result, timeInMillis);
        }
    }
    
    • 然后我创建了一个Service,用于将IFactorialService实例传达给可能的客户:

      package com.example.simonlbc.factorialservice;
      import android.app.Service;
      import android.content.Intent;
      import android.os.IBinder;
      import android.util.Log;
      import com.simonlbc.factorialcommon.IFactorialService;
      
      public class FactorialService extends Service {
      
          private IFactorialServiceImplem s = null;
          private static final String TAG = "FactorialService";
      
          @Override
          public void onCreate() {
              super.onCreate();
              s = new IFactorialServiceImplem();
              Log.d(TAG, "onCreate'd");
          }
              @Override
              public IBinder onBind(Intent intent) {
                  Log.d(TAG, "onBind()'d");
                  return this.s;
              }
      
              @Override
              public boolean onUnbind(Intent intent) {
                  Log.d(TAG, "onUnbind()'d");
                  return super.onUnbind(intent);
              }
      
              @Override
              public void onDestroy() {
                  Log.d(TAG, "onDestroy()'d");
                  s = null;
                  super.onDestroy();
              }
          }
      
      • 第一个“服务”应用程序的清单如下:

      <application
          android:allowBackup="true"
          android:icon="@mipmap/ic_launcher"
          android:label="@string/app_name"
          android:supportsRtl="true"
          android:theme="@style/AppTheme">
      
          <service
              android:name=".FactorialService">
              <!--
              android:enabled="true"
              android:exported="true"
              android:process=":remote"
              -->
      
              <intent-filter>
                  <action android:name="com.example.simonlbc.factorialservice.FactorialService" />
              </intent-filter>
          </service>
      
          <activity android:name=".MainActivity">
              <intent-filter>
                  <action android:name="android.intent.action.MAIN" />
      
                  <category android:name="android.intent.category.LAUNCHER" />
              </intent-filter>
          </activity>
      </application>
      

    • 第一个应用包含一个Launcher活动,它只是启动服务:

          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_service);
              curPackage = getString(R.string.packageService);
              MainActivity.this.startService(
                      new Intent()
                              .setAction(curPackage + ".FactorialService")
                              .setPackage(curPackage)
              );
          }
      
  • 我的第二个应用的启动器活动如下:

    public class MainActivity extends Activity implements View.OnClickListener, ServiceConnection

    我想要第二个应用的MainActivity来 与第一个应用IFactorialService进行通信。在onResume我 尝试绑定第一个应用程序的服务:

       @Override
       protected void onResume() {
           super.onResume();
           Intent i = new Intent();
           i.setAction("com.example.simonlbc.factorialservice.FactorialService");
           i.setPackage("com.example.simonlbc");
           if (!super.bindService(i, this, BIND_AUTO_CREATE))
               Log.w(TAG, "Failed to bind our service!!!");
       }
    

但似乎bindService失败了。确实每次我暂停应用程序并返回它,或启动它。 “无法绑定我们的服务!!!”显示。

请注意,这两个应用程序共享一个Android库模块,其中包含所需的aidl文件的定义。

你看到任何允许bindService()工作的东西吗?

1 个答案:

答案 0 :(得分:1)

您为什么使用super.bindservice()?相反,你可以尝试这个getApplicationContext().bindservice()

此外,如果这也不起作用,请尝试以下修改代码:

   Intent i = new Intent("com.example.simonlbc.factorialservice.FactorialService");
   if(getApplicationContext().startService(i) != null){
       if (!getApplicationContext().bindService(i, serviceConnection, 0))
           Log.w(TAG, "Failed to bind our service!!!");
   }

其中seriveConnection是服务连接的对象(我不想将this用于ServiceConnection)。此外,您的服务应该具有正确的Action设置,否则它将无法启动