再忆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);
    }
});
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

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

友情链接更多精彩内容