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两个进程间的通信,即相互调用了对方的对象。
时间: 2024-09-10 23:54:21