Android四大组件 之 Service

通过android:process指定的远程服务是运行在一个独立的进程里,比如说接入消息推送之类的,需要建立长连接。

默认是本地服务(与创建服务的在同一个进程中)

  • 服务适用于不需要和用户交互,又需要长期运行的任务。

  • 服务的运行不依赖于任何用户界面,即使程序切换到了后台,服务仍能正常运行。

  • 服务并不是运行在一个独立的进程中,而是依赖创建服务时所在的应用程序进程(默认运行在主线程中)。

  • 服务并不会自动创建线程,需要手动开启线程,才能执行耗时操作。

  • 每个服务只会存在一个实例,无论多次startService还是bindService获取到的实例

  • 服务启动了就会一直处于运行状态,除非执行stopService或者stopSelf (调用unbind不会停止service)

  • 需要在AndroidManifest中声明

既然服务和线程没有任何关系,而且服务工作在主线程中,不能执行耗时操作(无论是按键超时、服务超时、广播超时都会造成ANR);那服务有啥用呢?让服务执行耗时操作需要手动开启线程,线程不也可以长时间运行么?

官方解释:

A service is simply a component that can run in the background, even when the user is not interacting with your application, so you should create a service only if that is what you need.
If you must perform work outside of your main thread, but only while the user is interacting with your application, you should instead create a new thread.

If you create a Thread or an Executor in an Activity of your app, this leads to unpredictable results, since a simple screen orientation change will disrupt things, since the Activity will no longer be around when the Thread completes its task.You could use AsyncTask to handle this, but what if your app needs this Background Thread to be started from not just an Activity, but a notification or another component?

In these cases, Android Services are the right Android component to use to match up the Thread’s lifecycle with that of the Service’s lifecycle.

1、Thread 的运行是独立于Activity的,也就是说当一个Activity被finish之后,如果你没有主动停止Thread或者Thread里的run方法没有执行完毕的话,Thread 也会一直执行。在线程执行完毕,我们可以手动stopself让service结束,避免浪费资源。

2、当Activity被finish之后,不再持有该Thread的引用,也就不能在不同的Activity中对同一Thread进行控制。而我们可以在任何有Context的地方调用Context.startService、Context.stopService、Context.bindService,Context.unbindService 来操作service。

Android多线程编程

Android的单线程模型

1.不能阻塞UI线程。 所有耗时操作(网络、数据库、大文件等)都应该放在子线程中操作

2.不能在UI线程之外访问Android UI 。因为更新UI的方法不是线程安全的(更新时会进行线程检查)

所以一般在子线程中执行耗时操作,再回到主线程( UI线程 )更新UI。(一般通过Handler进行操作)

Handle模型

Handle/Message/MessageQueue/Looper 实现线程间交互

1、每个线程都只有一个MessageQueue,一个Looper

2、handle.sendMessage()会将message放入当前线程的Messagequeue中,等待执行

3、looper.loop()遍历MessageQueue中的每个message,执行msg.target.handleMessage(),回调handler的handleMessage()

详情请见:

服务的生命周期

  • onCreate() 服务创建的时候调用(只调用一次)

  • onStartCommand() 服务每次启动的时候调用(虽然每次startService都会调用一次,但每个服务都只会存在一个实例)

  • onDestroy() 服务销毁时调用(如果startService & bindService,则要调用stopService & unbindService,才回调onDestroy)

执行1-2 日志:onCreate -> onStartCommand -> onDestroy

执行1-1-2 日志:onCreate -> onStartCommand -> onStartCommand -> onDestroy (onStartCommand会执行多次)

执行3-4 日志:onCreate -> onBind -> onServiceConnected -> onDestroy (直接bindService创建的服务不会执行onStartCommand)

执行1-3-4-2 日志:onCreate -> onStartCommand -> onBind -> onServiceConnected -> onDestroy (既执行了startService,又执行了bindService)

执行4 日志:service not Registed exception (没有bind,不能执行unbind)

执行1-4 日志:service not Registed exception

执行1-3-4-4 日志:onCreate -> onStartCommand -> onBind -> onServiceConnected -> service not Registed exception (已经unbind之后,未bind,也不能unbind)

在activity中执行3,退出activity,报错has leaked ServiceConnection,会执行onDestroy

在activity中执行1,退出activity,不报错,不会执行onDestroy,服务启动了就会一直处于运行状态,除非执行stopService 或者 stopSelf

当activity 和 service 绑定之后,就可以调用该服务中 binder 提供的方法了

  1. startService
val intent = Intent(this, MyService::class.java)
startService(intent)
  1. stopService
val intent = Intent(this, MyService::class.java)
stopService(intent)
  1. bindService
val intent = Intent(this, MyService::class.java)
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)

4.unbindService

unbindService(serviceConnection)

服务的使用

通过startService 和stopService只是启动和结束服务,但是activity和service并没有建立关联,activity并不能定点让service干什么工作。

由bindService来建立 activity 和 service 之间的联系,onBind返回的IBinder类向上转型,为service中定义的Binder类,得到了Binder实例,就可以调用Binder中定义的方法。

var downloadBinder: MyService.DownLoadBinder? = null

val serviceConnection = object  : ServiceConnection{
    override fun onServiceDisconnected(name: ComponentName?) {
        LogUtils.e(" onServiceDisconnected invoke!!!")
    }

    override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
        LogUtils.e(" onServiceConnected invoke!!!")
        downloadBinder = service as MyService.DownLoadBinder? //向上转型
        downloadBinder?.startDownLoad() //调用bind的方法
        downloadBinder?.getProgress()
    }
}

MyService.java

public class MyService extends Service {

    private DownLoadBinder mBinder = new DownLoadBinder();

    public static class DownLoadBinder extends Binder {

        public void startDownLoad() {
            Log.e("zhen", "startDownLoad");
        }

        public void getProgress() {
            Log.e("zhen", "getProgress");
        }

    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("zhen", "onCreate");
    }

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

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

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

AndroidManifest中注册

android:exported=“true” 表示允许除当前程序之外的其它程序访问这个服务,默认为true

android:enabled=“true” 表示启动这个服务,默认为true

<service android:name=".module.service.MyService"
    android:exported="true"
    android:enabled="true"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值