Android API Guides 阅读笔记(9)----Bound Service
2015-07-31 20:50
435 查看
通过上节的笔记,了解到Service的调用方式有两种,其中使用startService的方式很好理解,就像是启动一个Activity一样,只不过没有UI界面,这节主要记录使用bindService()的方法,通过实例能更好的掌握使用方法
绑定的Service通过一个客户端和服务端的接口(这里客户端指要进行绑定的其他组件,服务端指这个Service),允许其他组件通过绑定,向Service发送请求,接收回应。绑定的Service完全依附与和它绑定的组件,也就是说他们的生命周期是相关的,当绑定它的组件销毁时,Service也就销毁了
一个Service可以同时被启动(通过startService())和被绑定(通过bindService())如果绑定了一个通过启动方式调用的Service,那么在解绑后,这个Service不会被销毁,除非调用stopSelf()或者stopService(),也就是说绑定并不能影响一个启动的Service的生命周期;
首先是Service中的代码:
然后是客户端的代码:
注:上面的例子中没有解绑Service,一般是需要解绑(unbind)的
使用Messenger:如果需要和其他线程通信,就需要用到Messenger,下面是例子
首先是Service的代码:
然后是客户端的代码:
绑定的Service通过一个客户端和服务端的接口(这里客户端指要进行绑定的其他组件,服务端指这个Service),允许其他组件通过绑定,向Service发送请求,接收回应。绑定的Service完全依附与和它绑定的组件,也就是说他们的生命周期是相关的,当绑定它的组件销毁时,Service也就销毁了
一个Service可以同时被启动(通过startService())和被绑定(通过bindService())如果绑定了一个通过启动方式调用的Service,那么在解绑后,这个Service不会被销毁,除非调用stopSelf()或者stopService(),也就是说绑定并不能影响一个启动的Service的生命周期;
使用绑定的Service的方式:
通过继承Binder类:(大多数时候使用这种方式)适用于Service只在当前应用程序中,并且与其他组件在同一个进程中运行,下面是一个使用这种方法的例子首先是Service中的代码:
[code]public class LocalService extends Service { // Binder given to clients private final IBinder mBinder = new LocalBinder(); // Random number generator private final Random mGenerator = new Random(); /** * Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */ public class LocalBinder extends Binder { LocalService getService() { // Return this instance of LocalService so clients can call public methods return LocalService.this; } } @Override public IBinder onBind(Intent intent) { return mBinder; } /** method for clients */ public int getRandomNumber() { return mGenerator.nextInt(100); } }
然后是客户端的代码:
[code]public class BindingActivity extends Activity { LocalService mService; boolean mBound = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onStart() { super.onStart(); // Bind to LocalService Intent intent = new Intent(this, LocalService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // Unbind from the service if (mBound) { unbindService(mConnection); mBound = false; } } /** Called when a button is clicked (the button in the layout file attaches to * this method with the android:onClick attribute) */ public void onButtonClick(View v) { if (mBound) { // Call a method from the LocalService. // However, if this call were something that might hang, then this request should // occur in a separate thread to avoid slowing down the activity performance. int num = mService.getRandomNumber(); Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show(); } } /** Defines callbacks for service binding, passed to bindService() */ private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { // We've bound to LocalService, cast the IBinder and get LocalService instance LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; } @Override public void onServiceDisconnected(ComponentName arg0) { mBound = false; } }; }
注:上面的例子中没有解绑Service,一般是需要解绑(unbind)的
使用Messenger:如果需要和其他线程通信,就需要用到Messenger,下面是例子
首先是Service的代码:
[code]public class MessengerService extends Service { /** Command to the service to display a message */ static final int MSG_SAY_HELLO = 1; /** * Handler of incoming messages from clients. */ class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_SAY_HELLO: Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show(); break; default: super.handleMessage(msg); } } } /** * Target we publish for clients to send messages to IncomingHandler. */ final Messenger mMessenger = new Messenger(new IncomingHandler()); /** * When binding to the service, we return an interface to our messenger * for sending messages to the service. */ @Override public IBinder onBind(Intent intent) { Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show(); return mMessenger.getBinder(); } }
然后是客户端的代码:
[code]public class ActivityMessenger extends Activity { /** Messenger for communicating with the service. */ Messenger mService = null; /** Flag indicating whether we have called bind on the service. */ boolean mBound; /** * Class for interacting with the main interface of the service. */ private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { // This is called when the connection with the service has been // established, giving us the object we can use to // interact with the service. We are communicating with the // service using a Messenger, so here we get a client-side // representation of that from the raw IBinder object. mService = new Messenger(service); mBound = true; } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. mService = null; mBound = false; } }; public void sayHello(View v) { if (!mBound) return; // Create and send a message to the service, using a supported 'what' value Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0); try { mService.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onStart() { super.onStart(); // Bind to the service bindService(new Intent(this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // Unbind from the service if (mBound) { unbindService(mConnection); mBound = false; } } }
绑定的Service的生命周期:
如下图相关文章推荐
- UVA1152-4 Values whose Sum is 0
- UIViewController(视图控制器)下的View切换
- UVA1605-Building for UN
- 仿Uber主界面布局,框架简单实现
- iOS-01-UILabel
- PcDuino初学分享
- BlockingQueue中add,offer,put方法区别
- cmsis-rtos v1.02支持Mail Queue问题
- [UVA11572]Unique Snowflakes[构造]
- UIScrollView的属性总结
- hdu 2767 Proving Equivalences
- AndroidUI设计之 布局管理器 - 详细解析布局实现
- LeetCode N-Queens
- UIImage存为本地文件,UIImage转换为NSData
- Equivalent Strings(Codeforces Round #313 (Div. 2) D)
- Snail—UI学习之UITableView之自定义UITableViewCell
- EasyUI----DataTable转拼EasyUI Tree
- Android UI列表的上拉下拉刷新之Android-PullToRefresh
- Snail—UI学习之UITableView之分组显示
- 【读书笔记】UIFont-动态下载系统提供的字体-官方代码