什么是Service?
Service(服务)是Android提供的四大组件之一,是一个没有用户界面的在后台运行执行耗时操作的应用组件。其他应用组件能够启动Service,并且当用户切换到另外的应用场景,Service将持续在后台运行。为了方便记忆,我们可以把Service看做是没有页面的Activity,它总是默默的后台处理一些耗时的操作或者不干扰用户使用的后台操作,例如,一个service可能会处理网络操作,播放音乐,操作文件I/O或者与内容提供者(content provider)交互,所有这些活动都是在后台进行。
Service都有哪些?
1)按照使用范围分类:
1.本地服务(Local Service):用于应用程序内部
Local Service运行于当前app的主进程中,如果当前app的进程被Kill掉了,Local Service也会随着随之终止。使用场景举例:音乐播放器服务
2.远程服务(Remote Service):用于android系统内部的应用程序之间
Remote Service是运行于一个独立的进程中,可以被多个app复用,可以使用android:process声明进程名字,由于运行于独立的进程,Activity所在进程被Kill的时候不会影响Remote Service。
2)按照运行类别分类:
1.前台服务
前台服务是那些被认为用户知道的并且在内存低的时候不允许系统杀死的服务,通过startForeground 使服务成为 前台服务。
2.后台服务
区别于前台服务,创建的服务默认是后台服务,在内存低的时候有可能被系统杀死。
3)按照使用方式分类:
1.context.startService()
2.context.bindService()
Service的如何使用?
1.Service AndroidManifest.xml 声明
<service android:enabled=["true" | "false"] android:exported=["true" | "false"] android:icon="drawable resource" android:isolatedProcess=["true" | "false"] android:label="string resource" android:name="string" android:permission="string" android:process="string" > . . . </service>
具体参数解说:
android:name 服务类名
android:label 服务的名字,如果此项不设置,那么默认显示的服务名则为类名
android:icon 服务的图标
android:permission 申明此服务的权限,这意味着只有提供了该权限的应用才能控制或连接此服务
android:process 表示该服务是否运行在另外一个进程,如果设置了此项,那么将会在包名后面加上这段字符串表示另一进程的名字
android:enabled 如果此项设置为 true,那么 Service 将会默认被系统启动,不设置默认此项为 false
android:exported 表示该服务是否能够被其他应用程序所控制或连接,不设置默认此项为 false
具体写个测试Service
public class TestService extends Service { private TestBinder binder=new TestBinder(); private Thread testThread; private boolean isStart=false; @Override public void onCreate() { super.onCreate(); Log.e("TestService", "执行 onCreate()"); startForeground(); } private void startForeground(){ Notification.Builder builder = new Notification.Builder(this); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0); builder.setContentIntent(contentIntent);//设置目标跳转 builder.setSmallIcon(R.mipmap.ic_launcher);//设置显示的图片 builder.setTicker("前台服务开启");// 状态栏上显示 builder.setContentTitle("前台服务");//设置标题 builder.setContentText("这是一个前台服务"); Notification notification = builder.build(); startForeground(1, notification); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e("TestService", "执行 onStartCommand()"); //startThread(); //testANR(); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.e("TestService", "执行 onDestroy()"); stopThread(); stopForeground(true); } @Override public IBinder onBind(Intent intent) { Log.e("TestService", "执行 onBind()"); return binder; } class TestBinder extends Binder { public void testMethod() { Log.e("TestService", "执行 testMethod()"); } } //测试是否ANR private void testANR(){ try { Thread.sleep(50000); } catch (Exception e) { } } private void startThread(){ stopThread(); isStart = true; if (testThread == null) { testThread = new Thread(runnable); testThread.start(); } } private void stopThread(){ try { isStart = false; if (null != testThread && Thread.State.RUNNABLE == testThread.getState()) { try { Thread.sleep(500); testThread.interrupt(); } catch (Exception e) { testThread = null; } } testThread = null; } catch (Exception e) { e.printStackTrace(); } finally { testThread = null; } } private Runnable runnable=new Runnable() { @Override public void run() { while(isStart) { Log.e("TestService", "runnable"); } } }; }