Android APK之间的调用返回值

来源:互联网 发布:中国平安管培生 知乎 编辑:程序博客网 时间:2024/04/20 04:32

目录(?)[+]

目标:

    假设有2个APK,A和B,A需要调用B里面的一些函数。

方法:

一、反射方式:

假设B里面有一个函数:

package com.ccc.bb;
public class B{
    public static String CMSform(String content,String pin,int filtertype,String certfilt)throws Exception
    {
        return "OK";
    }
}

A的调用方法:

public static String CMSform(Context thisatv,String challenge,String pin) throws Exception
{
 Context c = thisatv.createPackageContext("com.ccc.bApp", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
 Class<?> clazz = c.getClassLoader().loadClass("com.ccc.bb.B");
 Class<?>[] partypes = new Class[4];
 partypes[0]= String.class; //challenge
 partypes[1]= String.class; //pin
 partypes[2]= int.class; //filtertype
 partypes[3]= String.class; //certfilt
 Method method= clazz.getMethod("CMSform",partypes);
 Object[] args = new Object[4];
 args[0]= challenge;
 args[1]= pin;
 args[2]= 0;
 args[3]= null;
 String ret= (String)method.invoke(clazz,args);
 return ret;
}

二、Intent+ComponentName方式:

调用者:startActivityForResult(Intent intent, Int requestCode)
被调用者setResut(int resultCode, Intent intent)设置返回值
调用者被回调:onActivityResult(int requestCode, int resultCode, Intent intent)

在bApp的AndroidManifest.xml:

......

        <activity
            Android:label="CA证书"
            android:name=".CACertsAtv"  
      android:exported="true"/>
在A中调用:

public static void DebugTest2(Context thisatv)
{
 Intent intent = new Intent();
 ComponentName cName = new ComponentName("com.ccc.bApp","com.ccc.bApp.CACertsAtv");
 intent.setComponent(cName);
 Bundle bundle = new Bundle();
 bundle.putString("arge1", "from class A");
 intent.putExtras(bundle);  //传递参数
 thisatv.startActivityForResult(intent,0);
}

A的回调:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (resultCode) { //resultCode为回传的标记,我在B中回传的是RESULT_OK
   case RESULT_OK:
    Bundle b=data.getExtras(); //data为B中回传的Intent
    String str=b.getString("str1");//str即为回传的值
    break;
default:
    break;
    }
}

B:

public class CACertsAtv extends Activity {
 ......
     protected void onCreate(Bundle savedInstanceState) {
         ......
         Intent intent= getIntent();
         String value=intent.getStringExtra("arge1"); //从A传过来的参数
         Bundle b=intent.getExtras();
         b.putString("str1","return string");
         setResult(RESULT_OK, intent); //intent为A传来的带有Bundle的intent,当然也可以自己定义新的Bundle
         finish();//此处一定要调用finish()方法
         ......
     }
 ......

三、Intent方式:

在bApp的AndroidManifest.xml:

......

        <activity android:name=".CACertsAtv">
            <intent-filter>   
            <action android:name="myintent.becalled"/>   
            <category android:name="android.intent.category.DEFAULT"/>   
            </intent-filter>
        </activity>

在A中调用:

public static void DebugTest2(Context thisatv)
 {
  Intent intent = new Intent("myintent.becalled");
  thisatv.startActivity(intent);
 }

四、服务方式:

1)先建立服务接口声明文件AIDL
2)AIDL生成Java接口文件,接口包含抽象方法及Stub、Proxy类
3)在B端实现服务接口,并通过一个实现类来实现android.app.Service接口的方法,来管理服务的生命周期

bApp的mainfest.xml:
......
<service android:name=".MyService"
 android:process=":remote"
>
 <intent-filter>
  <action android:name="com.sample.IStockQuoteService"/>
 </intent-filter>
</service>


B的代码:
//实现AIDL文件定义的服务接口方法
private class MyServiceImpl extends IStockQuoteService.Stub{
    @Override
    public double getPrice(String ticker) throws RemoteException {
        Log.e(TAG, "getPrice");
        return 10.5;
    }
}
//实现服务类,对服务生命周期进行管理
public class MyService extends Service {
    static final String TAG="MyService";
    
    @Override
    public IBinder onBind(Intent arg0) {
        //返回AIDL实现
        return new MyServiceImpl();
    }
    
    @Override
    public void onDestroy(){
        Log.e(TAG, "Release MyService");
        super.onDestroy();
    }
}

A端调用:
public class MYyActivity extends Activity impletents ServiceConnection{
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //返回AIDL接口对象,然后可以调用AIDL方法
            IStockQuoteService iService=IStockQuoteService.Stub.asInterface(service);
            double value=0.0;
            try {
                  value=iService.getPrice("");
            }
            catch (RemoteException e) {
                Log.e(TAG,"调用出错!");
                e.printStackTrace();
            }
            Log.e(TAG, "返回数值为:"+value);
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i(TAG, "释放Service");
        }

 ......
 Intent intent=new Intent("com.sample.IStockQuoteService");
 startService(intent);
 bindService(intent, conn, Context.BIND_AUTO_CREATE);
 ......
};


总结:

三种方式的比较:

《待续》

通过反射方式或Intent方式调用,对比于jar方式调用,2个APK耦合性更低,有益于各自应用的独立升级
原创粉丝点击