【Android】Service的基本使用

Service是Android中四大组件之一。 Service是Android中实现程序后台运⾏的解决方案,它⾮常适合执⾏那些不需要和⽤户交互⽽且还要求⻓期运⾏的任务。Service的运⾏不依赖于任何⽤户界⾯,即使程序被切换到后台,或者⽤户打开了另外⼀个应⽤程序,Service仍然能够保持正常运⾏。

不过需要注意的是,Service并不是运⾏在⼀个独⽴的进程当中的,⽽是依赖于创建Service时所在的应⽤程序进程。当某个应⽤程序进程被杀掉时,所有依赖于该进程的Service也会停⽌运⾏。另外,也不要被Service的后台概念所迷惑,实际上Service并不会⾃动开启线程,所有的代码都是默认运行在主线程当中的。也就是说,我们需要在Service的内部⼿动创建⼦线程,并在这⾥执⾏具体的任务,否则就有可能出现主线程被阻塞的情况。

下面来介绍一下Service的基本使用方法:

定义Service

java 复制代码
```java
public class Myservice extends Service {
    public Myservice() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

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

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

    @Override
    public void onDestory() {
    super.onDestory();
    }

}
scss 复制代码
可以看到我们重写了onCreate()\onStartCommand\onDestory()三个方法,是服务中最常用到的三个方法。其中onCreate()是在服务创建时调用,onStartCommand是在服务启动时调用,onDestory很显然是在服务销毁时调用。

Service是Android四大组件之一,自然也是需要在 AndroidManifest.xml中注册。

## 启动和停止服务

与Activity类似,也是通过Intent启动Service


```java
//假设在button的点击事件里
Intent startIntent = new Intent(this, MyService.class);
stratService(startIntent);

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

stratService、stopService方法都是在Context类中的,所以可以直接使用。其中停止服务在上面代码中是用户手动点击的,其实也可以在Service中使用stopSelf()来让服务停下来。

活动与服务通信

虽然上述的服务是在活动里开启或停止的,但是一旦启动了服务,似乎活动与服务就没关系了。启动之后,服务一直处于运行状态,但是具体运行的是什么逻辑,活动无法对其控制。

想实现活动与服务进行通信,就必须用到上面Service中的onBind()。比如我们想在MyService中提供一个下载功能,然后在活动中可以通知什么时候开始下载以及查看下载进度。思路是:创建一个Binder对象来对下载功能进行管理。

java 复制代码
public class Myservice extends Service {
    public Myservice() {
    }
    
    private DownloadBinder mBinder = new DownloadBinder();
    //内部类
    class DownloadBinder extends Binder {
        public void startDownload(){
        Log.d("Myservice", startDownload);
         }
    }
    
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
    
    ...
   
}

接下来就是要考虑如何在Activity中绑定Service

java 复制代码
//假设在某个按钮上的点击事件:
Intent bindIntent = new Intent(this, MyService.class);
bindService(bindIntent, connection, BIND_AUTO_CREATE);
break;

我们来看看bindService()这个Context类提供的方法,要求输入一个ServiceConnection接口的实例。 这里使用内部类:

java 复制代码
private MyService.DownloadBinder downloadBinder;
private ServiceConnection connection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponetName name, IBinder service) {
        downloadBinder = (MyService.DownloadBinder) service;
        //得到Service中返回的mBinder,就可以调用里面的函数。
        downloadBinder.startDownload();
        
    }
}

PS:至于为什么用到Binder这些,查阅了一些资料,涉及太多Framework方面的内容,目前还理解不了。等待自己慢慢成长,回来补全这篇!!

IntentService

我们从开篇就讲过,服务中的代码都是运行在主线程中的,如果直接去服务里执行耗时的逻辑,就可能出现ANR:Application not response.

所以这个时候就可以用到Android多线程编程的东西了,在服务里的方法开启一个子线程去执行逻辑就可以:

java 复制代码
public class Myservice extends Service {
    
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(new Runnable() {
        @Override
        public void run(){
        //具体的逻辑
        //stopSelf()
        }
        }).start();
    }  
    }
}

//但是如果服务一旦启动起来,就会一直运行,并且要手动打开线程、关闭服务等操作。

Android考虑到了这些,提供了一个IntentService类,封装好了,可以创建一个异步的、会自动停止的服务。

scala 复制代码
public class MyIntentService extends IntentService {
    public MyIntentService() {
        super("MyIntentService);
    }
    
    @Override
    proteced void onHandleIntent(Intent intent) {
    //可执行操作 是在子线程中的
    }
}

在Activity中,启动该服务和普通的服务一样。

相关推荐
长亭外的少年2 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿4 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神5 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛6 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee
Y多了个想法6 小时前
RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526
android·rk3568·触摸屏·tp·敦泰·focaltech·ft5526
NotesChapter7 小时前
Android吸顶效果,并有着ViewPager左右切换
android
_祝你今天愉快8 小时前
分析android :The binary version of its metadata is 1.8.0, expected version is 1.5.
android
暮志未晚Webgl9 小时前
109. UE5 GAS RPG 实现检查点的存档功能
android·java·ue5
麦田里的守望者江9 小时前
KMP 中的 expect 和 actual 声明
android·ios·kotlin
Dnelic-9 小时前
解决 Android 单元测试 No tests found for given includes:
android·junit·单元测试·问题记录·自学笔记