1.这段时间,基本上把android的所有知识点遍历过一次,开始写点东西记录了,不然我发现我记忆力谁退的厉害,总是会忘记。

现在在写个音乐播放器的Demo,所以我又看了一遍Service的API,我决定把重点的东西写下来。

首先来看API中对Service的介绍.

1.服务是当不影响用户或者提供给其他应用程序功能的组件。每个服务都应该在配置文件中配置<service>,可以有两种方式启动一个服务。Context.startService和Context.bindService();

2.记住一点,服务和其他的应用组件一样,运行在主线程中。这就意味着,如果你进行播放MP3或者阻塞某些操作,这你就应该另起一条线程去操作。IntentService类是实现了Service的一个标准接口。它拥有自己的线程当调用它的时候。

什么是服务?

1.Service并不是一个分离的进程,它和应用进程有一部分是相同的。

2.Service并不是一个线程。这意味着它不能脱离主线程工作。

3.通过startService()方法启动一个Service的,这种Service一旦启动,调用者和服务之间没有任何关系,即使调用者不存在了,服务仍然会执行。

4.通过bingService()方法启动的Service,这种Service后和调用者进行交互,一但调用了upbindService()方法,服务会停止。

服务的生命周期:

1.通过StartService()启动的线程,会先去运行onCreat()方法,在去调用OnStartCommand()方法包含了客户端传过来的参数,此时,Service会一直运行下去,知道有人调用context.stop() or stopself().多次调用startServiece方法,即使他相当于调用了多次onStartCommand()的方法,无论启动多少次,当调用stop()方法的时候,它一样会停止。

1、当服务第一次启动时,首先执行onCreate,然后onStartCommand,如果服务停止 则执行onDestroy

2、当服务多次启动,则只会执行onStartCommand,不会执行onCreate,停止执行onDestroy


2.对于一个启动的Service,有两个传统的重要的工作模式是通过onStartCommand()返回值决定的。第一:START_STICKY 是明显的按需求进行停止Service或开始Service.

当返回值为START_NOT_STICKY or START_REDELIVER_Intent的时候,这服务被设置为

会一直运行,知道进程给予它命令的。

3 客户端可以通用调用bindService()方法去和服务获得一个长久的联系。他同样睇会产生一个Service如果这个服务并在运行期间的话。但不会再调用onStartCommand()的方法了但onCreat()会被调用。客户端会得到它的onBind(Intent)方法返回的一个IBinder的对象,运行客户端回调给Service.Service会尽可能的保持运行当联系被建立之后(无论客户端是否保持对Service的IBinder对象的引用)。Usually the IBinder returned is for a complex interface that has beenwritten in aidl.


4一个服务可以同时的开启和绑定联系。在这样的情况下,系统会尽可能长的保持服务的运行即使它已开启或者一个或者多个和他联系通过context_BIND_AUTO_CREATE的标示符。一旦这些情况都没有出现,服务的OnDestriy()方法被调用的同时服务会被有效的终止。所有的清理工作(停止线程。注销广播)都会被完成在onDsetroy()中。

5.访问权限:对于一个服务的所有访问都需要在其配置文件中声明一个《Service》标签.通过这样做的话,其他的应用可以通过使用《user-permission》的元素在他们最自己的应用配置文件中,以至于可以和一个线程进行启动,停止,交互。当使用‘conent.StartServie()方法启动一个Service的时候。你可以通过设置Intent。FLAG_GRANT_READ_URI_PERMISSION 或者 Intent.FLAG_GANT_WRITE_URI_PERMISSION在一个Intent中。这将会准予你这个Service可以在Intent中的URI中进行暂时性的访问。访问将会保持知道服务停止。这一工作为了准予访问其他应用的但却没有请求权限保护的

6.Android系统会尽可能长的保证一个已启动的托管进程或者是和客户端交互的Service.当内存太低需要回收资源的时候才会杀死存在的线程。托管服务会的级别会尽可能高。

如果Service正确的调用onCreat(),onStartCommand(),或者onDestroy()的方法,那么托管Service将会成为一个前台进程,并保证它的代码执行不会被kill;

如果服务已经启动了,那么他的托管线程会降低他的级别相对于前台UI来说,但比一些不可见的进程级别高。因为只有一些对于用户可见的服务才不会在系统内存过低的时候被杀死。

如果有多个客户端和Service通信,那么他的级别将永远不比和它通信的UI进程级别低。那么就是,如果一个客户端对于用户是可见的,那么他的服务也是相当于是可见的。

一个已启动的服务可以使用startForeground(int , Notification)API去设置一个Service为一个前台状态。

这些都在意味着你的Service在更多的时间中运行,但他也可能被杀死的。如果这发生了,系统最后将会尝试去重新启动这个服务。一个很重要的结果就是你要在onStartCommand()中去开启新线程去实行你的动作或使用异步Asyn。你可能会用到START_FLAG_REDELIVERY 去获得一个虚拟机的Intent。

其他的应用组件和服务一样,运行在同样的进程中。当然,提高他的级别是相当重要的。

7去了解IPC机制

8。如何和启动一个可交互的Service呢?

第一:创建一个Service的子类。复写oncreat() onStartCommand()方法。

第二:在这个Service子类创建一个内部Binder();在onbind中返回这个新binder;

第三:在这个Service子类中创建公共方法;

public class BinderService extends Service{private static final String TAG = "BinderService";private MyBinder binder =new MyBinder();public class MyBinder extends Binder{public BinderService getService(){return BinderService.this;}}@Overridepublic IBinder onBind(Intent intent){return binder;}public void MyMethod(){Log.i(TAG, "MyMethod()");}    

第四:在启动Service的Activity中实现ServiceConnection接口。

private ServiceConnection conn=new ServiceConnection(){@Overridepublic void onServiceDisconnected(ComponentName name){isConnected=false;}@Overridepublic void onServiceConnected(ComponentName name, IBinder                    binder){       //这里得到返回的binder对象;                        //在binder对象的获取它当前的Service                     MyBinder myBinder= (MyBinder)binder;BinderService service=myBinder.getService();                        //调用这个服务中的方法。service.MyMethod();                       //连接成功的标志isConnected=true;}};

第五:启动服务:

 Intent intent=new Intent(BinderActivity.this, BinderService.class);        bindService(intent, conn, Context.BIND_AUTO_CREATE);                当启动服务的时候,会去获取连接,然后调用服务里的公共方法。                到底是onCreat先执行还是连接类先运行?


第五:停止服务:unbindService(conn);


Servic的API还提供了远程启动一个Service(即使跨进程启动)

第一:创建一个Service的子类。复写oncreat() onStartCommand()方法。

第二:在这个Service子类创建一个内部Binder();在onbind中返回这个新binder;

第三:在Servie子类中new Handler()用来处理Message;

第四:

/**                       * Target we publish for clients to send messages to IncomingHandler.                        */                final Messenger mMessenger = new Messenger(new IncomingHandler());


第五:要为这个服务加上可以允许访问的权限:

  <service android:name=".app.MessengerService"                                 android:process=":remote" />       也可以在process后面的加上其他的名字,在冒号后面可以加上标准的报名Serivce名字。

第六:

 /** * 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 service object we can use to // interact with the service. We are communicating with our // service through an IDL interface, so get a client-side // representation of that from the raw service object. mService = new Messenger(service); mCallbackText.setText("Attached."); // We want to monitor the service for as long as we are // connected to it. try { Message msg = Message.obtain(null, MessengerService.MSG_REGISTER_CLIENT); msg.replyTo = mMessenger; mService.send(msg); // Give it some value as an example. msg = Message.obtain(null, MessengerService.MSG_SET_VALUE, this.hashCode(), 0); mService.send(msg); } catch (RemoteException e) { // In this case the service has crashed before we could even // do anything with it; we can count on soon being // disconnected (and then reconnected if it can be restarted) // so there is no need to do anything here. } // As part of the sample, tell the user what happened. Toast.makeText(Binding.this, R.string.remote_service_connected, Toast.LENGTH_SHORT).show(); } 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; mCallbackText.setText("Disconnected."); // As part of the sample, tell the user what happened. Toast.makeText(Binding.this, R.string.remote_service_disconnected, Toast.LENGTH_SHORT).show(); } }; void doBindService() { // Establish a connection with the service. We use an explicit // class name because there is no reason to be able to let other // applications replace our component. bindService(new Intent(Binding.this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; mCallbackText.setText("Binding."); } void doUnbindService() { if (mIsBound) { // If we have received the service, and hence registered with // it, then now is the time to unregister. if (mService != null) { try { Message msg = Message.obtain(null, MessengerService.MSG_UNREGISTER_CLIENT); msg.replyTo = mMessenger; mService.send(msg); } catch (RemoteException e) { // There is nothing special we need to do if the service // has crashed. } } // Detach our existing connection. unbindService(mConnection); mIsBound = false; mCallbackText.setText("Unbinding."); }

Servie 中的onBind方法

public abstractIBinderonBind(Intentintent)

Since:API Level 1

Return the communication channel to the service. May return null if clients can not bind to the service. The returnedIBinderis usually for a complex interface that has beendescribed using aidl.

Note that unlike other application components, calls on to the IBinder interface returned here may not happen on the main thread of the process. More information about the main thread can be found inProcesses and Threads.

Parameters
intent The Intent that was used to bind to this service, as given toContext.bindService. Note that any extras that were included with the Intent at that point willnotbe seen here.
Returns
  • Return an IBinder through which clients can call on to the service.

关于IntentService



更多相关文章

  1. Android(安卓)打包及引用 aar 文件的方法
  2. Android(安卓)官方:Google Play 等服务仍然可用
  3. Android(安卓)设计模式-----单利模式
  4. Android(安卓)fw修改让app方向跟随系统方向
  5. Android异步消息处理机制完全解析,带你从源码的角度彻底理解
  6. Android(安卓)API Guides---Host-based Card Emulation
  7. 安卓自定义相机,使用系统相机教程源码都有
  8. 处女男学Android(三)---Handler简介以及初步应用
  9. Android(安卓)来电(包括铃声),短信拦截的实现方法

随机推荐

  1. 总结的Android中surfaceView清屏的方式。
  2. android百度地图(二)之定位
  3. android.intent.action.MEDIA_MOUNTED广
  4. Android 内存泄漏检测之Profiler
  5. Android中的数据库——SQLite
  6. Android之开发BLE 详细步骤
  7. Android 微博登录
  8. 2011.06.03(2)——— android 1.6 launcher
  9. 关于用Android的API重写drawRegion方法的
  10. android Intent使用