Android学习笔记之Service

Service在程序的后台运行

Service

Service是Context的子类

UI控件是线程不安全的,所有的UI操作必须在主线程中

Service并不会自动开启线程,所有代码默认运行在主线程,要手动开启子线程

在服务里开的子线程(IntentService)比在活动里开的子线程(AsyncTask)重要性更高更不容易被杀死

Service的使用

右击New→Service→Service

Export属性表示是否允许其它程序访问这个Service

Enabled属性表示是否启用这个Service

在任何一个位置都可以调用stopSelf()方法使Service停止

普通使用

启动Service

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

结束Service

Intent intent=new Intent(this,MyService.class);
stopService(intent);

与Activity绑定

public class MyService extends Service {
​
    class MyBinder extends Binder{
        public void startSomething(){
            ...//可以在这里开IntentService
        }
    }
​
    public MyService() { }
​
    @Override
    public void onCreate() {
        super.onCreate();
    }
​
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }
​
    @Override
    public IBinder onBind(Intent intent) {
        return new MyBinder();//把连接器暴露给外部,活动就可以使用连接器里的方法,在Service中执行
    }
​
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

在活动中使用ServiceConnection获得Service返回回来的连接器

实现了指挥服务去干什么服务就去干什么的功能

private ServiceConnection connection=new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        MyService.MyBinder myBinder=(MyService.MyBinder) service;//获得连接器
        myBinder.startSomething();//执行连接器中的方法
    }
​
    @Override
    public void onServiceDisconnected(ComponentName name) { }
};

启动绑定

Intent intent=new Intent(this,MyService.class);
bindService(intent,connection,BIND_AUTO_CREATE);//通过ServiceConnection与后台某项特定服务绑定

结束绑定

unbindService(connection);

Service的生命周期

若进程里的Service正在执行生命周期回调,那么这个进程属于前台进程

若进程里的Service与目前处于前台的活动绑定,那么这个进程属于前台进程

使用startService()方式启动

只有第1次启动执行onCreate()->每次启动都执行onStartCommand()->stopService()/自己stopSelf()则执行onDestroy()

  • 适用于长期执行进行某项任务

  • 不管是否有Activity使用bindService()/unbindService()到该Service,该Service一直在后台运行,直到被调用stopService()/自己stopSelf()

  • 不管startService()多少次,stopService()1次就会停止服务

  • Service启动之后就和Activity没什么关联了,不要求在Activity退出时手动退出Service

使用bindService()方式启动

只有第1次启动执行onCreate()->只有第1次启动执行onBind()->unbindService()则执行onUnBind()->onDestroy()

  • 适用于与正在运行的Service取得联系/类似懒汉式的思路,开始先不创建,在需要用到的时候去bind一下,节约资源

  • 该Service一直在后台运行,直到被调用unbindService()解绑/绑定了该Service的Context不存在了

  • Service生命周期依附于启动它的Context,因此当前台调用bindService()的Context销毁,Service也会自动调用onUnbind()和onDestory()

使用混合型方式启动

Service被startService()的同时又被bindService(),该Service将会一直在后台运行,并且不管调用几次,onCreate()方法始终只会调用一次,onStartCommand()的调用次数与startService()调用的次数一致(使用bindService()方法不会调用onStartCommand())。同时,调用unBindService()将不会停止Service,必须调用stopService()或Service自身的stopSelf()来停止服务

前台Service

8.0+Service运行在后台时随时会被系统回收,只有应用前台可见时(以类似通知的形式存在),Service才能稳定运行

渠道一旦建立,修改渠道属性将不再生效,除非卸载重装/更改渠道id

9.0+需要添加一条普通权限

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

在Service的onCreate()方法

@Override
    public void onCreate() {
        super.onCreate();
​
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("foreground", "前台Service", NotificationManager.IMPORTANCE_DEFAULT);
            manager.createNotificationChannel(channel);
        }
        
        Intent intent = new Intent(this, MainActivity.class);
        //这里也可以使用taskStackBuilder的方式获得pendingIntent
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        
        //使用compat可以兼容所有安卓版本,参数为(上下文,渠道id)
        Notification notification= new NotificationCompat.Builder(this,"foreground")
            .setContentTitle("通知标题")
            .setContentText("通知内容")
            .setSmallIcon(R.drawable.xxx)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.xxx))//将图片解析为Bitmap
            .setShowWhen(false)//是否显示时间
            .setNotificationSilent()//静默通知
            .setVisibility(NotificationCompat.VISIBILITY_SECRET)//锁屏不可见
            .setContentIntent(pending)//点击通知后跳转到的页面
            .build();//创建通知对象
​
        //注意启动通知的方式不是通过管理器发送通知,而是启动前台
        startForeground(1, notification);
    }

取消

  • 将前台服务降为后台服务,可以让它从任务栏消失

//此时服务并没有停止,直到调用stopService()
stopForeground(true);
  • 直接stopService(),无论Service在前/后台都会直接结束啦

IntentService

是Service的子类

Service本身是在主线程中运行,如果执行耗时操作需要自己手动开启子线程并且在运行结束后调用stopSelf或者stopService来停止,这样可行,但是自己去管理Service的生命周期和子线程并不是一个好的选择,因此android提供了IntentService来实现自动开启子线程并关闭

新建一个继承了IntentService的类

public class MyIntentService extends IntentService {
​
    public MyIntentService() {
        super("MyIntentService");
    }
​
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        //这个方法已经是在子线程中运行的了,可以处理一些耗时逻辑
    }
}

使用方法

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

既然是Service就要在Manifest文件里注册

<service
        android:name=".MyIntentService"
        android:enabled="true"
        android:exported="true" />

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作为AI语言模型,我只能提供一些Android开发的基础知识和常用概念,希望对您有所帮助。 1. Android组成部分 Android操作系统由四个主要组成部分组成:应用程序、应用程序框架、系统运行库和硬件抽象层。 2. Activity Activity是Android应用程序中的一个组件,用于表示应用程序中的一个屏幕。Activity可以包含用户界面元素,如文本框、按钮和图像。 3. Intent Intent是Android应用程序中的一个基本组件,用于在不同的组件之间传递数据。Intent可以用于启动Activity、启动服务、发送广播等。 4. 布局 布局是Android应用程序中用于定义用户界面的XML文件。布局文件定义了应用程序中的视图层次结构,包括文本框、按钮、图像等。 5. AndroidManifest.xml AndroidManifest.xml是Android应用程序中的一个必需文件,用于描述应用程序的基本信息。该文件包含应用程序的包名、应用程序的入口Activity、应用程序需要的权限等信息。 6. 生命周期 Android应用程序中的每个组件都有自己的生命周期,包括创建、启动、暂停和销毁。了解组件的生命周期可以帮助开发者更好地管理应用程序的资源。 7. 线程 Android应用程序中的线程用于执行长时间运行的操作,如下载文件或执行计算。但是,在主线程中执行长时间运行的操作会导致应用程序变得缓慢或停止响应,因此必须使用异步线程。 8. Service ServiceAndroid应用程序中的一种组件,用于在后台执行长时间运行的操作。与Activity不同,Service没有用户界面,可以在后台执行。 9. 广播 广播是Android应用程序中的一种机制,用于在不同组件之间传递消息。广播可以用于通知应用程序中的其他组件,例如当设备电池电量低时,应用程序可以发送广播通知其他组件。 10. 内存管理 内存管理是Android应用程序中的一个重要方面。Android应用程序必须管理内存以确保应用程序能够正常运行,并避免出现内存泄漏和内存溢出等问题。可以使用垃圾回收器、使用合适的数据结构、避免创建不必要的对象等方法来管理内存。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值