1.Service简单介绍

依照使用范围分类:

类别 优点 缺点 差别 应用
本地服务 Local  Service 本地服务在一定程度上节约了资源,另外本地服务由于是在同一进程,因此不须要IPC,也不须要AIDL。相应bindService会方便非常多。 主进程被Kill后。服务便会终止。

本地服务依附在主进程上,而不是独立的进程,用于应用程序内部

音乐播放服务

远程服务

Remote Service

相应进程名格式为所在包名加上指定的android:process字符串。由于是独立的进程,因此在Activity所在进程被Kill的时候,该服务依旧在执行。不受其它进程影响,有利于为多个进程提供服务。具有较高的灵活性。 会占用一定资源,而且使用AIDL进行IPC略微麻烦一点。

远程服务是独立的进程。用于android系统内部的应用程序之间。可被其它应用程序复用

提供天气状况、时间日历的系统服务。这样的Service是常驻的。

按执行类型分类:

类别 差别 应用
前台服务 会在通知栏显示正在执行的Notification 当服务被终止的时候,通知一栏的 Notification 也会消失,对于用户有一定的通知作用。如音乐播放服务。
后台服务 默认的为后台服务。没有Notification 某些不须要提示的服务执行或终止时。用户看不到效果,如天气更新。日期同步,邮件同步等

服务是在调用 startForeground(android 2.0 及其以后版本号)使服务成为前台服务。这样做的优点在于,当服务被外部强制终止掉的时候。ONGOING 的 Notification 会被移除掉。

依照使用方式分类:

类别 差别
startService 启动的服务 主要用于启动一个服务执行后台任务,不进行通信。停止服务使用stopService
bindService 启动的服务 该方法启动的服务要进行通信,停止服务使用unbindService

2.Service 与 Thread 的差别(总结于网络)

1). Thread:Thread 是程序执行的最小单元,它是分配CPU的基本单位。 Thread 能够来来执行一些异步操作。

2). Service:Service 是android的一种机制,

假设执行的是Local Service,那么相应的 Service 是执行在主进程的 main 线程上的。如:onCreate,onStartCommand这些函数在被系统调用的时候都是在主进程的 main 线程上执行的。

假设执行是Remote Service,那么相应的 Service 则是执行在独立进程的 main 线程上。

 

为什么 Thread替代不了Service 呢?

一方面,Thread 的执行是独立于 Activity 的。也就是说当一个 Activity 被 finish 之后。假设你没有主动停止 Thread 或者 Thread 里的 run 方法没有执行完成的话,Thread 也会一直执行。因此这里会出现一个问题:当 Activity 被 finish 之后,你不再持有该 Thread 的引用。另
假设创建的 Thread 须要不停地隔一段时间就要连接server做某种同步的话。该 Thread 须要在 Activity 没有start的时候也在执行。

这个时候当你 start 一个 Activity 就没有办法在该 Activity 里面控制之前创建的 Thread。

还有一方面。因此你便须要创建并启动一个 Service ,在 Service 里面创建、执行并控制该 Thread,这样便攻克了该问题。由于不论什么 Activity 都能够控制同一 Service。而系统也仅仅会创建一个相应 Service 的实例。

因此能够把 Service 想象成一种消息服务。在不论什么有 Context 的地方调用方法来控制它,你也能够在 Service 里注冊BroadcastReceiver,在其它地方通过发送 broadcast 来控制它,当然这些都是 Thread 做不到的。

3.startService

被启动的服务的生命周期:onCreate -> onStartCommand -> onDestroy

假设Service被startService方法启动多次。当中仅仅会调用一次onCreate方法,可是会调用多次onStartCommand,此时系统仅仅会创建一个Service实例,因此仅仅须要调用一次stopService方法就能够停掉服务。

假设Service被某个Activity 调用startService方法启动。无论是否有Activity使用bindService绑定或unbindService解除绑定到该Service。该Service都在后台执行。

startService启动的Service将会一直在后台执行,而无论相应程序的Activity是否在执行。直到被调用stopService、或自身的stopSelf方法、或系统资源不足android系统也可能结束该服务。

demo1.java

public class demo1 extends AppCompatActivity {

    private Button start;
private Button stop; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo1); start = (Button) findViewById(R.id.start_Service1);
stop = (Button) findViewById(R.id.stop_Service1); //1.创建启动Service的Intent
final Intent intent = new Intent(demo1.this, service1.class); start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//2.启动service
startService(intent);
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//3.停止service
stopService(intent);
}
}); }
}

service1.java

public class service1 extends Service {
private final String TAG = "service1"; //Service被创建时调用
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate方法被调用");
} //必须要实现的方法
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onCreate方法被调用");
return null;
} //Service被启动时调用
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand方法被调用。");
return super.onStartCommand(intent, flags, startId);
} //Service被关闭之前回调
@Override
public void onDestroy() {
Log.i(TAG, "onDestroy方法被调用!");
super.onDestroy();
}
}

还有注冊一下!

AndroidManifest.xml:

<span style="font-size:18px;"><service android:name=".Service.service1"/></span>

注意:

当Service须要执行在单独的进程中,AndroidManifest.xml声明时须要通过android:process指明此进程名称。

当Service须要对其它App开放时,android:exported属性值须要设置为true(当然在有intent-filter时默认值就是true)。

4.bindService

被绑定的服务的生命周期:onCreate-> onBind-> onUnbind

假设Service被某个Activity调用bindService方法绑定启动。无论调用bindService几次,仅仅会调用一次onCreate方法,同一时候始终不会调用onStartCommand方法。

当连接建立之后,Service将会一直执行,除非调用unbindService断开连接、或之前调用bindService的Context 不存在了,如Activity被finish的时候。系统将会自己主动停止Service。相应的将被调用onDestroy方法。

依据onBind(Intentintent)方法放回的Binder对象的定义方式不同,又能够将其分为下面三种方式。这里。先写第一种方式,此方式Clinet与Service必须同属于同一个进程,不能实现进程间通信(IPC)。否则会出现相似于“android.os.BinderProxycannot be cast to xxx”错误。

demo2.java

public class demo2 extends AppCompatActivity {

    private Button bind;
private Button cancel;
private Intent intent;
private service2 service2;
private service2.myBinder myBinder;
private ServiceConnection conn = new myServiceConnection();
private boolean mBound; //保持所启动的service2的IBinder对象。同一时候定义一个ServiceConnection对象。 private class myServiceConnection implements ServiceConnection { @Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("----Service Connected----");
myBinder = (com.guofeng.demo4.Service.service2.myBinder) service;
service2 = myBinder.getgetService();
mBound = true;
} @Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("----Service DisConnected----");
mBound = false; }
} @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo2);
bind = (Button) findViewById(R.id.bind_service2);
cancel = (Button) findViewById(R.id.cancel_service2);
intent = new Intent(demo2.this, service2.class); bind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bindService(intent, conn, BIND_AUTO_CREATE); }
}); cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
excuteUnbindService();
}
}); } private void excuteUnbindService() {
if (mBound) {
unbindService(conn);
mBound = false;
}
} @Override
protected void onDestroy() {
super.onDestroy();
excuteUnbindService();
}
}

service2.java

public class service2 extends Service {

    private final String TAG = "Service2";
private myBinder binder = new myBinder();
public class myBinder extends Binder {
service2 getgetService() {
return service2.this;
}
} @Override
public void onCreate() {
Log.i(TAG, "onCreate方法被调用");
super.onCreate();
} @Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind方法被调用");
return binder;
} @Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "onUnbind方法被调用");
return super.onUnbind(intent);
} @Override
public void onRebind(Intent intent) {
Log.i(TAG, "onRebind方法被调用");
super.onRebind(intent);
} @Override
public void onDestroy() {
Log.i(TAG, "onDestroy方法被调用");
super.onDestroy();
}
}

当然要记得注冊Service。

注意:

1.自己定义Service继承基类Service。并重写onBind(Intentintent)方法,此方法中须要返回详细的Binder对象;

2.Client通过实现ServiceConnection接口来自己定义ServiceConnection。并通过bindService(Intent service, ServiceConnection sc, int flags)方法将Service绑定到此Client上。

3.自己定义的ServiceConnection中实现onServiceConnected(ComponentNamename, IBinder binder)方法。获取Service端Binder实例;

4.通过获取的Binder实例进行Service端其它公共方法的调用,以完成Client-Service通信。

5.当Client在恰当的生命周期(如onDestroy等)时,此时须要解绑之前已经绑定的Service,通过调用函数unbindService(ServiceConnectionsc)。

其它:

1.假设Service又被启动又被绑定,则该Service将会一直在后台执行。

无论怎样调用,始终仅仅会调用一次onCreate,相应调用多少次startService,Service便会调用多少次onStartCommand。

调用unbindService将不会停止Service,而必须调用stopService 、或Service的stopSelf 来停止服务。

2.当服务的onDestroy方法被调用时,应做一些清除工作。如:停止在Service中创建并执行的线程。

3. 想要用startService启动服务,无论Local还是Remote记得在Androidmanifest.xml 中注冊service。

4. Service本身都是执行在其所在进程的主线程(假设Service与Clinet同属于一个进程。则是执行于UI线程)。但Service一般都是须要进行“长期”操作。所以常常写法是在自己定义Service中处理“长期”操作时须要新建线程,以免堵塞UI线程或导致ANR。

5.IntentService

IntentService是系统提供给我们的一个已经继承自Service类的特殊子类。主要用于防止线程堵塞,处理异步请求。全部的请求将在一个工作线程HandlerThread中处理,工作完成了,线程也就结束了。

1.默认直接实现了onBind方法,直接返回null,并定义了抽象方法onHandlerIntent。用户自己定义子类时,须要实现此方法。

2.onHandlerIntent主要就是用来处于相应的”长期“任务的,而且已经自己主动在新的线程中,用户无语自己定义新线程;

3.当”长期“任务执行完成后,也就是onHandlerIntent执行完成后。此IntentService将自己主动结束,无需人为调用方法使其结束。

4.IntentService处于任务时,也是依照队列的方式一个个去处理。并不是真正意义上的多线程并发方式。

demo3.java

public class demo3 extends AppCompatActivity {
private Context mContext; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo3); mContext = this;
Button btn = (Button) findViewById(R.id.btn3);
assert btn != null;
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent1 = new Intent(mContext, service3.class);
Bundle bundle1 = new Bundle();
bundle1.putString("param", "s1");
intent1.putExtras(bundle1); Intent intent2 = new Intent(mContext, service3.class);
Bundle bundle2 = new Bundle();
bundle2.putString("param", "s2");
intent2.putExtras(bundle2); Intent intent3 = new Intent(mContext, service3.class);
Bundle bundle3 = new Bundle();
bundle3.putString("param", "s3");
intent3.putExtras(bundle3); //接着启动多次IntentService,每次启动,都会创建一个新工作线程
//可是始终仅仅有一个IntentService实例
startService(intent1);
startService(intent2);
startService(intent3);
}
});
}
}

service3.java

public class service3 extends IntentService {
private final String TAG = "IntentService:"; //必须实现父类的构造方法
public service3() {
super("guofeng");
} public service3(String name) {
super(name);
} //必须重写的核心方法
@Override
protected void onHandleIntent(Intent intent) {
String str = intent.getExtras().getString("param");
if (str.equals("s1"))
Log.i(TAG, "启动service1");
else if (str.equals("s2"))
Log.i(TAG, "启动service2");
else if (str.equals("s3"))
Log.i(TAG, "启动service3"); try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} } //重写其它方法,用于查看方法的调用顺序
@Override
public void onCreate() {
Log.i(TAG, "onCreate");
super.onCreate();
} @Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind");
return super.onBind(intent);
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand");
return super.onStartCommand(intent, flags, startId);
} @Override
public void setIntentRedelivery(boolean enabled) {
Log.i(TAG, "setIntentRedelivery");
super.setIntentRedelivery(enabled);
} @Override
public void onDestroy() {
Log.i(TAG, "onDestroy");
super.onDestroy();
}
}

6.前台服务

在 SDK 2.0 及其以后版本号使用的方法是 startForeground 与 stopForeground

NotificationListenerService和Android 通知栏Notification有关。它主要用于接收来自系统调用的服务及新通知的公布或删除。

service4.java

<span style="font-size:18px;">public class service4 extends Service {
public static final String TAG = "Service4"; @Override
public IBinder onBind(Intent intent) {
return null;
} @Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "in onCreate");
} @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand"); PendingIntent pi = PendingIntent.getActivity(
this,
0,
new Intent(this, demo3.class),
PendingIntent.FLAG_CANCEL_CURRENT
);
//NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification.Builder myBuilder = new Notification.Builder(this);
myBuilder.setContentTitle("QQ")
.setContentText("呵呵")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pi);
Notification notification = myBuilder.build();
//nm.notify(1, notification);
//注意使用startForeground,id为0将不会显示notification
startForeground(1, notification);
return START_REDELIVER_INTENT;
} @Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
}
</span>

关注一下onStartCommand(Intent intent, int flags, int startId)方法:


flags默认情况下是0,相应的常量名为START_STICKY_COMPATIBILITY。

startId是一个唯一的整型,用于表示此次Client执行startService方法的请求标识,在多次调用startService的情况下。呈现0,1,2....递增。另外,此函数具有一个int型的返回值。详细的可选值及含义例如以下:

START_NOT_STICKY:当Service由于内存不足而被系统kill后。接下来的某个时间内,即使系统内存足够可用,系统也不会尝试又一次创建此Service。除非程序中Client明白再次调用startService启动此Service。

 

START_STICKY:当Service由于内存不足而被系统kill后,接下来的某个时间内。当系统内存足够可用的情况下,系统将会尝试又一次创建此Service。一旦创建成功后将回调onStartCommand方法,但当中的Intent将是null,pendingintent除外。

 

START_REDELIVER_INTENT:与START_STICKY唯一不同的是,回调onStartCommand方法时。当中的Intent将是非空。将是最后一次调用startService中的intent。

 

 

7.在 AndroidManifest.xml 里 Service 元素的常见选项:

android:name:服务类名

android:label:服务的名字。假设此项不设置。那么默认显示的服务名则为类名

android:icon:服务的图标

android:permission:申明此服务的权限,这意味着仅仅有提供了该权限的应用才干控制或连接此服务

android:process:表示该服务是否执行在另外一个进程,假设设置了此项,那么将会在包名后面加上这段字符串表示还有一进程的名字

android:enabled:假设此项设置为 true,那么 Service 将会默认被系统启动。不设置默认此项为 false

android:exported:表示该服务能否够被其它应用程序所控制或连接。不设置默认此项为 false。


还有好多内容没有写,以后会深入写续集的~

Android 四大组件 Service 服务的更多相关文章

  1. Android四大组件——Service

    Service相关链接 Service初涉 Service进阶 Service精通 Service是Android系统中的一种组件,它跟Activity的级别差不多,但是它不能自己运行,只能后台运行, ...

  2. Android四大组件之服务-Service 原理和应用开发详解

    一.Android 服务简介 Service是android 系统中的四大组件之一(Activity.Service.BroadcastReceiver.ContentProvider),它跟Acti ...

  3. android关键组件service服务(一)

    一. Service简单介绍 Service是android 系统中的四大组件之中的一个(Activity.Service.BroadcastReceiver.ContentProvider),它跟A ...

  4. Android四大组件-Service

    http://blog.csdn.net/guolin_blog/article/details/11952435 http://www.jianshu.com/p/eeb2bd59853f 概述 定 ...

  5. Android四大组件之服务

    创建一个服务,并与活动绑定 作为安卓四大组件之一的服务,毫无例外也要在manifast中进行注册 新建服务类继承于Service,并覆盖onBind( )方法,用于与活动绑定 public class ...

  6. Android四大组件之服务的两种启动方式详解

    Service简单概述 Service(服务):是一个没有用户界面.可以在后台长期运行且可以执行操作的应用组件.服务可由其他应用组件启动(如:Activity.另一个service).此外,组件可以绑 ...

  7. 入职小白随笔之Android四大组件——服务(Service)

    Service Android多线程编程 当我们在程序中执行一些耗时操作时,比如发起一条网络请求,考虑到网速等原因,服务器未必会立刻响应我们的请求,此时我们就需要将这些操作放在子线程中去运行,以防止主 ...

  8. Android 四大组件之再论service

    service常见的有2种方式,本地service以及remote service. 这2种的生命周期,同activity的通信方式等,都不相同. 关于这2种service如何使用,这里不做介绍,只是 ...

  9. Android成长日记-Android四大组件之Service组件的学习

    1.什么是Service? Service是Android四大组件中与Activity最相似的组件,它们都代表可执行的程序,Service与Activity的区别在于:Service一直在后台运行,它 ...

随机推荐

  1. 数据摘要 MD5

    数据一样,摘要一样  (摘要即MD5) 摘要一样,数据一样 摘要是用于检验数据的完整性的技术(比如验证下载的东西是否完整,迅雷就是这样), 查看文件的MD5: Linux         :  md5 ...

  2. PHP+Mysql学习笔记

    1.      PHP is Hypertext Preproocessor. 2.      Hello World: <?php Echo 'Hello World!'; ?> 3.  ...

  3. Android studio 3.0以上版本无法引入,找不到v4,v7包方案解决

    Android studio 3.0以上版本无法引入v4.v7包报红,即找不到v4.v7包,解决方案如下: 步骤: 1,Close Object,点击左上角的关闭工程. 2,点击x,删除项目. 3,重 ...

  4. Android中AES256加密的实现

    AES加密是我们在工作中常用到一种加密方式,并且在java中也已经实现好了其相应的接口. 但是Java自带的JDK默认最多实现128位及其以下的加密.如果使用java自带的api实现aes256将会报 ...

  5. AngularJS中获取数据源的几种方式

    在AngularJS中,可以从$rootScope中获取数据源,也可以把获取数据的逻辑封装在service中,然后注入到app.run函数中,或者注入到controller中.本篇就来整理获取数据的几 ...

  6. Unity Shader-后处理:简单的颜色调整(亮度,饱和度,对比度)

    好久没坚持写blog了,是时候开始撸一波新博文了!学习Unity有一段时间了,关于Shader的书也看了几本<Unity Shader入门精要>,<Unity 3D ShaderLa ...

  7. electron实现类似QQ来新消息时的闪烁与任务栏窗口提醒

    公司项目有一款带即时聊天.群组功能的APP,因为要给客服人员使用,需要开发PC版本.之前使用C#开发过一个PC版本,但是C#的UI这一块支持的不太好,而且升级比较麻烦,我就牵头基于Electron去实 ...

  8. Android 热修复方案Tinker(一) Application改造

    基于Tinker V1.7.5 Android 热修复方案Tinker(一) Application改造    Android 热修复方案Tinker(二) 补丁加载流程    Android 热修复 ...

  9. Verilog 加法器和减法器(8)-串行加法器

    如果对速度要求不高,我们也可以使用串行加法器.下面通过状态机来实现串行加法器的功能. 设A=an-1an-2-a0, B=bn-1bn-2-b0,是要相加的两个无符号数,相加的和为:sum=sn-1s ...

  10. 流媒体Red5服务自定义媒体文件路径

    4. 创建类实现自定义媒体访问路径 使用bean对自己的项目进行配置,更换默认的视频播放目录和视频录制目录.在0.6版的时候, 我们可以直接在red5-web.properties中写入playbac ...