Service 学习

Service 学习要点

1.Service概述

Service的主要作用是让系统在后台在后台做一些不与用户交互的操作(例如耗时操作:下载网络资源,长期运行的操作:播放音乐)
Service与Thread的区别:(1)Service不是在一个独立的进程中,它与我们的应用程序在同一进程(process)中 (2)Service也不是一个线程,相反,它是运行在主线程的(即UI线程),因此若我们要在Service中进行耗时操作时,需要开启一个子线程,在其中进行耗时操作,否则很容易出现ANR错误(Application Not Responding 程序无响应)

2.Service用法

ServiceTest.java如下:

public class ServiceTest extends Service {

private MyLocalBinder myLocalBinder=new
MyLocalBinder();

@Override
public void onCreate() {
    super.onCreate();
    Log.e("TAG","onCreate");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.e("TAG","onStartCommand");
    return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
    Log.e("TAG","onBind");
    return myLocalBinder;
}

@Override
public boolean onUnbind(Intent intent) {
    Log.e("TAG","onUnbind");
    return super.onUnbind(intent);
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.e("TAG","onDestroy");
}

//对外提供的访问方法
public void downLoad(){
    Log.e("downLoad","正在下载...");
}
public void undownLoad(){
    Log.e("downLoad","取消下载...");
}
class MyLocalBinder extends Binder{
    public ServiceTest getServiceTestInstance(){
        return ServiceTest.this;
    }
    //...这里也可以继续写方法对外提供
}

}

与Activity相似,使用Service也需要通过intent,不能忘记的是在使用Service前,需要在AndroidManifest.xml中进行声明

启动方式一:startService()

通过打印Service的生命周期,我们发现第一次启动Service的时候,会执行onCreate()和onStartCommand(),**
再次启动时,只会执行onStartCommand(),也就是说onCreate()只会在第一次启动的时候进行初始化
**点击“stopService”后,Service被销毁,进入onDestroy()方法。不管我们启动了多少次Service,只要我们在外部调用一次Context.stopService()或者在Service内部调用stopSelf(),Service就会被销毁

上面这种启动方式的缺点:启动完Service后,这个Service就在后台运行了,同时也与启动它的Activity失去了联系,因为不能通过ServiceTest service = new ServiceTest()的方式启动Service,因而我们的Activity中不能获取到ServiceTest的实例。
为了解决与启动Service的组件的通信能力,还有一个解决方案就是通过广播的形式。我们在Activity中发出一些想用操作广播,在Service中注册该广播,Service接收到该广播信息后,完成相应的功能。但是频繁发送广播比较消耗性能,同时,由于广播接受者中的onReceive()中,不能执行长时间的工作,时间超过后,可能就直接跳出了方法。因此,这种方案不是首选。

启动方式二:bindService() Bound机制

通过bindService()方式第一次启动后,会执行onCreate()和onBind()方法,当我们点击“unBindService“时,走的是onUnbind()和onDestroy()方法。如果有另一个组件对同一个Service进行bindService()操作(也就是在bindService()中传入不同的ServiceConnection,此时只会进入onBind()方法,即onCreate()只会在第一次启动的时候进行初始化

总结:可以看到,不管是通过哪种方式启动Service,同一个Service在整个应用程序中只有一个实例存在。区别:(1)两种方式所走的生命周期是不一样的(2)何时被销毁:当我们通过startService()启动时,不管我们启动了多少次Service,只要我们在外部调用一次Context.stopService()或者在Service内部调用stopSelf(),Service就会被销毁;而当我们通过bindService()启动时,前面我们多次启动service后,当所有客户端发出unBindService(),这个Service将被系统销毁。(3)当Service即被startService()启动也被bindService()启动时,这种情况下,Service必须在既没有任何activity关联又停止的情况下,Service才会被销毁。

3.IntentService

我们在第一部分谈到,有时需要在service中进行耗时操作,此时就需要开启一个子线程,而对于这种需求,Android提供了IntentService给用户,intentservice内部已经帮我们开启了线程,我们只需要实现它的onHandleIntent方法,在里面实现我们的功能即可,注:intentservice不能处理多个线程的请求,但是可以处理多个service的请求(此处求解?)

IntentService提供的功能:(1)所有请求处理完成后自动停止服务(2)提供了默认onBind()的实现,直接返回null,意味着我们只能通过startService()的方式启动IntentService

public class MyIntentService extends IntentService

{

public MyIntentService()

{
super("MyIntentService");
}

@Override
protected void onHandleIntent(Intent intent) {
    Log.e("MyIntentService","Thread is"+Thread.currentThread().getId());
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.e("OnDestroy","OnDestroy");
}

}

使用时需注意两点:首先要提供一个无参的构造方法,里面调用父类的有参构造方法,第二是实现onHandleIntent这个抽象方法。

4.前台Service

Service默认都是在后台默默运行的,用户基本察觉不到有Service在运行。此时,Service的优先级是比较低的,当系统资源不足的时候,易被销毁。因此,如果我们想让用户知道有Service在后台运行,如音乐播放器,或者想让Service一直保持运行状态,不容易被系统回收,此时,就可以考虑使用前台Service。前台Service是被认为是用户已知的正在运行的服务,当系统需要释放内存时不会优先杀掉该进程。
用法:

@Override

public void onCreate() {

    super.onCreate();
    Log.e("TAG","onCreate");
    Notification notification=new Notification(R.mipmap.ic_launcher,"前台通知",System.currentTimeMillis());
    Intent intent=new Intent(this,MainActivity.class);
    PendingIntent pendingIntent=PendingIntent.getActivity(this,0,intent,0);
    notification.setLatestEventInfo(this, "通知标题", "前台Service内容", pendingIntent);
    //设置到前台运行,第一个参数为通知notification的唯一ID
    startForeground(1,notification);
}
(关于Notification在SDK23以后和SDK22之前用法不一样,上面是SDK22以前的,下面是SDK23以后的)

Notification.Builder builder=new Notification.Builder(getApplication());
    builder.setContentInfo("补充内容");
    builder.setContentText("主内容区");
    builder.setContentTitle("通知标题");
    builder.setSmallIcon(R.mipmap.ic_launcher);
    builder.setTicker("新消息");
    builder.setAutoCancel(true);
    builder.setWhen(System.currentTimeMillis());
    Intent intent = new Intent(getApplication(), MainActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(getApplication(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    builder.setContentIntent(pendingIntent);
    Notification notification = builder.build();

如果我们要移除这个前台Service,只需要调用stopService()即可

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容