简易计算器,默认执行1+1的计算,点击go按钮执行计算,先看效果图,如下
首先建立一个ICallback.aidl文件,作为Activity中的回调方法
然后再建立一个IService.aidl用来在Activity中接收Service回调,以及在Service中onBind时返回的Binder
注意:aidl中import不能写com.xxx.*,要写全类的路径
接下来是service,CalculateService.java
然后是CalculateActivity:
最后不要忘记在manifest中加上service标记:
布局文件,main.xml:
运行程序,查看Logcat
结果如下:
总结:
通过aidl总算实现了Service与Activity的通信,写起来麻烦点,使用诸如ContentProvider,Broadcast等也可以实现.
这样做很像是在使用MVC设计模式(Activity负责View,Service以及其他类负责Model,aidl(ServiceConnection)负责Controller)
源码见附件
![](http://dl.iteye.com/upload/attachment/575691/16c02799-90c9-33ba-8746-ed1eba462e37.jpg)
首先建立一个ICallback.aidl文件,作为Activity中的回调方法
- // 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.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.*,要写全类的路径
- 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
- 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();
- }
- }
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:
- 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. */
@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标记:
- <?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>
<?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>
<?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
结果如下:
![点击查看原始大小图片](http://dl.iteye.com/upload/attachment/575676/44e740c5-bb29-3772-8554-4562e8f1e683.jpg)
总结:
通过aidl总算实现了Service与Activity的通信,写起来麻烦点,使用诸如ContentProvider,Broadcast等也可以实现.
这样做很像是在使用MVC设计模式(Activity负责View,Service以及其他类负责Model,aidl(ServiceConnection)负责Controller)
源码见附件