当前位置: 首页 > news >正文

做知乎网站的图片计算机信息网络系统

做知乎网站的图片,计算机信息网络系统,苏州沧浪区做网站,机械加工网怎么发布信息出自于此#xff0c;写得很清楚。关于Android Service真正的完全详解#xff0c;你需要知道的一切_android service-CSDN博客 出自【zejian的博客】 什么是Service? Service(服务)是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。 服务可由其他应用组件… 出自于此写得很清楚。关于Android Service真正的完全详解你需要知道的一切_android service-CSDN博客 出自【zejian的博客】 什么是Service? Service(服务)是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。 服务可由其他应用组件启动如Activity服务一旦被启动将在后台一直运行即使启动服务的组件Activity已销毁也不受影响。 此外组件可以绑定到服务以与之进行交互甚至是执行进程间通信 (IPC)。 例如服务可以处理网络事务、播放音乐执行文件 I/O 或与内容提供程序交互而所有这一切均可在后台进行。 Service基本上分为两种形式 启动状态   当应用组件如 Activity通过调用 startService() 启动服务时服务即处于“启动”状态。一旦启动服务即可在后台无限期运行即使启动服务的组件已被销毁也不受影响除非手动调用才能停止服务 已启动的服务通常是执行单一操作而且不会将结果返回给调用方。 绑定状态   当应用组件通过调用 bindService() 绑定到服务时服务即处于“绑定”状态。绑定服务提供了一个客户端-服务器接口允许组件与服务进行交互、发送请求、获取结果甚至是利用进程间通信 (IPC) 跨进程执行这些操作。 仅当与另一个应用组件绑定时绑定服务才会运行。 多个组件可以同时绑定到该服务但全部取消绑定后该服务即会被销毁。 如何使用Service? 清单文件声明 使用Service前会在清单文件中声明配置。 service android:enabled[true | false]android:exported[true | false]android:icondrawable resourceandroid:isolatedProcess[true | false]android:labelstring resourceandroid:namestringandroid:permissionstringandroid:processstring . . . /service android:exported代表是否能被其他应用隐式调用其默认值是由service中有无intent-filter决定的如果有intent-filter默认值为true否则为false。为false的情况下即使有intent-filter匹配也无法打开即无法被其他应用隐式调用。android:name对应Service类名android:permission是权限声明android:process是否需要在单独的进程中运行,当设置为android:process”:remote”时代表Service在单独的进程中运行。注意“”很重要它的意思是指要在当前进程名称前面附加上当前的包名所以“remote”和”:remote”不是同一个意思前者的进程名称为remote而后者的进程名称为App-packageName:remote。android:isolatedProcess 设置 true 意味着服务会在一个特殊的进程下运行这个进程与系统其他进程分开且没有自己的权限。与其通信的唯一途径是通过服务的API(bind and start)。android:enabled是否可以被系统实例化默认为 true因为父标签 也有 enable 属性所以必须两个都为默认值 true 的情况下服务才会被激活否则不会激活。 创建Service子类 首先要创建服务必须创建 Service 的子类或使用它的一个现有子类如IntentService。 在实现中我们需要重写一些回调方法(其中onBind()方法必须重写)以处理服务生命周期的某些关键过程。 package com.example.androidstudiostudy.service;import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log;//创建 Service 的子类或使用它的一个现有子类如IntentService,重写一些回调方法 public class OneService extends Service {public OneService() {}// 绑定服务时调用Overridepublic IBinder onBind(Intent intent) {// TODO: Return the communication channel to the service.throw new UnsupportedOperationException(Not yet implemented);}// 首次创建服务时系统将调用此方法来执行一次性设置程序在调用 onStartCommand() 或onBind() 之前。// 如果服务已在运行则不会调用此方法该方法只调用一次Overridepublic void onCreate() {super.onCreate();Log.d(服务,首次创建服务调用此方法来执行一次性设置程序,该方法只调用一次);}// 每次通过startService()方法启动Service时都会被回调。Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.d(服务,onStartCommand);return super.onStartCommand(intent, flags, startId);}// 服务销毁时回调Overridepublic void onDestroy() {super.onDestroy();Log.d(服务,销毁服务);} } onBind()   当另一个组件想通过调用 bindService() 与服务绑定例如执行 RPC时系统将调用此方法。在此方法的实现中必须返回 一个IBinder 接口的实现类供客户端用来与服务进行通信。无论是启动状态还是绑定状态此方法必须重写但在启动状态的情况下直接返回 null。 onCreate()   首次创建服务时系统将调用此方法来执行一次性设置程序在调用 onStartCommand() 或onBind() 之前。如果服务已在运行则不会调用此方法该方法只调用一次 onStartCommand()   当另一个组件如 Activity通过调用 startService() 请求启动服务时系统将调用此方法。一旦执行此方法服务即会启动并可在后台无限期运行。 如果自己实现此方法则需要在服务工作完成后通过调用 stopSelf() 或 stopService() 来停止服务。在绑定状态下无需实现此方法。 onDestroy()   当服务不再使用且将被销毁时系统将调用此方法。服务应该实现此方法来清理所有资源如线程、注册的侦听器、接收器等这是服务接收的最后一个调用。 启动Service 使用 startService(intent); 停止Serviece 使用 stopService(intent); 通过Demo测试一下Service启动状态方法的调用顺序依次点击启动和停止。StudyService 代码如下 public class StudyService extends AppCompatActivity {Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_study_service);}public void serviceAction(View view) {int id view.getId();Intent intent new Intent(this,OneService.class);if(id R.id.bindService){// 绑定service} else if (id R.id.stopService) {stopService(intent); // 停止服务} else {startService(intent); // 启动服务}} } 此时的清单文件 applicationandroid:allowBackuptrueandroid:dataExtractionRulesxml/data_extraction_rulesandroid:fullBackupContentxml/backup_rulesandroid:iconmipmap/studyandroid:labelstring/app_nameandroid:networkSecurityConfigxml/network_security_configandroid:roundIconmipmap/studyandroid:supportsRtltrueandroid:themestyle/Theme.AndroidStudioStudytools:targetApi31activityandroid:name.service.StudyServiceandroid:exportedfalse /activityandroid:name.service.studyServiceandroid:exportedfalse /serviceandroid:name.service.OneServiceandroid:enabledtrueandroid:exportedtrueandroid:permission.service.OneService / 日志打印 绑定Service 绑定服务是Service的另一种变形当Service处于绑定状态时其代表着客户端-服务器接口中的服务器。 当其他组件如 Activity绑定到服务时组件如Activity可以向Service也就是服务端发送请求或者调用Service服务端的方法此时被绑定的Service服务端会接收信息并响应甚至可以通过绑定服务进行执行进程间通信 。 有时我们可能需要从Activity组件中去调用Service中的方法此时Activity以绑定的方式挂靠到Service后我们就可以轻松地方法到Service中的指定方法 与启动服务不同的是绑定服务的生命周期通常只在为其他应用组件(如Activity)服务时处于活动状态不会无限期在后台运行也就是说宿主(如Activity)解除绑定后绑定服务就会被销毁。 那么在提供绑定的服务时该如何实现呢 实际上我们必须提供一个 IBinder接口的实现类该类用以提供客户端用来与服务进行交互的编程接口该接口可以通过三种方法定义接口 扩展 Binder 类 如果服务是提供给自有应用专用的并且Service(服务端)与客户端相同的进程中运行常见情况则应通过扩展 Binder 类并从 onBind() 返回它的一个实例来创建接口。 客户端收到 Binder 后可利用它直接访问 Binder 实现中以及Service 中可用的公共方法。如果我们的服务只是自有应用的后台工作线程则优先采用这种方法。 不采用该方式创建接口的唯一原因是服务被其他应用或不同的进程调用。 在Service子类中创建一个扩展 Binder 的类(OneServiceBinder),在类中声明了一个getService方法客户端可访问该方法获取 Service子类 对象的实例只要客户端获取到 OneServiceBinder 对象的实例就可调用服务端的公共方法。创建一个实现IBinder 接口的实例对象并提供公共方法给客户端调用从 onBind() 回调方法返回此 Binder 实例。 private OneServiceBinder oneServiceBinder new OneServiceBinder();// 当另一个组件想通过调用 bindService() 与服务绑定例如执行 RPC时系统将调用此方法。 // 在此方法的实现中必须返回 一个IBinder 接口的实现类供客户端用来与服务进行通信。 // 无论是启动状态还是绑定状态此方法必须重写但在启动状态的情况下直接返回 null。 Override public IBinder onBind(Intent intent) {return oneServiceBinder;}/*** 创建Binder对象返回给客户端即Activity使用提供数据交换的接口*/public class OneServiceBinder extends Binder {// 声明一个方法getService。提供给客户端调用OneService getService() {// 返回当前对象LocalService,这样我们就可在客户端端调用Service的公共方法了return OneService.this;}} 完整service代码 package com.example.androidstudiostudy.service;import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log;//创建 Service 的子类或使用它的一个现有子类如IntentService,重写一些回调方法 public class OneService extends Service {private OneServiceBinder oneServiceBinder new OneServiceBinder();private Thread thread;// 当另一个组件想通过调用 bindService() 与服务绑定例如执行 RPC时系统将调用此方法。// 在此方法的实现中必须返回 一个IBinder 接口的实现类供客户端用来与服务进行通信。// 无论是启动状态还是绑定状态此方法必须重写但在启动状态的情况下直接返回 null。Overridepublic IBinder onBind(Intent intent) {return oneServiceBinder;}/*** 创建Binder对象返回给客户端即Activity使用提供数据交换的接口*/public class OneServiceBinder extends Binder {// 声明一个方法getService。提供给客户端调用OneService getService() {// 返回当前对象LocalService,这样我们就可在客户端端调用Service的公共方法了return OneService.this;}}// 首次创建服务时系统将调用此方法来执行一次性设置程序在调用 onStartCommand() 或onBind() 之前。// 如果服务已在运行则不会调用此方法该方法只调用一次private int count 0;private boolean quit false;Overridepublic void onCreate() {super.onCreate();Log.d(服务, 首次创建服务调用此方法来执行一次性设置程序,该方法只调用一次);thread new Thread(new Runnable() {Overridepublic void run() {while (!quit) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}count;}}});thread.start();}// 当另一个组件如 Activity通过调用 startService() 请求启动服务时系统将调用此方法。// 一旦执行此方法服务即会启动并可在后台无限期运行。 如果自己实现此方法则需要在服务工作完成后通过调用 stopSelf() 或 stopService() 来停止服务。// 在绑定状态下无需实现此方法。Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.d(服务, onStartCommand);return super.onStartCommand(intent, flags, startId);}// 当服务不再使用且将被销毁时系统将调用此方法。服务应该实现此方法来清理所有资源如线程、注册的侦听器、接收器等这是服务接收的最后一个调用。Overridepublic void onDestroy() {super.onDestroy();this.quit true;Log.d(服务, 销毁服务);}//--------------------公共方法------------------public int getCount() {return count;}//--------------------解除绑定时调用------------------Overridepublic boolean onUnbind(Intent intent) {Log.d(服务, 解除绑定);return super.onUnbind(intent);} } 客户端绑定到服务步骤: 1.ServiceConnection代表与服务的连接它只有两个方法实现ServiceConnection重写这两个回调方法。 onServiceConnected()—系统会调用该方法以传递服务的onBind()返回的IBinderonServiceDisconnected()—Android系统会在服务崩溃或被杀死导致的连接中断时调用或者随着activity 的生命周期stop时调用该方法当客户端取消绑定的时候不会回调该方法 private ServiceConnection serviceConnection;private OneService myService;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_study_service);serviceConnection new ServiceConnection() {// 绑定成功时调用Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {Log.d(绑定服务,成功绑定服务);OneService.OneServiceBinder oneServiceBinder (OneService.OneServiceBinder) iBinder;myService oneServiceBinder.getService();}// Android 系统会在与服务的连接意外中断时例如当服务崩溃或被终止时调用该方法Overridepublic void onServiceDisconnected(ComponentName componentName) {Log.d(绑定服务,与服务的连接意外中断);myService null;}};} 2.调用bindService()传递ServiceConnection 3.当系统调用onServiceConnected()的回调方法时可以使用接口定义的方法开始调用服务 4.要断开与服务的连接请调用unBindService() 如果应用在客户端与服务仍然绑定的状态下被销毁了则销毁会导致客户端取消绑定。 Activity代码          public class StudyService extends AppCompatActivity {private ServiceConnection serviceConnection;private OneService myService;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_study_service);serviceConnection new ServiceConnection() {// 绑定成功时调用Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {Log.d(绑定服务,成功绑定服务);OneService.OneServiceBinder oneServiceBinder (OneService.OneServiceBinder) iBinder;myService oneServiceBinder.getService();}// Android 系统会在与服务的连接意外中断时例如当服务崩溃或被终止时调用该方法Overridepublic void onServiceDisconnected(ComponentName componentName) {Log.d(绑定服务,与服务的连接意外中断);myService null;}};}public void serviceAction(View view) {int id view.getId();Intent intent new Intent(this,OneService.class);if(id R.id.bindService){// 绑定servicebindService(intent,serviceConnection,Service.BIND_AUTO_CREATE);if (myService ! null) {// 通过绑定服务传递的Binder对象获取Service暴露出来的数据Log.d(获取绑定数据, 从服务端获取数据 myService.getCount());} else {Log.d(获取绑定数据, 还没绑定呢先绑定,无法从服务端获取数据);}} else if (id R.id.stopService) {stopService(intent);} else {startService(intent);}} } 打印数据 使用 Messenger 前面了解到应用内同一进程的通信可以使用IBinder而不同进程间的通信最简单的方式则是使用 Messenger 服务提供通信接口利用此方式我们无需使用 AIDL 便可执行进程间通信 (IPC)。Messenger底层也是通过aidl实现不过封装了一层AIDL 支持多线程并发。messenger是同步如果没有多线程并发要求就可以使用轻量级的Messenger。 以下是使用 Messenger 绑定Service的主要步骤 主要步骤 1.创建一个服务子类MessengerService 并在里面实现一个 Handler由其接收来自客户端的每个调用的回调 // 用于接收从客户端传递过来的数据class ServiceReciveHandle extends Handler {Overridepublic void handleMessage(NonNull Message msg) {switch (msg.what) {case MSG_SAY_HELLO:Log.i(TAG, thanks,Service had receiver message from client!);break;default:super.handleMessage(msg);}}} 2.将该Handler 用于创建 Messenger 对象对 Handler 的引用 3.Messenger 会创建一个 IBinderMessengerService 通过 onBind() 返回这个Messenger对象的底层Binder。 final Messenger messenger new Messenger(new ServiceReciveHandle());Overridepublic IBinder onBind(Intent intent) {Log.i(TAG, 服务绑定);return messenger.getBinder();} 4.客户端使用 IBinder 将 Messenger引用MessengerService 的 Handler实例化然后使用Messenger将 Message 对象发送给服务。 // 实现与服务端链接的对象private final ServiceConnection mConnection new ServiceConnection() {Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {// 通过服务端传递的IBinder对象,创建相应的Messenger// 通过该Messenger对象与服务端进行交互Log.i(TAG, 服务链接绑定);myService new Messenger(iBinder);mBound true;}Overridepublic void onServiceDisconnected(ComponentName componentName) {Log.i(TAG, 服务链接绑定取消);myService null;mBound false;}}; 5.MessengerService 在其 Handler 中在 handleMessage() 方法中接收每个 Message。 完整Service代码 package com.example.androidstudiostudy.service;import android.app.Service; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.util.Log;import androidx.annotation.NonNull;public class MessengerService extends Service {static final int MSG_SAY_HELLO 1;private static final String TAG MessengerService;// 用于接收从客户端传递过来的数据class ServiceReciveHandle extends Handler {Overridepublic void handleMessage(NonNull Message msg) {switch (msg.what) {case MSG_SAY_HELLO:Log.i(TAG, 服务器接收到来自客户端的消息);break;default:super.handleMessage(msg);}}}final Messenger messenger new Messenger(new ServiceReciveHandle());Overridepublic IBinder onBind(Intent intent) {Log.i(TAG, 服务绑定);return messenger.getBinder();}Overridepublic void onCreate() {Log.i(TAG, 服务onCreate);super.onCreate();}Overridepublic void onDestroy() {Log.i(TAG, 服务Destroy);super.onDestroy();} } Activity代码 package com.example.androidstudiostudy.service;public class MessengerServiceActivity extends AppCompatActivity {private static final String TAG MessengerService-Activity;// 与服务端交互的Messengerprivate Messenger myService null;// 是否绑定boolean mBound false;// 实现与服务端链接的对象private final ServiceConnection mConnection new ServiceConnection() {Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {// 通过服务端传递的IBinder对象,创建相应的Messenger// 通过该Messenger对象与服务端进行交互Log.i(TAG, 服务链接绑定);myService new Messenger(iBinder);mBound true;}Overridepublic void onServiceDisconnected(ComponentName componentName) {Log.i(TAG, 服务链接绑定取消);myService null;mBound false;}};private Button sendMsg, bindService, unbindService, createService, destoryService;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_messenger_service);sendMsg findViewById(R.id.sendMessageToService);sendMsg.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {if (!mBound)return;Message msg Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);try {// 发送消息myService.send(msg);} catch (RemoteException e) {throw new RuntimeException(e);}}});Intent intent new Intent(MessengerServiceActivity.this, MessengerService.class);unbindService findViewById(R.id.unbindMessengerService);unbindService.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {unbindService(mConnection);}});bindService findViewById(R.id.bindMessengerService);bindService.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {Log.i(TAG, bd);bindService(intent, mConnection, Context.BIND_AUTO_CREATE);}});createService findViewById(R.id.startMessengerService);createService.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {startService(intent);}});destoryService findViewById(R.id.destoreyMessengerService);destoryService.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {stopService(intent);}});} } 服务器与客户端的双向通信 上述代码能够实现客户端向服务器的通信如果想要服务器向客户端通信则需要在客户端也创建一个接收消息的Messenger和Handler改造 MessengerService 中的handler,在接受到信息时发送信息。 MessengerService 在服务器端的handler中发送返回消息 // 用于接收从客户端传递过来的数据private static class ServiceReciveHandle extends Handler {Overridepublic void handleMessage(NonNull Message msg) {if (msg.what MSG_SAY_HELLO) {Log.i(TAG, 服务器接收到来自客户端的消息);Messenger replyMessenger msg.replyTo;Message replyMessenge Message.obtain(null, MessengerService.MSG_SAY_HELLO);Bundle bundlenew Bundle();bundle.putString(reply,ok~,I had receiver message from you! );replyMessenge.setData(bundle);try {replyMessenger.send(replyMessenge);} catch (RemoteException e) {throw new RuntimeException(e);}} else {super.handleMessage(msg);}}} Activity: 1.创建一个用于接收服务器端消息的Messenger和Handler 2.在发送消息时,把接收服务器端的回复的Messenger通过Message的replyTo参数传递给服务端 private final Messenger activityRecevierMessenger new Messenger(new activityRecevierHandler());private static class activityRecevierHandler extends Handler{Overridepublic void handleMessage(NonNull Message msg) {if (msg.what MessengerService.MSG_SAY_HELLO) {Log.i(TAG, 客户端接收到来自服务的消息 msg.getData().getString(reply));} else {super.handleMessage(msg);}}} sendMsg findViewById(R.id.sendMessageToService);sendMsg.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {if (!mBound)return;Message msg Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);// 把接收服务器端的回复的Messenger通过Message的replyTo参数传递给服务端msg.replyTo activityRecevierMessenger;try {// 发送消息myService.send(msg);} catch (RemoteException e) {throw new RuntimeException(e);}}}); 绑定服务的注意点    1.多个客户端可同时连接到一个服务。不过只有在第一个客户端绑定时系统才会调用服务的 onBind() 方法来检索 IBinder。系统随后无需再次调用 onBind()便可将同一 IBinder 传递至任何其他绑定的客户端。当最后一个客户端取消与服务的绑定时系统会将服务销毁除非 startService() 也启动了该服务。 2.通常情况下我们应该在客户端生命周期如Activity的生命周期的引入 (bring-up) 和退出 (tear-down) 时刻设置绑定和取消绑定操作以便控制绑定状态下的Service一般有以下两种情况 如果只需要在 Activity 可见时与服务交互则应在 onStart() 期间绑定在 onStop() 期间取消绑定。如果希望 Activity 在后台停止运行状态下仍可接收响应则可在 onCreate() 期间绑定在 onDestroy() 期间取消绑定。需要注意的是这意味着 Activity 在其整个运行过程中甚至包括后台运行期间都需要使用服务因此如果服务位于其他进程内那么当提高该进程的权重时系统很可能会终止该进程。 3.通常情况下(注意)切勿在 Activity 的 onResume() 和 onPause() 期间绑定和取消绑定因为每一次生命周期转换都会发生这些回调这样反复绑定与解绑是不合理的。此外如果应用内的多个 Activity 绑定到同一服务并且其中两个 Activity 之间发生了转换则如果当前 Activity 在下一次绑定恢复期间之前取消绑定暂停期间系统可能会销毁服务并重建服务因此服务的绑定不应该发生在 Activity 的 onResume() 和 onPause()中。 4.我们应该始终捕获 DeadObjectException DeadObjectException 异常该异常是在连接中断时引发的表示调用的对象已死亡也就是Service对象已销毁这是远程方法引发的唯一异常DeadObjectException继承自RemoteException因此我们也可以捕获RemoteException异常。 5.应用组件客户端可通过调用 bindService() 绑定到服务,Android 系统随后调用服务的 onBind() 方法该方法返回用于与服务交互的 IBinder而该绑定是异步执行的。 关于启动服务与绑定服务间的转换问题 通过前面对两种服务状态的分析相信大家已对Service的两种状态有了比较清晰的了解那么现在我们就来分析一下当启动状态和绑定状态同时存在时又会是怎么的场景   虽然服务的状态有启动和绑定两种但实际上一个服务可以同时是这两种状态也就是说它既可以是启动服务以无限期运行也可以是绑定服务。有点需要注意的是Android系统仅会为一个Service创建一个实例对象所以不管是启动服务还是绑定服务操作的是同一个Service实例而且由于绑定服务或者启动服务执行顺序问题将会出现以下两种情况 先绑定服务后启动服务 如果当前Service实例先以绑定状态运行然后再以启动状态运行那么绑定服务将会转为启动服务运行这时如果之前绑定的宿主Activity被销毁了也不会影响服务的运行服务还是会一直运行下去指定收到调用停止服务或者内存不足时才会销毁该服务。 先启动服务后绑定服务 如果当前Service实例先以启动状态运行然后再以绑定状态运行当前启动服务并不会转为绑定服务但是还是会与宿主绑定只是即使宿主解除绑定后服务依然按启动服务的生命周期在后台运行直到有Context调用了stopService()或是服务本身调用了stopSelf()方法抑或内存不足时才会销毁服务。 以上两种情况显示出启动服务的优先级确实比绑定服务高一些。不过无论Service是处于启动状态还是绑定状态或处于启动并且绑定状态我们都可以像使用Activity那样通过调用 Intent 来使用服务(即使此服务来自另一应用)。 当然我们也可以通过清单文件将服务声明为私有服务阻止其他应用访问。 最后这里有点需要特殊说明一下的由于服务在其托管进程的主线程中运行UI线程它既不创建自己的线程也不在单独的进程中运行除非另行指定。 这意味着如果服务将执行任何耗时事件或阻止性操作例如 MP3 播放或联网时则应在服务内创建新线程来完成这项工作简而言之耗时操作应该另起线程执行。只有通过使用单独的线程才可以降低发生“应用无响应”(ANR) 错误的风险这样应用的主线程才能专注于用户与 Activity 之间的交互 以达到更好的用户体验。 前台服务以及通知发送  前台服务被认为是用户主动意识到的一种服务因此在内存不足时系统也不会考虑将其终止。 前台服务必须为状态栏提供通知状态栏位于“正在进行”标题下方这意味着除非服务停止或从前台删除否则不能清除通知。 例如将从服务播放音乐的音乐播放器设置为在前台运行这是因为用户明确意识到其操作。 状态栏中的通知可能表示正在播放的歌曲并允许用户启动 Activity 来与音乐播放器进行交互。如果需要设置服务运行于前台 我们该如何才能实现呢Android官方给我们提供了两个方法分别是startForeground()和stopForeground()这两个方式解析如下 startForeground(int id, Notification notification) 该方法的作用是把当前服务设置为前台服务其中id参数代表唯一标识通知的整型数需要注意的是提供给 startForeground() 的整型 ID 不得为 0而notification是一个状态栏的通知。 stopForeground(boolean removeNotification) 该方法是用来从前台删除服务此方法传入一个布尔值指示是否也删除状态栏通知true为删除。 注意该方法并不会停止服务。 但是如果在服务正在前台运行时将其停止则通知也会被删除。 服务Service与线程Thread的区别 两者的真正关系 没有关系。 两者概念的迥异 Thread 是程序执行的最小单元它是分配CPU的基本单位android系统中UI线程也是线程的一种当然Thread还可以用于执行一些耗时异步的操作。 Service是Android的一种机制服务是运行在主线程上的它是由系统进程托管。它与其他组件之间的通信类似于client和server是一种轻量级的IPC通信这种通信的载体是binder它是在linux层交换信息的一种IPC而所谓的Service后台任务只不过是指没有UI的组件罢了。 两者的执行任务迥异 在android系统中线程一般指的是工作线程(即后台线程)而主线程是一种特殊的工作线程它负责将事件分派给相应的用户界面小工具如绘图事件及事件响应因此为了保证应用 UI 的响应能力主线程上不可执行耗时操作。如果执行的操作不能很快完成则应确保它们在单独的工作线程执行。 Service 则是android系统中的组件一般情况下它运行于主线程中因此在Service中是不可以执行耗时操作的否则系统会报ANR异常之所以称Service为后台服务大部分原因是它本身没有UI用户无法感知(当然也可以利用某些手段让用户知道)但如果需要让Service执行耗时任务可在Service中开启单独线程去执行。 两者使用场景 当要执行耗时的网络或者数据库查询以及其他阻塞UI线程或密集使用CPU的任务时都应该使用工作线程(Thread)这样才能保证UI线程不被占用而影响用户体验。 在应用程序中如果需要长时间的在后台运行而且不需要交互的情况下使用服务。比如播放音乐通过ServiceNotification方式在后台执行同时在通知栏显示着。 两者的最佳使用方式 在大部分情况下Thread和Service都会结合着使用: 比如下载文件:一般会通过Service在后台执行Notification在通知栏显示Thread异步下载;再如应用程序会维持一个Service来从网络中获取推送服务。 在Android官方看来也是如此所以官网提供了一个Thread与Service的结合来方便我们执行后台耗时任务它就是IntentService当然 IntentService并不适用于所有的场景但它的优点是使用方便、代码简洁不需要我们创建Service实例并同时也创建线程某些场景下还是非常赞的由于IntentService是单个worker thread所以任务需要排队因此不适合大多数的多任务情况。 管理服务生命周期  左图显示了使用 startService() 所创建的服务的生命周期。右图显示了使用 bindService() 所创建的服务的生命周期。 通过图中的生命周期方法我们可以监控Service的整体执行过程包括创建运行销毁 服务的整个生命周期从调用 onCreate() 开始起到 onDestroy() 返回时结束。与 Activity 类似服务也在 onCreate() 中完成初始设置并在 onDestroy() 中释放所有剩余资源。例如音乐播放服务可以在 onCreate() 中创建用于播放音乐的线程然后在 onDestroy() 中停止该线程。无论服务是通过 startService() 还是 bindService() 创建都会为所有服务调用 onCreate() 和 onDestroy() 方法。服务的有效生命周期从调用 onStartCommand() 或 onBind() 方法开始。每种方法均有 Intent 对象该对象分别传递到 startService() 或 bindService()。对于启动服务有效生命周期与整个生命周期同时结束即便是在 onStartCommand() 返回之后服务仍然处于活动状态。对于绑定服务有效生命周期在 onUnbind() 返回时结束。 从执行流程图来看服务的生命周期比 Activity 的生命周期要简单得多。但是我们必须密切关注如何创建和销毁服务因为服务可以在用户没有意识到的情况下运行于后台。管理服务的生命周期从创建到销毁有以下两种情况 启动服务 该服务在其他组件调用 startService() 时创建然后无限期运行且必须通过调用 stopSelf() 来自行停止运行。此外其他组件也可以通过调用 stopService() 来停止服务。服务停止后系统会将其销毁。 绑定服务 该服务在另一个组件客户端调用 bindService() 时创建。然后客户端通过 IBinder 接口与服务进行通信。客户端可以通过调用 unbindService() 关闭连接。多个客户端可以绑定到相同服务而且当所有绑定全部取消后系统即会销毁该服务。 服务不必自行停止运行 启动服务与绑定服务的结合体 我们可以绑定到已经使用 startService() 启动的服务。例如可以通过使用 Intent标识要播放的音乐调用 startService() 来启动后台音乐服务。随后可能在用户需要稍加控制播放器或获取有关当前播放歌曲的信息时Activity 可以通过调用 bindService() 绑定到服务。在 这种情况下除非所有客户端均取消绑定否则 stopService() 或 stopSelf() 不会真正停止服务。 如何保证服务不被杀死 因内存资源不足而杀死Service 这种情况比较容易处理可将onStartCommand() 方法的返回值设为 START_STICKY或START_REDELIVER_INTENT 该值表示服务在内存资源紧张时被杀死后在内存资源足够时再恢复。也可将Service设置为前台服务这样就有比较高的优先级在内存资源紧张时也不会被杀掉。 用户通过 settings - Apps - Running - Stop 方式杀死Service 这种情况是用户手动干预的不过幸运的是这个过程会执行Service的生命周期也就是onDestory方法会被调用这时便可以在 onDestory() 中发送广播重新启动。这样杀死服务后会立即启动。这种方案是行得通的但为程序更健全我们可开启两个服务相互监听相互启动。服务A监听B的广播来启动B服务B监听A的广播来启动A。 
文章转载自:
http://www.morning.kycwt.cn.gov.cn.kycwt.cn
http://www.morning.tkryt.cn.gov.cn.tkryt.cn
http://www.morning.fqhbt.cn.gov.cn.fqhbt.cn
http://www.morning.qzdxy.cn.gov.cn.qzdxy.cn
http://www.morning.hclqy.cn.gov.cn.hclqy.cn
http://www.morning.fbmjl.cn.gov.cn.fbmjl.cn
http://www.morning.crrjg.cn.gov.cn.crrjg.cn
http://www.morning.qqnp.cn.gov.cn.qqnp.cn
http://www.morning.wblpn.cn.gov.cn.wblpn.cn
http://www.morning.ljngm.cn.gov.cn.ljngm.cn
http://www.morning.c7500.cn.gov.cn.c7500.cn
http://www.morning.lztrt.cn.gov.cn.lztrt.cn
http://www.morning.bdsyu.cn.gov.cn.bdsyu.cn
http://www.morning.pqfbk.cn.gov.cn.pqfbk.cn
http://www.morning.bsqth.cn.gov.cn.bsqth.cn
http://www.morning.pndw.cn.gov.cn.pndw.cn
http://www.morning.qstkk.cn.gov.cn.qstkk.cn
http://www.morning.gjlst.cn.gov.cn.gjlst.cn
http://www.morning.fbccx.cn.gov.cn.fbccx.cn
http://www.morning.knlyl.cn.gov.cn.knlyl.cn
http://www.morning.bydpr.cn.gov.cn.bydpr.cn
http://www.morning.xsqbx.cn.gov.cn.xsqbx.cn
http://www.morning.wpwyx.cn.gov.cn.wpwyx.cn
http://www.morning.dmrjx.cn.gov.cn.dmrjx.cn
http://www.morning.ghssm.cn.gov.cn.ghssm.cn
http://www.morning.rgxll.cn.gov.cn.rgxll.cn
http://www.morning.zympx.cn.gov.cn.zympx.cn
http://www.morning.ygkk.cn.gov.cn.ygkk.cn
http://www.morning.zfhzx.cn.gov.cn.zfhzx.cn
http://www.morning.qprtm.cn.gov.cn.qprtm.cn
http://www.morning.qgfy.cn.gov.cn.qgfy.cn
http://www.morning.dtnjr.cn.gov.cn.dtnjr.cn
http://www.morning.yuanshenglan.com.gov.cn.yuanshenglan.com
http://www.morning.brbmf.cn.gov.cn.brbmf.cn
http://www.morning.cylbs.cn.gov.cn.cylbs.cn
http://www.morning.bfcxf.cn.gov.cn.bfcxf.cn
http://www.morning.xpgwz.cn.gov.cn.xpgwz.cn
http://www.morning.hwljx.cn.gov.cn.hwljx.cn
http://www.morning.czgtt.cn.gov.cn.czgtt.cn
http://www.morning.cnwpb.cn.gov.cn.cnwpb.cn
http://www.morning.rkmsm.cn.gov.cn.rkmsm.cn
http://www.morning.ljcf.cn.gov.cn.ljcf.cn
http://www.morning.pbdnj.cn.gov.cn.pbdnj.cn
http://www.morning.bhmnp.cn.gov.cn.bhmnp.cn
http://www.morning.phxns.cn.gov.cn.phxns.cn
http://www.morning.tmbfz.cn.gov.cn.tmbfz.cn
http://www.morning.ghphp.cn.gov.cn.ghphp.cn
http://www.morning.sxlrg.cn.gov.cn.sxlrg.cn
http://www.morning.brfxt.cn.gov.cn.brfxt.cn
http://www.morning.qjzgj.cn.gov.cn.qjzgj.cn
http://www.morning.mtbth.cn.gov.cn.mtbth.cn
http://www.morning.qczpf.cn.gov.cn.qczpf.cn
http://www.morning.plchy.cn.gov.cn.plchy.cn
http://www.morning.dplmq.cn.gov.cn.dplmq.cn
http://www.morning.ykkrg.cn.gov.cn.ykkrg.cn
http://www.morning.wmqxt.cn.gov.cn.wmqxt.cn
http://www.morning.kklwz.cn.gov.cn.kklwz.cn
http://www.morning.nnttr.cn.gov.cn.nnttr.cn
http://www.morning.joinyun.com.gov.cn.joinyun.com
http://www.morning.qhln.cn.gov.cn.qhln.cn
http://www.morning.mcpdn.cn.gov.cn.mcpdn.cn
http://www.morning.lxbml.cn.gov.cn.lxbml.cn
http://www.morning.bqwnp.cn.gov.cn.bqwnp.cn
http://www.morning.gktds.cn.gov.cn.gktds.cn
http://www.morning.qflcb.cn.gov.cn.qflcb.cn
http://www.morning.dpruuode.cn.gov.cn.dpruuode.cn
http://www.morning.wjjxr.cn.gov.cn.wjjxr.cn
http://www.morning.kgqww.cn.gov.cn.kgqww.cn
http://www.morning.rmtxp.cn.gov.cn.rmtxp.cn
http://www.morning.tpxgm.cn.gov.cn.tpxgm.cn
http://www.morning.jkcnq.cn.gov.cn.jkcnq.cn
http://www.morning.lpsjs.com.gov.cn.lpsjs.com
http://www.morning.flncd.cn.gov.cn.flncd.cn
http://www.morning.jopebe.cn.gov.cn.jopebe.cn
http://www.morning.rymd.cn.gov.cn.rymd.cn
http://www.morning.hrpbq.cn.gov.cn.hrpbq.cn
http://www.morning.dwdjj.cn.gov.cn.dwdjj.cn
http://www.morning.cwnqd.cn.gov.cn.cwnqd.cn
http://www.morning.rdqzl.cn.gov.cn.rdqzl.cn
http://www.morning.fwlch.cn.gov.cn.fwlch.cn
http://www.tj-hxxt.cn/news/266065.html

相关文章:

  • 网站开发多长时间微信小程序源代码大全
  • 加强门户网站建设的通知网站创建怎么做
  • 如何做网站聚合页百度软件商店下载安装
  • 工程建设业绩公示网站网络平台推广有哪些渠道
  • 网站制作 合肥网站建设的数字化和互联网化
  • 重庆制作网站开发app开发公司小程序模板商城
  • 在线做动图的网站麻章网站开发公司
  • 山西公司网站建设效果新零售网站建设
  • 文化传媒网站封面东莞长安做网站公司
  • 怎么在word上做超链接网站金华市建设监理协会网站
  • 网站建设平台市场wordpress组件开发
  • 海安网站建设家装室内设计案例分析图文
  • 网站设计 中国风小程序注册推广
  • 郑州网站建设制作费用wordpress 关联文章
  • 二级域名网站怎么投广告北京高端网站建设公司哪家好
  • 建设部网站 光纤到户墨子学院网站建设vip课程
  • 网站程序模块安徽省住房和城乡建设厅门户网站
  • 搜款网站一起做网店免费的招标网有哪些
  • 旅行社网站建设方案书dedecms漏洞
  • 爱站网域名查询西安网站搭建
  • 怎嘛做网站南京市住宅建设总公司网站
  • 山西推广型网站制作wordpress 主页
  • 怎么建设网站最便宜wordpress 5.2.2中文版
  • 上海市网站制作在putty做网站要拷贝什么
  • 市辖区郑州网站建设网站后台添加图片显示不了
  • 抚顺您做煮火锅网站推广计划表格
  • 我的网站突然打不开了怎么回事啊长沙专业网站设计公司
  • 宣武上海网站建设福州mip网站建设
  • 制作游戏网站公司潍坊市建设一体化平台网站
  • 医疗网站建设哪个好用小伟破解WordPress主题