Service和Thread的关系
不少Android初学者都可能会有这样的疑惑,Service和Thread到底有什么关系呢?什么时候应该用Service,什么时候又应该用Thread?答案可能会有点让你吃惊,因为Service和Thread之间没有任何关系!
之所以有不少人会把它们联系起来,主要就是因为Service的后台概念。Thread我们大家都知道,是用于开启一个子线程,在这里去执行一些耗时操作就不会阻塞主线程的运行。而Service我们最初理解的时候,总会觉得它是用来处理一些后台任务的,一些比较耗时的操作也可以放在这里运行,这就会让人产生混淆了。但是,如果我告诉你Service其实是运行在主线程里的,你还会觉得它和Thread有什么关系吗?让我们看一下这个残酷的事实吧。
在MainActivity的onCreate()方法里加入一行打印当前线程id的语句:
Log.d("MyService", "MainActivity thread id is " + Thread.currentThread().getId());
然后在MyService的onCreate()方法里也加入一行打印当前线程id的语句:
Log.d("MyService", "MyService thread id is " + Thread.currentThread().getId());
现在重新运行一下程序,并点击Start Service按钮,会看到如下打印日志:
可以看到,它们的线程id完全是一样的,由此证实了Service确实是运行在主线程里的,也就是说如果你在Service里编写了非常耗时的代码,程序必定会出现ANR的。
你可能会惊呼,这不是坑爹么!?那我要Service又有何用呢?其实大家不要把后台和子线程联系在一起就行了,这是两个完全不同的概念。Android的后台就是指,它的运行是完全不依赖UI的。即使Activity被销毁,或者程序被关闭,只要进程还在,Service就可以继续运行。比如说一些应用程序,始终需要与服务器之间始终保持着心跳连接,就可以使用Service来实现。你可能又会问,前面不是刚刚验证过Service是运行在主线程里的么?在这里一直执行着心跳连接,难道就不会阻塞主线程的运行吗?当然会,但是我们可以在Service中再创建一个子线程,然后在这里去处理耗时逻辑就没问题了。
额,既然在Service里也要创建一个子线程,那为什么不直接在Activity里创建呢?这是因为Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例。而且在一个Activity中创建的子线程,另一个Activity无法对其进行操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。因此,使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。
一个比较标准的Service就可以写成:
@Override public int onStartCommand(Intent intent, int flags, int startId) { new Thread(new Runnable() { @Override public void run() { // 开始执行后台任务 } }).start(); return super.onStartCommand(intent, flags, startId); } class MyBinder extends Binder { public void startDownload() { new Thread(new Runnable() { @Override public void run() { // 执行具体的下载任务 } }).start(); } }
相关推荐
在Android开发中,`Service`、`Thread`、`Toast`和`Handler`是四个非常重要的组件和概念,它们在创建高效、响应式的应用程序中起着关键作用。下面将详细阐述这些知识点及其相互关系。 首先,`Service`是Android中的...
- "Service和Thread的关系.png"可能是一张图解,清楚地展示了Service如何在不同线程中运行。 - "服务的生命周期.png"可能是Service生命周期各个阶段的可视化表示。 - "Serviced的种类.png"可能区分了标准Service...
接下来就为大家解释以下Service和Thread的区别。 首先要说明的是,进程是系统最小资源分配单位,而线程是则是最小的执行单位,线程需要的资源通过它所在的进程获取。 Service与Thread的区别: Thread:Thread 是程序...
Service与客户端组件(如Activity)的通信可以通过bindService()方法来实现,客户端可以得到一个ServiceConnection对象,从而与Service建立绑定关系,进行更直接的交互。 Service还提供了几种不同的启动类型,以...
此时,Visual Studio 会自动创建一个新的 Windows Service 项目,包括两个主要文件:`Program.cs` 和 `Service1.cs`。 ##### 2.2 编写服务代码 **2.2.1 `Program.cs` 文件** 该文件已经包含了服务的主入口点,...
**CPU QoS (Quality of Service)** 是一种资源管理机制,用于控制和优化虚拟机所占用的CPU资源。主要包括以下三个概念: - **预留**: 定义了分配给虚拟机的最小CPU资源量。 - **份额**: 决定了多个虚拟机在竞争CPU...
在Android开发中,短信(SMS)的发送、Handler、Runnable和Service是四个关键概念,它们在构建复杂的异步任务和后台处理中起着至关重要的作用。让我们深入探讨这些概念及其相互关系。 首先,Android SMS(短消息服务...
- OnExecute:服务主循环,通常用while循环和Sleep函数确保服务不会过度消耗CPU,同时使用ServiceThread.ProcessRequests处理服务请求。 - OnPause、OnShutdown、OnStart和OnStop:分别处理服务暂停、关闭、启动和...
通过Thread类和Runnable接口,开发者可以创建并管理多个执行线程,以实现高效的并发处理。 4. **异常处理**:在服务开发中,良好的错误处理机制至关重要。Java的try-catch-finally语句块和异常类层次结构使得异常...
在Android系统中,线程(Thread)和进程(Process)是理解应用程序运行机制的关键概念。它们决定了应用如何分配资源和执行任务,对于优化性能、提高用户体验具有重要意义。 **线程** 线程是程序中的执行流,是操作...
- View和ViewGroup:理解两者的关系,如何自定义View和实现复杂的布局。 - LayoutParams:在不同类型的布局中如何使用。 - RecyclerView和ListView:性能优化,如使用ViewHolder和DiffUtil。 3. **数据持久化**...
首先,SQLite是Android系统内置的关系型数据库,用于存储应用程序的数据。在断点下载中,SQLite的主要作用是记录每个线程的下载进度。每个下载任务会被拆分为多个线程,每个线程对应一个数据块,SQLite数据库会存储...
它内置了Gradle构建系统,便于管理项目的依赖关系和构建流程。 2. **安装与配置** 在开始开发之前,你需要下载并安装Android Studio,配置相应的SDK平台和工具。教程将指导你如何设置Android SDK路径,以及如何...
优点是能灵活控制消息队列,处理复杂任务,但需要管理和维护消息对象和线程关系,可能引入线程安全问题。 总的来说,AsyncTask适用于简单任务,而Handler适合更复杂的异步操作和长时间运行的任务。根据项目需求和...
"天气预报3_java+xml" 在这个项目中,我们可以看到以下几个重要的知识点: ...这个项目展示了 Android 中的一些基本概念和技术,例如 Service、SQLite、SharedPreferences、文件操作、Java 基础等。