Activity中使用AIDL让Service与Activity通信
16lz
2021-01-25
简易计算器,默认执行1+1的计算,点击go按钮执行计算,先看效果图,如下
首先建立一个ICallback.aidl文件,作为Activity中的回调方法
Java代码
然后再建立一个IService.aidl用来在Activity中接收Service回调,以及在Service中onBind时返回的Binder
注意:aidl中import不能写com.xxx.*,要写全类的路径
Java代码
接下来是service,CalculateService.java
Java代码
然后是CalculateActivity:
Java代码
最后不要忘记在manifest中加上service标记:
Java代码
布局文件,main.xml:
Java代码
运行程序,查看Logcat
结果如下:
总结:
通过aidl总算实现了Service与Activity的通信,写起来麻烦点,使用诸如ContentProvider,Broadcast等也可以实现.
这样做很像是在使用MVC设计模式(Activity负责View,Service以及其他类负责Model,aidl(ServiceConnection)负责Controller)
源码见附件
首先建立一个ICallback.aidl文件,作为Activity中的回调方法
Java代码
- // My AIDL file, named SomeClass.aidl
- package com.zhang.test.service;
- // See the list above for which classes need
- // import statements (hint--most of them)
- // Declare the interface.
- interface ICallback {
- // Methods can take 0 or more parameters, and
- // return a value or void.
- // Methods can even take other AIDL-defined parameters.
- //BankAccount createAccount(in String name, int startingDeposit, in IAtmService atmService);
- // All non-Java primitive parameters (e.g., int, bool, etc) require
- // a directional tag indicating which way the data will go. Available
- // values are in, out, inout. (Primitives are in by default, and cannot be otherwise).
- // Limit the direction to what is truly needed, because marshalling parameters
- // is expensive.
- void showResult(int result);
- }
// My AIDL file, named SomeClass.aidlpackage com.zhang.test.service;// See the list above for which classes need// import statements (hint--most of them)// Declare the interface.interface ICallback {// Methods can take 0 or more parameters, and// return a value or void.// Methods can even take other AIDL-defined parameters.//BankAccount createAccount(in String name, int startingDeposit, in IAtmService atmService);// All non-Java primitive parameters (e.g., int, bool, etc) require// a directional tag indicating which way the data will go. Available// values are in, out, inout. (Primitives are in by default, and cannot be otherwise).// Limit the direction to what is truly needed, because marshalling parameters// is expensive.void showResult(int result);}
然后再建立一个IService.aidl用来在Activity中接收Service回调,以及在Service中onBind时返回的Binder
注意:aidl中import不能写com.xxx.*,要写全类的路径
Java代码
- package com.zhang.test.service;
- import com.zhang.test.service.ICallback;
- interface IService {
- void registerCallback(ICallback cb);
- void unregisterCallback(ICallback cb);
- }
package com.zhang.test.service;import com.zhang.test.service.ICallback;interface IService {void registerCallback(ICallback cb);void unregisterCallback(ICallback cb);}
接下来是service,CalculateService.java
Java代码
- package com.zhang.test.service;
- import android.app.Service;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.Handler;
- import android.os.IBinder;
- import android.os.Message;
- import android.os.RemoteCallbackList;
- import android.os.RemoteException;
- import android.util.Log;
- public class CalculateService extends Service {
- private static final String TAG = "MainService";
- public static final String ACTION_CALCUlATE = "action_calculate";
- private RemoteCallbackList
mCallbacks = new RemoteCallbackList(); - private IService.Stub mBinder = new IService.Stub() {
- @Override
- public void unregisterCallback(ICallback cb) {
- if (cb != null) {
- mCallbacks.unregister(cb);
- }
- }
- @Override
- public void registerCallback(ICallback cb) {
- if (cb != null) {
- mCallbacks.register(cb);
- }
- }
- };
- //这里的BroadcastReceiver实现了Activity主动与Service通信
- private BroadcastReceiver receiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (ACTION_CALCUlATE.equals(action)) {
- int first;
- int second;
- try {
- first = Integer.parseInt(intent.getStringExtra("first"));
- second = Integer.parseInt(intent.getStringExtra("second"));
- callBack(first, second);
- } catch (NumberFormatException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- };
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- //默认计算1+1
- callBack(1, 1);
- super.handleMessage(msg);
- }
- };
- @Override
- public IBinder onBind(Intent intent) {
- Log.d(TAG, "onBind");
- return mBinder;
- }
- @Override
- public void onCreate() {
- Log.d(TAG, "onCreate");
- // 这里不知道为什么,直接使用callback方法回调showResult
- // mCallbacks.beginBroadcast()是0,需要用handler延迟1000毫秒
- // 也许是在activity中binService太耗时的原因?
- mHandler.sendEmptyMessageDelayed(0, 1000);
- super.onCreate();
- IntentFilter filter = new IntentFilter(ACTION_CALCUlATE);
- registerReceiver(receiver, filter);
- }
- @Override
- public void onDestroy() {
- mHandler.removeMessages(0);
- mCallbacks.kill();
- super.onDestroy();
- }
- private void callBack(int first, int second) {
- int N = mCallbacks.beginBroadcast();
- try {
- for (int i = 0; i < N; i++) {
- mCallbacks.getBroadcastItem(i).showResult(first + second);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- }
- mCallbacks.finishBroadcast();
- }
- }
package com.zhang.test.service;import android.app.Service;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.os.RemoteCallbackList;import android.os.RemoteException;import android.util.Log;public class CalculateService extends Service {private static final String TAG = "MainService";public static final String ACTION_CALCUlATE = "action_calculate";private RemoteCallbackList mCallbacks = new RemoteCallbackList();private IService.Stub mBinder = new IService.Stub() {@Overridepublic void unregisterCallback(ICallback cb) {if (cb != null) {mCallbacks.unregister(cb);}}@Overridepublic void registerCallback(ICallback cb) {if (cb != null) {mCallbacks.register(cb);}}}; //这里的BroadcastReceiver实现了Activity主动与Service通信private BroadcastReceiver receiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (ACTION_CALCUlATE.equals(action)) {int first;int second;try {first = Integer.parseInt(intent.getStringExtra("first"));second = Integer.parseInt(intent.getStringExtra("second"));callBack(first, second);} catch (NumberFormatException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}}};private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {//默认计算1+1 callBack(1, 1);super.handleMessage(msg);}};@Overridepublic IBinder onBind(Intent intent) {Log.d(TAG, "onBind");return mBinder;}@Overridepublic void onCreate() {Log.d(TAG, "onCreate");// 这里不知道为什么,直接使用callback方法回调showResult// mCallbacks.beginBroadcast()是0,需要用handler延迟1000毫秒// 也许是在activity中binService太耗时的原因?mHandler.sendEmptyMessageDelayed(0, 1000);super.onCreate();IntentFilter filter = new IntentFilter(ACTION_CALCUlATE);registerReceiver(receiver, filter);}@Overridepublic void onDestroy() {mHandler.removeMessages(0);mCallbacks.kill();super.onDestroy();}private void callBack(int first, int second) {int N = mCallbacks.beginBroadcast();try {for (int i = 0; i < N; i++) {mCallbacks.getBroadcastItem(i).showResult(first + second);}} catch (RemoteException e) {Log.e(TAG, "", e);}mCallbacks.finishBroadcast();}}
然后是CalculateActivity:
Java代码
- package com.zhang.test;
- 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.CompoundButton;
- import android.widget.EditText;
- import android.widget.TextView;
- import com.zhang.test.service.ICallback;
- import com.zhang.test.service.IService;
- import com.zhang.test.service.CalculateService;
- public class CalculateActivity extends Activity {
- private static final String TAG = "MainActivity";
- private IService mService;
- private EditText first;// 第一个计算数
- private EditText second;// 第二个计算数
- private Button calculate;// 计算按钮
- private TextView result;// 计算结果
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- setUpViews();
- setUpEvents();
- Intent i = new Intent(this, CalculateService.class);
- bindService(i, mConnection, Context.BIND_AUTO_CREATE);
- }
- private void setUpViews() {
- first = (EditText) findViewById(R.id.first);
- second = (EditText) findViewById(R.id.second);
- calculate = (Button) findViewById(R.id.calculate);
- result = (TextView) findViewById(R.id.result);
- }
- private void setUpEvents() {
- calculate.setOnClickListener(new CompoundButton.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(CalculateService.ACTION_CALCUlATE);
- intent.putExtra("first", first.getText().toString());
- intent.putExtra("second", second.getText().toString());
- sendBroadcast(intent);
- }
- });
- }
- @Override
- protected void onDestroy() {
- if (mService != null) {
- try {
- mService.unregisterCallback(mCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- }
- }
- // destroy的时候不要忘记unbindService
- unbindService(mConnection);
- super.onDestroy();
- }
- /**
- * service的回调方法
- */
- private ICallback.Stub mCallback = new ICallback.Stub() {
- @Override
- public void showResult(int result) {
- Log.d(TAG, "result : " + result);
- CalculateActivity.this.result.setText(result + "");
- }
- };
- /**
- * 注册connection
- */
- private ServiceConnection mConnection = new ServiceConnection() {
- @Override
- public void onServiceDisconnected(ComponentName name) {
- Log.d(TAG, "onServiceDisconnected");
- mService = null;
- }
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- Log.d(TAG, "onServiceConnected");
- mService = IService.Stub.asInterface(service);
- try {
- mService.registerCallback(mCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- }
- }
- };
- }
package com.zhang.test;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.CompoundButton;import android.widget.EditText;import android.widget.TextView;import com.zhang.test.service.ICallback;import com.zhang.test.service.IService;import com.zhang.test.service.CalculateService;public class CalculateActivity extends Activity {private static final String TAG = "MainActivity";private IService mService;private EditText first;// 第一个计算数private EditText second;// 第二个计算数private Button calculate;// 计算按钮private TextView result;// 计算结果/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);setUpViews();setUpEvents();Intent i = new Intent(this, CalculateService.class);bindService(i, mConnection, Context.BIND_AUTO_CREATE);}private void setUpViews() {first = (EditText) findViewById(R.id.first);second = (EditText) findViewById(R.id.second);calculate = (Button) findViewById(R.id.calculate);result = (TextView) findViewById(R.id.result);}private void setUpEvents() {calculate.setOnClickListener(new CompoundButton.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(CalculateService.ACTION_CALCUlATE);intent.putExtra("first", first.getText().toString());intent.putExtra("second", second.getText().toString());sendBroadcast(intent);}});}@Overrideprotected void onDestroy() {if (mService != null) {try {mService.unregisterCallback(mCallback);} catch (RemoteException e) {Log.e(TAG, "", e);}}// destroy的时候不要忘记unbindServiceunbindService(mConnection);super.onDestroy();}/** * service的回调方法 */private ICallback.Stub mCallback = new ICallback.Stub() {@Overridepublic void showResult(int result) {Log.d(TAG, "result : " + result);CalculateActivity.this.result.setText(result + "");}};/** * 注册connection */private ServiceConnection mConnection = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {Log.d(TAG, "onServiceDisconnected");mService = null;}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {Log.d(TAG, "onServiceConnected");mService = IService.Stub.asInterface(service);try {mService.registerCallback(mCallback);} catch (RemoteException e) {Log.e(TAG, "", e);}}};}
最后不要忘记在manifest中加上service标记:
Java代码
- <?xml version="1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android" - package="com.zhang.test"
- android:versionCode="1"
- android:versionName="1.0">
- "@drawable/icon" android:label="@string/app_name">
- ".CalculateActivity"
- android:label="@string/app_name">
-
- "android.intent.action.MAIN" />
-
"android.intent.category.LAUNCHER" /> -
".service.CalculateService" /> -
"3" />
<?xml version="1.0" encoding="utf-8"?>
布局文件,main.xml:
Java代码
- <?xml version="1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="horizontal" >
-
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="计算:" />
-
- android:id="@+id/first"
- android:layout_width="50dip"
- android:layout_height="wrap_content"
- android:text="1" />
-
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="+" />
-
- android:id="@+id/second"
- android:layout_width="50dip"
- android:layout_height="wrap_content"
- android:text="1" />
-
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="=" />
-
- android:id="@+id/result"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- android:id="@+id/calculate"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="go" />
<?xml version="1.0" encoding="utf-8"?>
运行程序,查看Logcat
结果如下:
总结:
通过aidl总算实现了Service与Activity的通信,写起来麻烦点,使用诸如ContentProvider,Broadcast等也可以实现.
这样做很像是在使用MVC设计模式(Activity负责View,Service以及其他类负责Model,aidl(ServiceConnection)负责Controller)
源码见附件
- 大小: 30.4 KB
- 大小: 7.4 KB
- TestService.rar (48.7 KB)
- 下载次数: 4
- 查看图片附件
更多相关文章
- 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
- Android中继承RadioButton后,点击不能选中
- Android(安卓)Intent初步试用
- android 常用系统修改和设置
- android MMI(多媒体)接口--音乐播放器
- 在eclipse中查看Android各版本源代码
- android虚席总结(16.08.26)Activity的生命周期
- 基站定位
- android下的多线程下载实现方法