Android 四大组件之Service

本文详细介绍了Android四大组件中的Service,包括进程被kill的五个级别,服务的启动方式(startService和bindService),服务生命周期,AIDL远程服务调用,以及如何将服务提升为前台进程。重点探讨了Service的使用场景和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android 四大组件之Service


本文由 Luzhuo 编写,转发请保留该信息.
原文: http://blog.csdn.net/rozol/article/details/79606166


服务 (可理解为没有界面的Activity)
四大组件(Activity / BroadcastReceiver / Service / ContentProvider)之一
四大组件均运行于主线程

进程被kill的5个级别

  • 进程被kill的5个级别
      1. 前台进程: 用户能与Activity交互的进程(相当于onResume())
      1. 可视进程: 用户能对Activity可见, 但是不能对其进行操作(没有焦点, 相当于onPause())
      1. 服务进程: 没有界面, 通过startService()开启的服务
      1. 后台进程: 用户不可见 (相当于onStop())
      1. 空进程: 没有维持任务组件运行, 不kill是为了下次开启速度
        */

服务使用

startService开启服务 (级别3)

  • 清单配置

    <service android:name=".service.StartService"/>
    
  • 服务代码

    public class StartService extends Service {
        private static final String TAG = StartService.class.getSimpleName();
    
        /**
         * 当服务第一次被开启的时候调用, 即使多次调用startService(intent);
         */
        @Override
        public void onCreate() {
            Log.i(TAG, "onCreate");
            super.onCreate();
        }
    
        /**
         * 服务销毁的时候执行
         */
        @Override
        public void onDestroy() {
            Log.i(TAG, "onDestroy");
            super.onDestroy();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.i(TAG, "onStartCommand");
            return super.onStartCommand(intent, flags, startId);
        }
    
    
    
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    }
  • 调用代码

    Intent intent = new Intent(this, StartService.class);
    
    /**
     * 用startService的方式开启服务
     */
    public void click1(View v) {
        // 开启服务 (级别3)
        startService(intent);
    }
    
    /**
     * 停止用startService的方式开启服务
     * @param v
     */
    public void click2(View v) {
        // 停止服务
        stopService(intent);
    }

bindService开启服务 (级别?[随Activity的销毁而销毁])

  • 清单配置 (略)
  • 服务代码

    public class BindService extends Service {
        private static final String TAG = BindService.class.getSimpleName();
    
        /**
         * 当服务第一次被开启的时候调用, 只执行一次
         */
        @Override
        public void onCreate() {
            Log.i(TAG, "onCreate");
            super.onCreate();
        }
    
        /**
         * 连接(绑定), 只执行一次
         * @param intent
         * @return
         */
        @Override
        public IBinder onBind(Intent intent) {
            Log.i(TAG, "onBind");
            return new MyBinder(); // 返回自定义的Binder对象
        }
    
        /**
         * 服务销毁的时候执行
         */
        @Override
        public void onDestroy() {
            Log.i(TAG, "onDestroy");
            super.onDestroy();
        }
    
    
        /**
         * 定义IBinder对象
         */
        private class MyBinder extends Binder implements IService{
            /**
             * 创建让Activity调用的Binder方法
             */
            public String call(String str){
                return str + "123";
            }
            public void call1(){}
        }
    }
  • 限制Binder调用方法的接口

    public interface IService {
        public String call(String str);
    }
    
  • 调用代码

    Intent intent = new Intent(this, BindService.class);
    
    /**
     * 用 bindservice 开启的服务
     * @param v
     */
    public void click3(View v) {
        bindService(intent, connection, BIND_AUTO_CREATE);
    }
    
    /**
     * 停止用 bindservice 开启的服务
     * @param v
     */
    public void click4(View v) {
        unbindService(connection);
    }
    
    /**
     * 通过binder调用服务里的方法
     * @param view
     */
    public void click5(View view){
        Log.e(TAG, myBinder.call("ABC"));
        // myBinder.call1(); // 不能调
    }
    
    IService myBinder;
    /**
     * 用来监听服务的状态
     */
    ServiceConnection connection = new ServiceConnection() {
        /**
         * 连接成功后调用
         */
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.i(TAG, "onServiceConnected");
            myBinder = (IService) iBinder; // 取出binder对象, 用于调用服务里的方法
        }
        /**
         * 失去连接调用
         */
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.i(TAG, "onServiceDisconnected");
        }
    };

startService + bindService 开启服务

  • 将startService和bindService的代码整合在一起
    • 开始服务: start + bind
    • 退出Activity: unbind
    • 停止服务: (unbind) + stop
  • 服务部分

    public class StartBindService extends Service {
        private static final String TAG = StartBindService.class.getSimpleName();
    
        @Override
        public void onCreate() {
            Log.i(TAG, "onCreate");
            super.onCreate();
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            Log.i(TAG, "onBind");
            return new MyBinder();
        }
    
        @Override
        public void onDestroy() {
            Log.i(TAG, "onDestroy");
            super.onDestroy();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.i(TAG, "onStartCommand");
            return super.onStartCommand(intent, flags, startId);
        }
    
        /**
         * 定义IBinder对象
         */
        private class MyBinder extends Binder implements IService {
            /**
             * 创建让Activity调用的Binder方法
             */
            public String call(String str){
                return str + "123";
            }
            public void call1(){}
        }
    }
  • 调用代码

    Intent intent = new Intent(this, StartBindService.class);
    }
    
    /**
     * 开启服务
     * @param view
     */
    public void onclick1(View view){
        // 先调start
        startService(intent);
    
        // 再掉bind
        bindService(intent, connection, BIND_AUTO_CREATE);
    }
    
    /**
     * 解绑服务
     */
    public void onclick2(View view){
        // 先调unbind
        unbindService(connection);
    }
    
    /**
     * 停止服务
     */
    public void onclick3(View view){
        // 再调stop
        stopService(intent);
    }
    
    public void onclick4(View view){
        Log.e(TAG, myBinder.call("ABC"));
    }
    
    IService myBinder;
    /**
     * 用来监听服务的状态
     */
    ServiceConnection connection = new ServiceConnection() {
        /**
         * 连接成功后调用
         */
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.i(TAG, "onServiceConnected");
            myBinder = (IService) iBinder; // 取出binder对象, 用于调用服务里的方法
        }
        /**
         * 失去连接调用
         */
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.i(TAG, "onServiceDisconnected");
        }
    };

服务的生命周期

/*
startService开启的服务:
    无法调用服务里的方法
    退出Activity时无须停止
    手机设置服务界面可找到
startService开启的服务的生命周期
    StartService开启的生命周期: onCreate -> onStartCommand
    StartService停止的生命周期: onDestroy

    StartService已开启执行startService: onStartCommand

bindService开启的服务:
    可以调用服务里的方法
    退出Activity时服务也随之停止
    手机设置服务界面不可找到
    只能进行一次unbind
bindService开启的服务的生命周期
    BindService开启的生命周期: onCreate -> onBind -> (onServiceConnected)
    BindService停止的生命周期: onDestroy

    BindService已开启执行bindService: -

start+bind 开启的服务
    可以调用服务里的方法
    退出Activity不会停止, 但要解绑
    手机设置服务界面可以找到
    只能进行一次unbind
生命周期:
    StartBindService开启的生命周期: onCreate -> onStartCommand -> onBind -> (onServiceConnected)
    StartBindService解绑的生命周期: -
    StartBindService停止的生命周期: onDestroy
 */

AIDL 远程服务调用

  • 用于
    • 本地服务
    • 远程服务
    • 进程间通信
  • .aidl进程间通信语言, 系统自动生成iBinder
  • 见 IPC 文章

将服务从 服务进程[3] 提升为 前台进程[1]

使用通知的方式

  • 代码

    public class MyService extends Service {
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            // 通知与服务结合
            Notification notification = new NotificationCompat.Builder(this).build();
            // 升级为前台进程
            startForeground(1, notification);
        }
    
        public void stop(){
            // 取消前台进程
            stopForeground(true);
        }
    
        /*
        通过命令 `adb shell dumpsys meminfo` 查看进程
    
        22,260K: Perceptible
        12,770K: me.luzhuo.servicedemo (pid 4970)
        */
    }
  • 使用这种方式的代价是: 通知栏会有个通知

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值