再忆Service(一)

Service基本使用

Service是长时间驻留在Android中的一种后台服务, 主要用于消息处理, 跨进程之间的通信. 例如, 使用手机能够边播放音乐边使用其他应用就是因为音乐应用通过Service播放.

0x10 简介

Service有两种启动方式, 分别为Startbind方式:

状态 描述
Started Android的应用程序组件,如活动,通过startService()启动了服务,则服务是Started状态。一旦启动,服务可以在后台无限期运行,即使启动它的组件已经被销毁。
Bound 当Android的应用程序组件通过bindService()绑定了服务,则服务是Bound状态。Bound状态的服务提供了一个客户服务器接口来允许组件与服务进行交互,如发送请求,获取结果,甚至通过IPC来进行跨进程通信。

0x11 生命周期

services

0x12 回调方法

回调 描述
onStartCommand() 其他组件(如活动)通过调用startService()来请求启动服务时,系统调用该方法。如果你实现该方法,你有责任在工作完成时通过stopSelf()或者stopService()方法来停止服务。
onBind 当其他组件想要通过bindService()来绑定服务时,系统调用该方法。如果你实现该方法,你需要返回IBinder对象来提供一个接口,以便客户来与服务通信。你必须实现该方法,如果你不允许绑定,则直接返回null。
onUnbind() 当客户中断所有服务发布的特殊接口时,系统调用该方法。
onRebind() 当新的客户端与服务连接,且此前它已经通过onUnbind(Intent)通知断开连接时,系统调用该方法。
onCreate() 当服务通过onStartCommand()和onBind()被第一次创建的时候,系统调用该方法。该调用要求执行一次性安装。
onDestroy() 当服务不再有用或者被销毁时,系统调用该方法。你的服务需要实现该方法来清理任何资源,如线程,已注册的监听器,接收器等。

0x20 代码示例

定义一个ServiceDemo.class类, 作为处理消息的主要类:

package com.killshadow.attackhms;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class ServiceDemo extends Service {
    private static final String TAG = "ServiceDemo";
    private int count;
    private boolean start;

    // 用于onBind的时候返回给客户端
    private MyBinder binder = new MyBinder();
    public class MyBinder extends Binder {
        public int getCount() {
            return count;
        }
    }

    // Service最开始启动的回调方法, 如果已经onCreate, 则bindService的时候直接onBind
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG,"ServiceDemo -> onCreate, Thread ID: " + Thread.currentThread().getId());
        this.start = true;
        // 创建一个线程动态修改count的值
        new Thread() {
            public void run() {
                while (start) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // 每秒加1
                    count++;
                }
            }
        }.start();
    }

    // startService的时候回调用这个回调
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "ServiceDemo -> onStartCommand, startId: " + startId + ", Thread ID: " + Thread.currentThread().getId());
        return START_STICKY;
    }

    // bindService的时候, 一定会调用这个回调
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "ServiceDemo -> onBind, Thread ID: " + Thread.currentThread().getId());
        return binder;
    }

    // 当service被unBind之后, 再次bind的时候会调用这个回调
    @Override
    public void onRebind(Intent intent) {
        super.onRebind(intent);
        Log.i(TAG, "ServiceDemo -> onRebind");
    }

    // 调用unbindService的时候会调用这个方法
    @Override
    public boolean onUnbind(Intent intent) {
        Log.i(TAG, "ServiceDemo -> onUnbind");
        return true;
    }

    // stopService会调用这个回调, 销毁service
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "ServiceDemo -> onDestroy, Thread ID: " + Thread.currentThread().getId());
        this.start = false;
    }
}

下面分别介绍两种启动Service的方法.

0x21 Started

Intent intent = new Intent(mContext, ServiceDemo.class);
// start-stop Service
startService(intent);
stopService(new Intent(mContext, ServiceDemo.class));

通过Start/Stop方法开启/关闭Service的方式比较简单, 发送intent即可.

0x22 Bound

ServiceDemo.MyBinder myBinder;
private ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        Log.i(TAG, "Service Connected: " + name.getClassName());
        myBinder = (ServiceDemo.MyBinder) service;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        Log.i(TAG, "Service DisConnected: " + name.getClassName());
    }
};

button1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // unbind的时候检查count的值
        Toast.makeText(mContext, "Count: " + myBinder.getCount(), Toast.LENGTH_SHORT).show();
        unbindService(conn);
    }
});

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

推荐阅读更多精彩内容

  • 人生的道路虽然漫长,但紧要处常常只有几步,特别是当人年轻的时候。 没有一个人的生活道路是笔直的、没有岔道的。有...
    风继续吹SH阅读 152评论 0 0
  • 这是冬天的第一场雪大家都非常开心是啊我也非常喜欢下雪下午的时候老师带着我们来到操场上老师说我们来比赛堆雪人吧如果女...
    87bfde696eb9阅读 89评论 0 0
  • 8月15日是我们中华民族的传统节日,那一天,月亮很圆,传说,月亮上面有长娥,和月兔。还有一个是蒙古人建造的元...
    小蝴蝶杨蒙松阅读 183评论 0 0
  • 生命之歌 我们是年轻战士 那时代美好的希望 落在我们稚嫩的肩上 凭一股青春豪情 鼓起那理想的风帆 驶向改革的巨潮 ...
    无心剑阅读 407评论 0 2
  • 引言 关于放寒暑假,有段子云: 问:为何要放寒暑假? 神回复:那是给老师疗伤用的,再不放假怕老师会疯。 又问:又为...
    远走高飞的灵与肉阅读 551评论 0 0