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兩個進程間的通信,即相互調用了對方的對象。
最後更新:2017-04-02 06:52:19