Activity中使用AIDL让Service与Activity通信

 
简易计算器,默认执行1+1的计算,点击go按钮执行计算,先看效果图,如下




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

Java代码 复制代码  收藏代码
  1. // My AIDL file, named SomeClass.aidl   
  2. package com.zhang.test.service;   
  3. // See the list above for which classes need  
  4. // import statements (hint--most of them)   
  5. // Declare the interface.   
  6. interface ICallback {   
  7. // Methods can take 0 or more parameters, and  
  8. // return a value or void.   
  9.   
  10. // Methods can even take other AIDL-defined parameters.  
  11. //BankAccount createAccount(in String name, int startingDeposit, in IAtmService atmService);  
  12. // All non-Java primitive parameters (e.g., int, bool, etc) require  
  13. // a directional tag indicating which way the data will go. Available  
  14. // values are in, out, inout. (Primitives are in by default, and cannot be otherwise).  
  15. // Limit the direction to what is truly needed, because marshalling parameters  
  16. // is expensive.   
  17.   
  18. void showResult(int result);   
  19. }  
// 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);
}


然后再建立一个IService.aidl用来在Activity中接收Service回调,以及在Service中onBind时返回的Binder
注意:aidl中import不能写com.xxx.*,要写全类的路径

Java代码 复制代码  收藏代码
  1. package com.zhang.test.service;   
  2.   
  3. import com.zhang.test.service.ICallback;   
  4.   
  5. interface IService {   
  6.     void registerCallback(ICallback cb);   
  7.     void unregisterCallback(ICallback cb);   
  8. }  
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代码 复制代码  收藏代码
  1. package com.zhang.test.service;   
  2.   
  3. import android.app.Service;   
  4. import android.content.BroadcastReceiver;   
  5. import android.content.Context;   
  6. import android.content.Intent;   
  7. import android.content.IntentFilter;   
  8. import android.os.Handler;   
  9. import android.os.IBinder;   
  10. import android.os.Message;   
  11. import android.os.RemoteCallbackList;   
  12. import android.os.RemoteException;   
  13. import android.util.Log;   
  14.   
  15. public class CalculateService extends Service {   
  16.     private static final String TAG = "MainService";   
  17.   
  18.     public static final String ACTION_CALCUlATE = "action_calculate";   
  19.     private RemoteCallbackList<ICallback> mCallbacks = new RemoteCallbackList<ICallback>();   
  20.   
  21.     private IService.Stub mBinder = new IService.Stub() {   
  22.   
  23.         @Override  
  24.         public void unregisterCallback(ICallback cb) {   
  25.             if (cb != null) {   
  26.                 mCallbacks.unregister(cb);   
  27.             }   
  28.         }   
  29.   
  30.         @Override  
  31.         public void registerCallback(ICallback cb) {   
  32.             if (cb != null) {   
  33.                 mCallbacks.register(cb);   
  34.             }   
  35.         }   
  36.     };   
  37.            
  38.          //这里的BroadcastReceiver实现了Activity主动与Service通信  
  39.     private BroadcastReceiver receiver = new BroadcastReceiver() {   
  40.   
  41.         @Override  
  42.         public void onReceive(Context context, Intent intent) {   
  43.             String action = intent.getAction();   
  44.             if (ACTION_CALCUlATE.equals(action)) {   
  45.                 int first;   
  46.                 int second;   
  47.                 try {   
  48.                     first = Integer.parseInt(intent.getStringExtra("first"));   
  49.                     second = Integer.parseInt(intent.getStringExtra("second"));   
  50.                     callBack(first, second);   
  51.                 } catch (NumberFormatException e) {   
  52.                     e.printStackTrace();   
  53.                 } catch (Exception e) {   
  54.                     e.printStackTrace();   
  55.                 }   
  56.             }   
  57.         }   
  58.     };   
  59.     private Handler mHandler = new Handler() {   
  60.   
  61.         @Override  
  62.         public void handleMessage(Message msg) {   
  63.             //默认计算1+1   
  64.                             callBack(11);   
  65.             super.handleMessage(msg);   
  66.         }   
  67.     };   
  68.   
  69.     @Override  
  70.     public IBinder onBind(Intent intent) {   
  71.         Log.d(TAG, "onBind");   
  72.         return mBinder;   
  73.     }   
  74.   
  75.     @Override  
  76.     public void onCreate() {   
  77.         Log.d(TAG, "onCreate");   
  78.         // 这里不知道为什么,直接使用callback方法回调showResult  
  79.         // mCallbacks.beginBroadcast()是0,需要用handler延迟1000毫秒  
  80.         // 也许是在activity中binService太耗时的原因?   
  81.         mHandler.sendEmptyMessageDelayed(01000);   
  82.         super.onCreate();   
  83.         IntentFilter filter = new IntentFilter(ACTION_CALCUlATE);   
  84.         registerReceiver(receiver, filter);   
  85.   
  86.     }   
  87.   
  88.     @Override  
  89.     public void onDestroy() {   
  90.         mHandler.removeMessages(0);   
  91.         mCallbacks.kill();   
  92.         super.onDestroy();   
  93.     }   
  94.   
  95.     private void callBack(int first, int second) {   
  96.         int N = mCallbacks.beginBroadcast();   
  97.         try {   
  98.             for (int i = 0; i < N; i++) {   
  99.                 mCallbacks.getBroadcastItem(i).showResult(first + second);   
  100.             }   
  101.         } catch (RemoteException e) {   
  102.             Log.e(TAG, "", e);   
  103.         }   
  104.         mCallbacks.finishBroadcast();   
  105.     }   
  106.   
  107. }  
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() {

		@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();
	}

}


然后是CalculateActivity:

Java代码 复制代码  收藏代码
  1. package com.zhang.test;   
  2.   
  3. import android.app.Activity;   
  4. import android.content.ComponentName;   
  5. import android.content.Context;   
  6. import android.content.Intent;   
  7. import android.content.ServiceConnection;   
  8. import android.os.Bundle;   
  9. import android.os.IBinder;   
  10. import android.os.RemoteException;   
  11. import android.util.Log;   
  12. import android.view.View;   
  13. import android.widget.Button;   
  14. import android.widget.CompoundButton;   
  15. import android.widget.EditText;   
  16. import android.widget.TextView;   
  17.   
  18. import com.zhang.test.service.ICallback;   
  19. import com.zhang.test.service.IService;   
  20. import com.zhang.test.service.CalculateService;   
  21.   
  22. public class CalculateActivity extends Activity {   
  23.     private static final String TAG = "MainActivity";   
  24.   
  25.     private IService mService;   
  26.   
  27.     private EditText first;// 第一个计算数  
  28.     private EditText second;// 第二个计算数  
  29.     private Button calculate;// 计算按钮  
  30.     private TextView result;// 计算结果  
  31.   
  32.     /** Called when the activity is first created. */  
  33.     @Override  
  34.     public void onCreate(Bundle savedInstanceState) {   
  35.         super.onCreate(savedInstanceState);   
  36.         setContentView(R.layout.main);   
  37.   
  38.         setUpViews();   
  39.         setUpEvents();   
  40.         Intent i = new Intent(this, CalculateService.class);   
  41.         bindService(i, mConnection, Context.BIND_AUTO_CREATE);   
  42.     }   
  43.   
  44.     private void setUpViews() {   
  45.         first = (EditText) findViewById(R.id.first);   
  46.         second = (EditText) findViewById(R.id.second);   
  47.         calculate = (Button) findViewById(R.id.calculate);   
  48.         result = (TextView) findViewById(R.id.result);   
  49.     }   
  50.   
  51.     private void setUpEvents() {   
  52.         calculate.setOnClickListener(new CompoundButton.OnClickListener() {   
  53.   
  54.             @Override  
  55.             public void onClick(View v) {   
  56.                 Intent intent = new Intent(CalculateService.ACTION_CALCUlATE);   
  57.                 intent.putExtra("first", first.getText().toString());   
  58.                 intent.putExtra("second", second.getText().toString());   
  59.                 sendBroadcast(intent);   
  60.             }   
  61.         });   
  62.     }   
  63.   
  64.     @Override  
  65.     protected void onDestroy() {   
  66.         if (mService != null) {   
  67.             try {   
  68.                 mService.unregisterCallback(mCallback);   
  69.             } catch (RemoteException e) {   
  70.                 Log.e(TAG, "", e);   
  71.             }   
  72.         }   
  73.         // destroy的时候不要忘记unbindService   
  74.         unbindService(mConnection);   
  75.         super.onDestroy();   
  76.     }   
  77.   
  78.     /**  
  79.      * service的回调方法  
  80.      */  
  81.     private ICallback.Stub mCallback = new ICallback.Stub() {   
  82.   
  83.         @Override  
  84.         public void showResult(int result) {   
  85.             Log.d(TAG, "result : " + result);   
  86.             CalculateActivity.this.result.setText(result + "");   
  87.         }   
  88.     };   
  89.   
  90.     /**  
  91.      * 注册connection  
  92.      */  
  93.     private ServiceConnection mConnection = new ServiceConnection() {   
  94.   
  95.         @Override  
  96.         public void onServiceDisconnected(ComponentName name) {   
  97.             Log.d(TAG, "onServiceDisconnected");   
  98.             mService = null;   
  99.         }   
  100.   
  101.         @Override  
  102.         public void onServiceConnected(ComponentName name, IBinder service) {   
  103.             Log.d(TAG, "onServiceConnected");   
  104.             mService = IService.Stub.asInterface(service);   
  105.             try {   
  106.                 mService.registerCallback(mCallback);   
  107.             } catch (RemoteException e) {   
  108.                 Log.e(TAG, "", e);   
  109.             }   
  110.         }   
  111.     };   
  112. }  
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);
			}
		}
	};
}

最后不要忘记在manifest中加上service标记:

Java代码 复制代码  收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.       package="com.zhang.test"  
  4.       android:versionCode="1"  
  5.       android:versionName="1.0">   
  6.     <application android:icon="@drawable/icon" android:label="@string/app_name">   
  7.         <activity android:name=".CalculateActivity"  
  8.                   android:label="@string/app_name">   
  9.             <intent-filter>   
  10.                 <action android:name="android.intent.action.MAIN" />   
  11.                 <category android:name="android.intent.category.LAUNCHER" />   
  12.             </intent-filter>   
  13.         </activity>   
  14.         <service android:name=".service.CalculateService" />   
  15.     </application>   
  16.     <uses-sdk android:minSdkVersion="3" />   
  17.   
  18. </manifest>  
<?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:

Java代码 复制代码  收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="horizontal" >   
  6.   
  7.     <TextView   
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:text="计算:" />   
  11.   
  12.     <EditText   
  13.         android:id="@+id/first"  
  14.         android:layout_width="50dip"  
  15.         android:layout_height="wrap_content"  
  16.         android:text="1" />   
  17.   
  18.     <TextView   
  19.         android:layout_width="wrap_content"  
  20.         android:layout_height="wrap_content"  
  21.         android:text="+" />   
  22.   
  23.     <EditText   
  24.         android:id="@+id/second"  
  25.         android:layout_width="50dip"  
  26.         android:layout_height="wrap_content"  
  27.         android:text="1" />   
  28.   
  29.     <TextView   
  30.         android:layout_width="wrap_content"  
  31.         android:layout_height="wrap_content"  
  32.         android:text="=" />   
  33.   
  34.     <TextView   
  35.         android:id="@+id/result"  
  36.         android:layout_width="wrap_content"  
  37.         android:layout_height="wrap_content" />   
  38.   
  39.     <Button   
  40.         android:id="@+id/calculate"  
  41.         android:layout_width="wrap_content"  
  42.         android:layout_height="wrap_content"  
  43.         android:text="go" />   
  44.   
  45. </LinearLayout>  
<?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)

源码见附件
  • 大小: 30.4 KB
  • 大小: 7.4 KB
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值