Android Service

一、Service简介

Service是Android程序中的四大组件之一,他和Activity一样都是Context的子类,只不过他没有UI界面,是在后台运行的组件。

二、Service种类

按运行地点分类

类别区别优点缺点应用
本地服务(Local Service)该服务依附在主进程上服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外Local服务因为是在同一进程因此不需要IPC,也不需要AIDL。相应bindService会方便很多。主进程被Kill后,服务便会终止。例如:音乐播放器等不需要常驻的服务
远程服务(Remote Service)该服务是独立的进程服务为独立的进程,对应进程名格式为所在包名加上你指定的android:process 字符串。由于是独立的进程,因此Activity所在进程被Kill的时候,该服务依然在运行,不受其他进程影响,有利于为多个进程提供服务具有较高的灵活性。该服务是独立的进程,会占用一定资源,并且使用AIDL进行IPC。一些提供系统服务的Service 这种 Service是常驻的。

按运行类型分类

类别区别应用
前台服务会在通知栏显示onGoing的Notification当服务被终止的时候,通知一栏的Notification 也会消失,这样对于用户有一定的通知作用。常见的如 "音乐播放服务"
后台服务默认的服务即为后台服务,即不会在通知栏显示 onGoing 的Notification当服务被终止的时候,用户是看不到效果的,某些不需要运行或终止提示的服务,"如天气更新,日期同步,邮件同步等"

按使用方式分类

类别区别
startService启动的服务主要用于启动一个服务执行后台任务,不进行通信。停止服务使用stopService
bindService启动的服务方法启动的服务要进行通信。停止服务使用 unbindService。
同时使用startService、bindService启动的服务停止服务应同时使用stopService与 unbindService。

三、Service生命周期

在这里插入图片描述
onCreate: 系统在service第一次创建时执行此方法,来执行只运行一次的初始化工作。如果service已经运行,这个方法不会被调用。

onStartCommand: 每次客户端调用startService 方法启动该Service都会回调该方法。一旦这个方法执行,service就启动并且在后台长期运行。通过调用stopSelf 或 topService来停止服务。

onBind: 当组件调用 bindService 想要绑定到service时 (例如想要执行进程间通讯) 系统调用此方法 (一次调用,一旦绑定后,下次再调用bindService不会回调该方法) 在你的实现中,你必须提供一个返回一个IBinder 来以使客户端能够使用它与service 通讯,你必须总是实现这个方法,但是如果你不允许绑定,那么你应返回 NULL

onUnbind: 当前组件调用 unbindService,想要解除与service 的绑定时系统调用此方法 (一次调用,一旦解除绑定后,下次再调用unbindService会抛出异常)

onDestory: 系统在service 不再被使用并要销毁时调用此方法 (一次调用)。service 应在此方法中释放资源, 例如 线程,已注册的侦听器,接收器等等。这是service收到的最后一个调用

1.startService/stopService

生命周期:

onCreate
onStartCommand
onDestory

注意点:

  1. 第一次 startService 会触发onCreate 和 onStartCommand,以后在服务运行过程中,每次startService都只会触发onStartCommand
  2. 不论startService多少次,stopService一次就会停止服务

2.bindService/unbindService

生命周期:

onCreate
onBind
onUnBind
onDestory

注意点:
第一次bindService会触发 onCreate、onBind,以后在服务运行过程中,每次调用bindService都不会触发任何回调。

3. 混合型(上面两种方式的交互)

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i(TAG,"onServiceConnected"+service.toString());
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i(TAG,"onServiceDisconnected"+name);

        }
    };
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_life_cycle);
        Intent intent = new Intent(this,BaseService.class);
        startService(intent);
        bindService(intent,connection,BIND_AUTO_CREATE);
               ((Button) findViewById(R.id.btn_next)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopService(intent);
            }
        });
        ((Button) findViewById(R.id.btn_back)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                unbindService(connection);
            }
        });
    }

public class BaseService extends Service {
    public static final String TAG = "BaseService";
    private MyBinder myBinder;

    @Override
    public void onCreate() {
        super.onCreate();
        myBinder = new MyBinder();
        Log.i(TAG, "onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind");
        return myBinder;
    }

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

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

    class MyBinder extends IMyAidlInterface.Stub {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
                               double aDouble, String aString) {

        }
    }
}

生命周期:

onCreate
onStartCommand
onBind

执行stopService时无效
执行 "unbindService(connection)"

unBind
onDestory

4.前台服务

所谓前台服务只不过通过一定的方式将服务所在的进程级别提升了。前台服务会一直有一个正在运行的图标再系统的状态栏显示。非常类似与通知效果。

Service 的 startForegroud 方法可启动为前台服务。
执行 startForegroud 方法时需要添加权限 <uses-permissionandroid:name=“android.permission.FOREGROUND_SERVICE”/>

intent = new Intent(this, ForeService.class);
startService(intent);

public class ForeService extends Service {
    private static final String childID = "channel_1";
    private static final String childName = "channel";
    private static final String description = "这个市描述Description";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        beginForeService();
    }

    private void beginForeService() {
       NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            int importanceHigh = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel channel = new NotificationChannel(childID,childName,importanceHigh);
            channel.setDescription(description);
            channel.enableLights(true);
            channel.setLightColor(Color.BLUE);
            channel.enableVibration(true);//是否震动
            channel.setVibrationPattern(new long[]{100,200,300,400,500,400,300,200,400});
            channel.setShowBadge(true);
            manager.createNotificationChannel(channel);
        }
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this,childID)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("标题")
                .setContentText("内容");
        Intent intent = new Intent(this,TwoLifeCycleActivity.class);
        TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(this);
        taskStackBuilder.addParentStack(TwoLifeCycleActivity.class);
        taskStackBuilder.addNextIntent(intent);
        PendingIntent pendingIntent = taskStackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(pendingIntent);
        manager.notify(1,builder.build());
        startForeground(1,builder.build());
    }
}

使用PendingIntent来跳转到 TwoLifeCycleActivity
这句话的意思是:为跳转后的activity添加一个父activity,在activity中manifest中添加parentActivityName即可

        <activity
            android:name=".TwoLifeCycleActivity"
            android:parentActivityName=".LifeCycleActivity"/>

parentActivity为LifeCycleActivity,也就是说在TwoLifeCycleActivity这个界面点击回退时,会跳转到MainActivity这个界面,而不是像上面一样直接回到home菜单。

stopForeground 方法可以取消通知,将前台服务降至后台服务。
此时服务依然存在没有停止,
stopService可以把前台服务停止

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值