首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

Activity中运用AIDL让Service与Activity通信

2012-07-29 
Activity中使用AIDL让Service与Activity通信简易计算器,默认执行1+1的计算,点击go按钮执行计算,先看效果图

Activity中使用AIDL让Service与Activity通信
简易计算器,默认执行1+1的计算,点击go按钮执行计算,先看效果图,如下




首先建立一个ICallback.aidl文件,作为Activity中的回调方法

// 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.*,要写全类的路径

package com.zhang.test.service;import com.zhang.test.service.ICallback;interface IService {void registerCallback(ICallback cb);void unregisterCallback(ICallback cb);}


接下来是service,CalculateService.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<ICallback> mCallbacks = new RemoteCallbackList<ICallback>();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:

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标记:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.zhang.test"      android:versionCode="1"      android:versionName="1.0">    <application android:icon="@drawable/icon" android:label="@string/app_name">        <activity android:name=".CalculateActivity"                  android:label="@string/app_name">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity><service android:name=".service.CalculateService" />    </application>    <uses-sdk android:minSdkVersion="3" /></manifest>


布局文件,main.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="horizontal" >    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="计算:" />    <EditText        android:id="@+id/first"        android:layout_width="50dip"        android:layout_height="wrap_content"        android:text="1" />    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="+" />    <EditText        android:id="@+id/second"        android:layout_width="50dip"        android:layout_height="wrap_content"        android:text="1" />    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="=" />    <TextView        android:id="@+id/result"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <Button        android:id="@+id/calculate"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="go" /></LinearLayout>


运行程序,查看Logcat
结果如下:



总结:
通过aidl总算实现了Service与Activity的通信,写起来麻烦点,使用诸如ContentProvider,Broadcast等也可以实现.
这样做很像是在使用MVC设计模式(Activity负责View,Service以及其他类负责Model,aidl(ServiceConnection)负责Controller)

源码见附件

热点排行