Android远程service aidl的用法
AIDL即android 接口定义语言,概念不多说,网上有太多的帖子介绍概念。本文只想说明一下aidl的用法。由于最近开发一个播放器的项目使用了aidl。aidl是解决进程间通信用的。在本例中就是Activity(即client端)与Service(即服务端)的通信。
首先,定义Aidl文件,如Service中暴露给Activity的接口可以定义在aidl文件中,反之也一样。本文中,Service给Activity使用接口文件是ServiceAidl.aidl而Activity给Service回调的接口在ActivityAidl.aidl文件中
package org.august.music;
import org.august.music.ActivityAidl;
interface ServiceAidl{
package org.august.music;
interface ActivityAidl{
void callActivity();
}
第二步,写Service。写一个MyService继承于Service类,并在onBind()方法中 返回ServiceAidl.Stub对象
具体看下面代码
package org.august.music;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;
public class MyService extends Service {
public static final String SERVICE_NAME = "org.august.music.start.MyService";
private static final String TAG = "MyService";
private ActivityAidl activityAidlCallBack;
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i(TAG, "onStart");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
Log.i(TAG, "onRebind");
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "onUnbind");
return super.onUnbind(intent);
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private ServiceAidl.Stub mBinder = new ServiceAidl.Stub() {
@Override
public void callService() throws RemoteException {
Log.i(TAG, "Call Service's method ****** callService()");
Toast.makeText(getApplicationContext(), "Call Service's method ****** callService()", 1000).show();
activityAidlCallBack.callActivity();
}
@Override
public void registActivityAidl(ActivityAidl activityAidl)
throws RemoteException {
activityAidlCallBack = activityAidl;
}
};
}
说明一下在ServiceAidl.Stub mBinder = new ServiceAidl.Stub(){}里面的callService() 和registActivityAidl(ActivityAidl activityAidl)方法就是在Activity将会被调用到的。而registActivityAidl(ActivityAidl )是在Activity中给Service的回调方法注册到Service中去,这样Service中就可以调用Activity的接口了
package org.august.music;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private Button startBtn;
private Button stopBtn;
private Button callServiceBtn;
private ServiceAidl myService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
init();
}
private void init() {
startBtn = (Button)findViewById(R.id.start_service);
stopBtn = (Button)findViewById(R.id.stop_service);
callServiceBtn = (Button)findViewById(R.id.call_service_method);
startBtn.setOnClickListener(btnListener);
stopBtn.setOnClickListener(btnListener);
callServiceBtn.setOnClickListener(btnListener);
}
private View.OnClickListener btnListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.start_service:
startService();
break;
case R.id.stop_service:
stopService();
break;
case R.id.call_service_method:
if(myService == null){
Toast.makeText(getApplicationContext(), "Service 为空", 1000).show();
return;
}
try {
myService.callService();
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
};
private void startService() {
Intent intent = new Intent();
intent.setAction(MyService.SERVICE_NAME);
bindService(intent, serviceConn, Context.BIND_AUTO_CREATE);
startService(intent);
Log.i(TAG, "********startService()");
}
private void stopService() {
}
private ServiceConnection serviceConn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
myService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myService = ServiceAidl.Stub.asInterface(service);
try {
myService.registActivityAidl(activityAidl);
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
private ActivityAidl activityAidl = new ActivityAidl.Stub() {
@Override
public void callActivity() throws RemoteException {
Log.i(TAG, "callActivity()");
Toast.makeText(getApplicationContext(), "call activity", 1000).show();
}
};
}
在activity中有三个按钮分别为 start service ; stop service ;callService
各个按钮的动作顾名思义啦。在Activity中会看到在ServiceConnection中 会拿到ServiceAidl (myService)的实例
并且将activityAidl的引用注册到了myService中
这个程序跑起来的顺序是,启动Activity后,并start service后 点击callServiceBtn,就会调用MyService中实现的callService()接口,而在callService中又调用了activityAidl即Activity的回调callActivity()的
这样就模拟了 Activity 与Service两个进程间的通信,即相互调用了对方的对象。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库