RPC:进程间通讯,
AIDL:android interface definition language 安卓接口定义语言,
在版本4.0之前使用时可以直接使用隐式意图去绑定service,但是在4.0之后到去使用就先得把隐式意图转为显示意图才能调用另一个进程里的方法
需要注的事项:
1.包名,aidl名称必须一致
终端:
第一步:定义aidl接口:
interface AlipayRemoteService {
boolean forwardPayMoney(float money);
}
第二步:写一个服务回调
//服务里面的方法
public class AlipayService extends Service {
@Override
public IBinder onBind(Intent intent) {
return new PayController();//返回一个Binder对象
}
//回调时使用的方法
public boolean pay(float money) {
Toast.makeText(getApplicationContext(), "支付" + money + "成功",
Toast.LENGTH_SHORT).show();
return true;
}
//Stub里面自动生成接口里的类
public class PayController extends Stub {
@Override
public boolean forwardPayMoney(float money) throws RemoteException {
return pay(money);
}
}
}
第三步:在清单文件里面注册Service并指定动作为隐式意图
<service android:name="com.example.rpcdemo.service.AlipayService" >
<intent-filter>
<action android:name="com.ciat.alipay" >
</action>
</intent-filter>
</service>
第四步:开户服务 :
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent i=new Intent(this,AlipayService.class);
startService(i);
}
}
2.android4.0版本以后不支持隐士意图,需要转换成显示意图
客户端:
interface AlipayRemoteService {
boolean forwardPayMoney(float money);
}
第一步:创建并绑定意图对象,这里需要把隐式意图转换成显示意图
Intent service = new Intent();
service.setAction("com.ciat.alipay");//因为service在另一个客户里面,所以只能使用的是隐式意图
final Intent eintent = new Intent(createExplicitFromImplicitIntent(
this, service));//然后隐式版本4.0以后不能使用,所以要先转为显示意图后能才使用
boolean bindService = bindService(eintent, new MyConnection(),BIND_AUTO_CREATE);//通过续写服务来获取终端里面的方法
if (bindService) {
Toast.makeText(this, "服务绑定成功", 1).show();
} else {
Toast.makeText(this, "服务绑定失败", 1).show();
}
第二步:实现服务连接通道
//获取终端服务里的方法
class MyConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Toast.makeText(getApplicationContext(), "服务已经连接...",
Toast.LENGTH_SHORT).show();
remoteService = Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(getApplicationContext(), "服务已经断开...",
Toast.LENGTH_SHORT).show();
}
}
第三步:转换意图对象
/**
* 隐士意图转换为显示意图方法
* @param context
* @param implicitIntent
* @return Intent
*/
public static Intent createExplicitFromImplicitIntent(Context context,
Intent implicitIntent) {
// Retrieve all services that can match the given intent
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent,
0);
// Make sure only one match was found
if (resolveInfo == null || resolveInfo.size() != 1) {
return null;
}
// Get component info and create ComponentName
ResolveInfo serviceInfo = resolveInfo.get(0);
String packageName = serviceInfo.serviceInfo.packageName;
String className = serviceInfo.serviceInfo.name;
ComponentName component = new ComponentName(packageName, className);
// Create a new intent. Use the old one for extras and such reuse
Intent explicitIntent = new Intent(implicitIntent);
// Set the component to be explicit
explicitIntent.setComponent(component);
return explicitIntent;
}
第四步:回调终端方法
//调用终端方法转参
public void pay(View v) {
if (TextUtils.isEmpty(et.getText().toString().trim())) {
Toast.makeText(this, "请输入金钱数", 0).show();
return;
}
Float money = Float.valueOf(et.getText().toString().trim());
try {
remoteService.forwardPayMoney(money);
} catch (RemoteException e) {
e.printStackTrace();
Toast.makeText(this, "付款失败", 1).show();
return;
}
Toast.makeText(this, "成功转账:" + money + "元!", 0).show();
}