3.Service

Android Service中显示Dialog

1.启动方式

Service有两种启动方式,分别通过startService方法和bindService方法启动

  • startService通过这种方法启动的Service,在启动它的应用退出后,仍然会继续运行,除非服务自身调用stopSelf()或者外部接口调用stopService()方法才能停止服务;当服务停止时,系统会销毁服务
  • bindService通过这种方法启动的Service,是与启动他的应用绑定在一起的,即应用退出时,该服务也退出;如果要停止服务,需要调用unBindService()方法> 通过startService启动的服务可以被绑定,即通过bindService()方法与Activity绑定。此时如果需要关闭Service,需要先调用方法unBindService()然后stopService(),否则Service是不会被关闭的

2.生命周期

Paste_Image.png

通过StartService()启动

不论调用几次startService(),Service中onCreate()方法只调用一次,但是每次都会调用onStartCommand()
当调用stopService() / stopSelf()时,如果此时Service未与任何组件绑定,会直接调用onDestroy()方法销毁服务

通过onBindService()绑定

不论调用几次bindService(),Service中onCreate()方法只调用一次,但是每次都会调用onBind()
当调用unBindService()时,系统会回调一个onUnbind()回调方法,然后再销毁服务

先通过onStartService()启动,再通过onBindService()绑定

不论调用几次startService(),Service中onCreate()方法只调用一次,但是每次都会调用onStartCommand()
当终止Service时,需要先unbindService(),再stopService()。如果先调用stopService()将不会停止Service

附加参数

onStartCommand() 提供一个返回值,告诉系统在onStartCommand()方法调用结束后Service被kill时如何重启Service。返回值有如下几种

  • START_STICKY 如果Service被kill,那么系统会在随后试图重新启动Service,但是不会继续使用前次传入的Intent对象
  • START_NOT_STICKY 如果Service被kill,系统不会试图重新启动Service
  • START_REDELIVER_INTENT 类似于START_STICKY,但是会重新传入Intent对象
  • START_STICKY_COMPATIBILITY START_STICKY的兼容版本,当START_STICKY不好使时可以试一下这个参数

Foreground Service

使用Foreground Service,使Service在内存回收中获得更高优先级,比后台Service更不容易被系统kill通过在Service的onStartCommand()回调方法中调用startForeground()方法,可以让Service在前台运行通过调用stopForeground()方法,可以让Service停止前台运行,但是Service本身不会被停止

保证service不被杀掉

1.onStartCommand方法,返回START_STICKY

//onStartCommand方法,返回START_STICKY
@Override  
public int onStartCommand(Intent intent, int flags, int startId) {  
    flags = START_STICKY;  
    return super.onStartCommand(intent, flags, startId);  
}

**【结论】 **手动返回START_STICKY,亲测当service因内存不足被kill,当内存又有的时候,service又被重新创建,比较不错,但是不能保证任何情况下都被重建,比如进程被干掉了....

2.提升service优先级

在AndroidManifest.xml文件中对于intent-filter可以通过android:priority = "1000"这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时适用于广播。

<service  
    android:name="com.dbjtech.acbxt.waiqin.UploadService"  
    android:enabled="true" >  
    <intent-filter android:priority="1000" >  
        <action android:name="com.dbjtech.myservice" />  
    </intent-filter>  
</service> 

【结论】目前看来,priority这个属性貌似只适用于broadcast,对于Service来说可能无效

3. Android开发之如何保证Service不被杀掉(broadcast+system/app)

服务不被杀死分3种来讨论
1.系统根据资源分配情况杀死服务
2.用户通过 settings
-> Apps
-> Running
-> Stop
方式杀死服务
3.用户通过 settings
-> Apps
-> Downloaded
-> Force Stop
方式杀死服务

第一种情况:
用户不干预,完全靠系统来控制,办法有很多。比如 onStartCommand() 方法的返回值设为 START_STICKY
,服务就会在资源紧张的时候被杀掉,然后在资源足够的时候再恢复。当然也可设置为前台服务,使其有高的优先级,在资源紧张的时候也不会被杀掉。

第二种情况:
用户干预,主动杀掉运行中的服务。这个过程杀死服务会通过服务的生命周期,也就是会调用 onDestory() 方法,这时候一个方案就是在 onDestory() 中发送广播开启自己。这样杀死服务后会立即启动。如下:

 @Override
    public void onCreate() { // TODO Auto-generated method stub 
        super.onCreate();
        mBR = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Intent a = new Intent(ServiceA.this, ServiceA.class);
                startService(a);
            }
        };
        mIF = new IntentFilter();
        mIF.addAction("listener");
        registerReceiver(mBR, mIF);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Intent intent = new Intent();
        intent.setAction("listener");
        sendBroadcast(intent);
        unregisterReceiver(mBR);
    }

当然,从理论上来讲这个方案是可行的,实验一下也可以。但有些情况下,发送的广播在消息队列中排的靠后,就有可能服务还没接收到广播就销毁了(这是我对实验结果的猜想,具体执行步骤暂时还不了解)。所以为了能让这个机制完美运行,可以开启两个服务,相互监听,相互启动。服务A监听B的广播来启动B,服务B监听A的广播来启动A。经过实验,这个方案可行,并且用360杀掉后几秒后服务也还是能自启的。到这里再说一句,如果不是某些功能需要的服务,不建议这么做,会降低用户体验。
第三种情况:
强制关闭就没有办法。这个好像是从包的level去关的,并不走完整的生命周期。所以在服务里加代码是无法被调用的。处理这个情况的唯一方法是屏蔽掉 force stop
和 uninstall
按钮,让其不可用。方法自己去找吧。当然有些手机自带的清理功能就是从这个地方清理的,比如华为的清理。所以第三种情况我也没有什么更好的办法了。

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

推荐阅读更多精彩内容