Android 服务 Service

本文详细解析了Android中Service的生命周期、分类及应用实例,包括后台服务的启动方式、与Activity的交互过程,以及如何实现前台服务和后台服务,本地服务与远程服务的区别,通过具体代码展示了Service的绑定和解绑流程。

1、Service 生命周期

在这里插入图片描述

2、Service 分类
  1. 按功能分类
类别特点
不可通信后台服务1.startService 启动。2.调用者退出能存在
可通信后台服务1.bindService 启动。2.随调用者的销毁而销毁
  1. 按运行类型分类
类别特点
前台服务1.通知栏显示。2.优先级更高,不会因内存不足被回收
后台服务1.后台运行。2.内存不足会被回收
  1. 按运行地点分类
类别特点
本地服务1.运行在主线程。2.主线程终止,服务也会终止
远程服务1.运行在独立线程。2.服务常驻后台,不受 Activity 影响
3、Service 应用
public class ServiceActivity extends AppCompatActivity implements View.OnClickListener{

    private MyService.MyBinder binder;
    private Intent intent;
    private MyServiceConnection conn = new MyServiceConnection();
    private boolean isConnected = false;
    private class MyServiceConnection implements ServiceConnection{

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            binder = (MyService.MyBinder)service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            binder = null;
        }
    }
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_service);
        findViewById(R.id.btn_startService).setOnClickListener(this);
        findViewById(R.id.btn_bindService).setOnClickListener(this);
        findViewById(R.id.btn_stopService).setOnClickListener(this);
        findViewById(R.id.btn_unbindService).setOnClickListener(this);
        findViewById(R.id.stopForeground).setOnClickListener(this);
        intent = new Intent(this,MyService.class);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_startService:
                startService(intent);
                break;
            case R.id.btn_bindService:
                isConnected = bindService(intent,conn, Context.BIND_AUTO_CREATE);
                break;
            case R.id.btn_stopService:
                stopService(intent);
                break;
            case R.id.btn_unbindService:
                if(isConnected){
                    unbindService(conn);
                    isConnected = false;
                }
                break;
            case R.id.stopForeground:
                if(binder!=null){
                    binder.getService().stopForeground();
                }
                break;
        }
    }
}

public class MyService extends Service {

    private MyBinder binder = new MyBinder();
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("tag","onCreate");
        // 后台服务转前台服务
        sendSimpleNotification(this);
    }

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

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("tag","onDestroy");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e("tag","onBind");
        return binder;
    }

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

    public class  MyBinder extends Binder{
        public MyService getService() {
            return MyService.this;
        }
    }

    public void sendSimpleNotification(Context context) {

        int id = 1000;
        String groupId = "groupId_1";
        String groupName = "渠道组名1";
        String channelId = "channelId_1";
        String channelName = "渠道名1";

        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId);

        builder.setContentTitle("简单的通知的标题")
                .setContentText("这是通知内容")
                .setLargeIcon(BitmapFactory.decodeResource(
                        context.getResources(),
                        R.mipmap.ic_launcher))
                .setAutoCancel(true)// 自己维护通知的消失
                .setSmallIcon(R.mipmap.ic_launcher)
                .setPriority(NotificationCompat.PRIORITY_HIGH);

        //构建一个Intent
        Intent resultIntent = new Intent( context,MainActivity.class);
        // 封装一个Intent
        PendingIntent resultPendingIntent = PendingIntent.getActivity(
                context, 0, resultIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        builder.setContentIntent(resultPendingIntent);

        // 这里必须设置chanenelId,要不然该通知在8.0手机上,不能正常显示
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createChannelId(context,groupId,groupName,channelId,channelName);
            builder.setChannelId(channelId);
        }

        // 让Service变成前台Service,并在系统的状态栏显示
        startForeground(id, builder.build());

//        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//        notificationManager.notify(id, builder.build());
    }

    @RequiresApi(Build.VERSION_CODES.O)
    public static void createChannelId(Context context,String groupId,String groupName , String channelId,String channelName){

        // 分组(可选)groupId 要唯一
        NotificationChannelGroup ncp1 = new NotificationChannelGroup(groupId, groupName);

        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannelGroup(ncp1);

        // channelId 要唯一
        NotificationChannel chan = new NotificationChannel(channelId,
                channelName,
                NotificationManager.IMPORTANCE_DEFAULT);
        chan.setLightColor(Color.GREEN);
        chan.setGroup(groupId);
        // VISIBILITY_PRIVATE:表面只有当没有锁屏的时候才能够显示,VISIBILITY_PUBLIC:表明任何情况下都会显示,VISIBILITY_SECRET:表明在pin,password等安全锁和没有锁屏的情况下才能够显示
        chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
        notificationManager.createNotificationChannel(chan);
    }

    public void stopForeground(){
        stopForeground(true);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值