导航:首页 > 操作系统 > androidservice子线程

androidservice子线程

发布时间:2023-02-07 00:21:54

1. android开发中不同的activity是否在同一个线程

2. android 主线程和子线程有什么区别

具体如下:
在一个Android 程序开始运行的时候,会单独启动一个Process。默认的情况下,所有这个程序中的Activity或者Service(Service和 Activity只是Android提供的Components中的两种,除此之外还有Content Provider和Broadcast Receiver)都会跑在这个Process。
一个Android 程序默认情况下也只有一个Process,但一个Process下却可以有许多个Thread。在这么多Thread当中,有一个Thread,我们称之为UI Thread。UI Thread在Android程序运行的时候就被创建,是一个Process当中的主线程Main Thread,主要是负责控制UI界面的显示、更新和控件交互。在Android程序创建之初,一个Process呈现的是单线程模型,所有的任务都在一个线程中运行。因此,我们认为,UI Thread所执行的每一个函数,所花费的时间都应该是越短越好。而其他比较费时的工作(访问网络,下载数据,查询数据库等),都应该交由子线程去执行,以免阻塞主线程。
那么,UI Thread如何和其他Thread一起工作呢?常用方法是:诞生一个主线程的Handler物件,当做Listener去让子线程能将讯息Push到主线程的Message Quene里,以便触发主线程的handlerMessage()函数,让主线程知道子线程的状态,并在主线程更新UI。
例如,在子线程的状态发生变化时,我们需要更新UI。如果在子线程中直接更新UI,通常会抛出下面的异常:
11-07 13:33:04.393: ERROR/JavaBinder(1029):android.view.ViewRoot$:Only the original thread that created a view hierarchy can touch its views.
意思是,无法在子线程中更新UI。为此,我们需要通过Handler物件,通知主线程Ui Thread来更新界面。

3. Android中service和子线程的用处比较

比如:程序的进程关了 service还在运行 但线程没有 。当你要做个在APP没运行的情况下 还能给你各种提示(消息推送什么的)就可以开个服务
网络下载图片什么的 就开个线程 因为耗时的程序段是不能阻塞到ui线程(主线程)的

4. android中的service和开启service的组件是否处于同一线程

需要说明Service也是运行在主线程的,如果Service有长时间操作,依然会阻塞主线程,造成响应超时被强制关闭。
另外,启动服务是可以在子线程启动的,也可以在主线程启动,但是不管怎么样,服务都是运行在主线程。
综上所述:如果启动service在主线程,则与服务处于同一个线程,如果服务启动在子线程,则服务不在同一线程。

5. Android开发,怎么在service中实现 oncreat方法创建子线程,onstart里实现子线程逻辑

创建线程后,在run, while(true){ xxx()} xxx(){ if(?)xxxx ?=false} ,onstart(){? = true}
这样能否行.. 要不然你就每次都重新创建线程发送socket..

6. Android 中的“子线程”解析

Android 中线程可分为 主线程 和 子线程 两类,其中主线程也就是 UI线程 ,它的主要这作用就是运行四大组件、处理界面交互。子线程则主要是处理耗时任务,也是我们要重点分析的。

首先 Java 中的各种线程在 Android 里是通用的,Android 特有的线程形态也是基于 Java 的实现的,所以有必要先简单的了解下 Java 中的线程,本文主要包括以下内容:

在 Java 中要创建子线程可以直接继承 Thread 类,重写 run() 方法:

或者实现 Runnable 接口,然后用Thread执行Runnable,这种方式比较常用:

简单的总结下:

Callable 和 Runnable 类似,都可以用来处理具体的耗时任务逻辑的,但是但具体的差别在哪里呢?看一个小例子:

定义 MyCallable 实现了 Callable 接口,和之前 Runnable 的 run() 方法对比下, call() 方法是有返回值的哦,泛型就是返回值的类型:

一般会通过线程池来执行 Callable (线程池相关内容后边会讲到),执行结果就是一个 Future 对象:

可以看到,通过线程池执行 MyCallable 对象返回了一个 Future 对象,取出执行结果。

Future 是一个接口,从其内部的方法可以看出它提供了取消任务(有坑!!!)、判断任务是否完成、获取任务结果的功能:

Future 接口有一个 FutureTask 实现类,同时 FutureTask 也实现了 Runnable 接口,并提供了两个构造函数:

用 FutureTask 一个参数的构造函数来改造下上边的例子:

FutureTask 内部有一个 done() 方法,代表 Callable 中的任务已经结束,可以用来获取执行结果:

所以 Future + Callable 的组合可以更方便的获取子线程任务的执行结果,更好的控制任务的执行,主要的用法先说这么多了,其实 AsyncTask 内部也是类似的实现!

注意, Future 并不能取消掉运行中的任务,这点在后边的 AsyncTask 解析中有提到。

Java 中线程池的具体的实现类是 ThreadPoolExecutor ,继承了 Executor 接口,这些线程池在 Android 中也是通用的。使用线程池的好处:

常用的构造函数如下:

一个常规线程池可以按照如下方式来实现:

执行任务:

基于 ThreadPoolExecutor ,系统扩展了几类具有新特性的线程池:

线程池可以通过 execute() 、 submit() 方法开始执行任务,主要差别从方法的声明就可以看出,由于 submit() 有返回值,可以方便得到任务的执行结果:

要关闭线程池可以使用如下方法:

IntentService 是 Android 中一种特殊的 Service,可用于执行后台耗时任务,任务结束时会自动停止,由于属于系统的四大组件之一,相比一般线程具有较高的优先级,不容易被杀死。用法和普通 Service 基本一致,只需要在 onHandleIntent() 中处理耗时任务即可:

至于 HandlerThread,它是 IntentService 内部实现的重要部分,细节内容会在 IntentService 源码中说到。

IntentService 首次创建被启动的时候其生命周期方法 onCreate() 会先被调用,所以我们从这个方法开始分析:

这里出现了 HandlerThread 和 ServiceHandler 两个类,先搞明白它们的作用,以便后续的分析。

首先看 HandlerThread 的核心实现:

首先它继承了 Thread 类,可以当做子线程来使用,并在 run() 方法中创建了一个消息循环系统、开启消息循环。

ServiceHandler 是 IntentService 的内部类,继承了 Handler,具体内容后续分析:

现在回过头来看 onCreate() 方法主要是一些初始化的操作, 首先创建了一个 thread 对象,并启动线程,然后用其内部的 Looper 对象 创建一个 mServiceHandler 对象,将子线程的 Looper 和 ServiceHandler 建立了绑定关系,这样就可以使用 mServiceHandler 将消息发送到子线程去处理了。

生命周期方法 onStartCommand() 方法会在 IntentService 每次被启动时调用,一般会这里处理启动 IntentService 传递 Intent 解析携带的数据:

又调用了 start() 方法:

就是用 mServiceHandler 发送了一条包含 startId 和 intent 的消息,消息的发送还是在主线程进行的,接下来消息的接收、处理就是在子线程进行的:

当接收到消息时,通过 onHandleIntent() 方法在子线程处理 intent 对象, onHandleIntent() 方法执行结束后,通过 stopSelf(msg.arg1) 等待所有消息处理完毕后终止服务。

为什么消息的处理是在子线程呢?这里涉及到 Handler 的内部消息机制,简单的说,因为 ServiceHandler 使用的 Looper 对象就是在 HandlerThread 这个子线程类里创建的,并通过 Looper.loop() 开启消息循环,不断从消息队列(单链表)中取出消息,并执行,截取 loop() 的部分源码:

dispatchMessage() 方法间接会调用 handleMessage() 方法,所以最终 onHandleIntent() 就在子线程中划线执行了,即 HandlerThread 的 run() 方法。

这就是 IntentService 实现的核心,通过 HandlerThread + Hanlder 把启动 IntentService 的 Intent 从主线程切换到子线程,实现让 Service 可以处理耗时任务的功能!

AsyncTask 是 Android 中轻量级的异步任务抽象类,它的内部主要由线程池以及 Handler 实现,在线程池中执行耗时任务并把结果通过 Handler 机制中转到主线程以实现UI操作。典型的用法如下:

从 Android3.0 开始,AsyncTask 默认是串行执行的:

如果需要并行执行可以这么做:

AsyncTask 的源码不多,还是比较容易理解的。根据上边的用法,可以从 execute() 方法开始我们的分析:

看到 @MainThread 注解了吗?所以 execute() 方法需要在主线程执行哦!

进而又调用了 executeOnExecutor() :

可以看到,当任务正在执行或者已经完成,如果又被执行会抛出异常!回调方法 onPreExecute() 最先被执行了。

传入的 sDefaultExecutor 参数,是一个自定义的串行线程池对象,所有任务在该线程池中排队执行:

可以看到 SerialExecutor 线程池仅用于任务的排队, THREAD_POOL_EXECUTOR 线程池才是用于执行真正的任务,就是我们线程池部分讲到的 ThreadPoolExecutor :

再回到 executeOnExecutor() 方法中,那么 exec.execute(mFuture) 就是触发线程池开始执行任务的操作了。

那 executeOnExecutor() 方法中的 mWorker 是什么? mFuture 是什么?答案在 AsyncTask 的构造函数中:

原来 mWorker 是一个 Callable 对象, mFuture 是一个 FutureTask 对象,继承了 Runnable 接口。所以 mWorker 的 call() 方法会在 mFuture 的 run() 方法中执行,所以 mWorker 的 call() 方法在线程池得到执行!

同时 doInBackground() 方法就在 call() 中方法,所以我们自定义的耗时任务逻辑得到执行,不就是我们第二部分讲的那一套吗!

doInBackground() 的返回值会传递给 postResult() 方法:

就是通过 Handler 将最终的耗时任务结果从子线程发送到主线程,具体的过程是这样的, getHandler() 得到的就是 AsyncTask 构造函数中初始化的 mHandler , mHander 又是通过 getMainHandler() 赋值的:

可以在看到 sHandler 是一个 InternalHandler 类对象:

所以 getHandler() 就是在得到在主线程创建的 InternalHandler 对象,所以
就可以完成耗时任务结果从子线程到主线程的切换,进而可以进行相关UI操作了。
当消息是 MESSAGE_POST_RESULT 时,代表任务执行完成, finish() 方法被调用:

如果任务没有被取消的话执行 onPostExecute() ,否则执行 onCancelled() 。

如果消息是 MESSAGE_POST_PROGRESS , onProgressUpdate() 方法被执行,根据之前的用法可以 onProgressUpdate() 的执行需要我们手动调用 publishProgress() 方法,就是通过 Handler 来发送进度数据:

进行中的任务如何取消呢?AsyncTask 提供了一个 cancel(boolean mayInterruptIfRunning) ,参数代表是否中断正在执行的线程任务,但是呢并不靠谱, cancel() 的方法注释中有这么一段:

大致意思就是调用 cancel() 方法后, onCancelled(Object) 回调方法会在 doInBackground() 之后被执行而 onPostExecute() 将不会被执行,同时你应该 doInBackground() 回调方法中通过 isCancelled() 来检查任务是否已取消,进而去终止任务的执行!

所以只能自己动手了:

AsyncTask 整体的实现流程就这些了,源码是最好的老师,自己跟着源码走一遍有些问题可能就豁然开朗了!

7. 既然android service是运行在主线程中的,那service还有什么用

你没有将android 组件和android C/S架构的概念理解清楚,不仅没有理解清楚,还把组件的概念,跟线程、进程混淆在一起了。 我将android比喻成一栋办公大楼,android 中进程就是一个办公室,线程就是办公室里面的员工,办公室是不能干活的,而真正干活的是这个办公室里面的员工。一个员工只能在一个办公室里面干活,而一个办公室可以有很多员工。 Android的老板希望它的公司能办理的井井有条,于是针对每一种职能专门设立管理部门,例如WMS,负责窗口管理的,例如MPS,负责多媒体播放的。 一个部门可以有一个或多个办公室,一个办公室也可以有多个部门。 而android的管理部门往往是不干什么实事的,就像我们的天朝的猿类,你推它一下,它才动一下。所以android需要一些干实事的部门,做对外客户的,这些部门我们统称为apk。Android中有好多这种部门,于是为了防止这些部门瞎干,又把部门分成Activity、Service、BrocastReceiver、ContentProvider四种子部门,这些子部门就是用来跟其它部门做沟通的,而所有的子部门运作时都会由大管家AMS来记录在案。 Activity,做门面的。 Service,做对外支持的。 BrocastReceiver,做门卫收信的。 ContentProvider,做仓库管理的。 做门面的,可以做对外支持的活,也可以做仓库管理的活。但是外面可不这么认为,它想找你要数据,只会找ContentProvier,找对外支持只会找Service。 另外AMS大管家有个不好的习惯,它为了节省公司的资源,AMS那里没有你这个apk任何部门运行记录的时候,它有可能把你的电关了(杀进程)。 而LZ你描述的问题呢,就是你的部门想下载东西,是由Activity子部门去干呢,还是Service去干。

8. Android中服务service

本文原文连接 https://blog.csdn.net/wen20102321/article/details/53155736

Service是Android中的四大组件之一,它的级别和Activity差不多。只不过Service没有页面显示,只能后台运行,可以和其他组件进行交互。
Service的后台运行并不是子线程,是在主线程中进行的,只是它没有界面显示。如果Service进行了耗时操作同样需要开启子线程,否则会跟Activity一样出现ANR问题(application not response–程序没有响应)。
补充说明:
主线程的内容包括UI和后台,只要程序中的UI或者后台其中一个在跑,程序都算是在运行状态。

1,创建一个自己的TestService继承Service
2,必须实现重写其中的onBind方法,可以在里边做各种操作,也可以接收传递过来的Intent的数据。
(在Android Studio中可以直接新建一个Service)

服务的注册是四大组件中最简单的一个,一般只要设置name属性就可以了。

1,startService()启动
(1)启动服务startService:onCerate(),onStart()
(2)停止服务stopService:onDestroy()
此方法启动服务,服务如果未被创建,系统会先调用onCreate()方法,接着调用onStrat()方法。如果调用startService前服务已经被启动,多次调用启动方法,不会多次调用onCreate,但会导致多次调用onStrat。
2,bindService()启动
(1)绑定bindService:onCreate(),onBind()
(2)解除绑定unbindService:onUnbind()
(3)正常停止程序服务的方法是先接触绑定unbindService,在停止服务stopService
绑定后调用stopService方法,这时候是不能停止服务的,如果这时再调用解绑unbindService,程序会先解绑,后停止服务。
用此方法启动服务,在服务未被创建时,会先调用onCreate(),接着调用onBind()方法,这时候调用者和服务绑定在一起,调用者退出,系统会先调用服务的onUnbind(),然后onDestroy()。如果调用bindService之前服务已经被绑定,多次调用bindService并不会导致onCreate()和onBind()方法被多次调用。如果调用者想与正在绑定的服务解除绑定,可以调用unbindService()。

(1),onCerate()服务第一次被创建
(2),onStartComand()服务开始工作
(3),onBind()服务已经绑定
(4),onUnBind()服务解绑
(5),onDestroy()服务已经停止

普通的Service进行耗时操作要创建一个线程去完成,因为service是在主线程运行的,并且这个子线程完成工作要手动停止 。IntentService是继承了Service并处理起步请求的一个类,在IntentService内有一个工作线程,来处理耗时操作,启动IntentService的方式和启动传统的Service是一样,当任务执行完成后,IntentService会自动停止,而不需要我们去控制。
可以启动多次IntentService,每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推,而且,所有请求都在一个单线程中,不会阻塞主线程,同一时间只处理一个请求。
IntentService优点
1,省去了在Service中开线程的麻烦
2,当操作完成时,不用手动停止Service。IntentService是Service,但是比Service更智能。

9. android service是运行在主线程吗

是的,所以如果你要做网络请求的话,即使在服务里也用在子线程里操作
否则会卡主界面

10. Android中进程与线程及如何在子线程中操作U

一个Android 程序默认情况只有一个进程,但是一个进程可以有多个线程。其中有一个UI 线程也称为UI主线程,UI Thread在Android程序运行的时候就被创建,主要是负责控制UI界面的显示、更新和控件交互。所有的Android应用程序组件----包括Activity、Service、Broadcast Receiver都在应用程序的主线程中运行。因此,任何组件中的费时操作处理都可能阻塞所有其他的组件、包括Service和可见的Activity。
在Android 中,对未响应的定义是:Activity对一个输入事件在5s内没有响应,或者Broadcast Receiver在10s内没有完成他的onReceive处理程序。对于任何不用直接和用户界面进行交互的重要处理,使用后台线程技术处理是非常重要的,将文件操作、网络交互、数据库、复杂计算调度到后台线程中完成非常重要,以免阻塞主线程。
方法一:Thread+Handler
开启一个新线程:new Thread(new MyThread()).start();

//通过Handler物件,通知主线程UI Thread来更新界面
Handler myHandler=new Handler(){
//此方法主要用于更新UI
public void handleMessage(Message msg){
switch(msg.what){
//根据Thread返回的标识进行相应的处理
}
}
};

class MyThread implements Runnable{
public void run(){
int what=0;
//将耗时操作放到这里处理

//to-do

阅读全文

与androidservice子线程相关的资料

热点内容
登录器一般存在哪个文件夹 浏览:533
中兴光猫机器码算法 浏览:330
android响应时间测试 浏览:940
java编程思想第四版答案 浏览:888
如何对nbt编程 浏览:885
mscpdf 浏览:948
文件夹d盘突然0字节可用 浏览:272
吃火腿肠的解压场面 浏览:339
卫星锅加密教程 浏览:792
php7的特性是什么 浏览:469
编译类高级语言源代码运行过程 浏览:177
科普中国app怎么分享 浏览:87
51单片机与32单片机比较 浏览:422
SQL加密存储解密 浏览:507
电气工程师把程序加密 浏览:797
解压切东西动画版 浏览:965
点到椭圆的距离算法 浏览:388
新的编译系统 浏览:533
cad替换样板命令 浏览:363
des算法例子 浏览:390