任务、进程和线程

Android-TaskScheduler一个简洁实用方便的Android异步处理库 一个简洁、实用、方便的Android异步处理库,已应用到百万日活的线上项目中 立即下载
关于Android中的组件和应用,之前涉及,大都是静态的概念。而当一个应用运行起来,就难免会需要关心进程、线程这样的概念。在Android中,组件的动态运行,有一个最与众不同的概念,就是Task,翻译成任务,应该还是比较顺理成章的。
Task的介入,最主要的作用,是将组件之间的连接,从进程概念的细节中剥离出来,可以以一种不同模型的东西进行配置,在很多时候,能够简化上层开发人员的理解难度,帮助大家更好的进行开发和配置。

任务

在SDK中关于 Task( guide/topics/fundamentals.html#acttask),有一个很好的比方,说,Task就相当于应用( application)的概念。在开发人员眼中,开发一个Android程序,是做一个个独门独户的组件,但对于一般用户而言,它们感知到的,只是一个运行起来的整体应用,这个整体背后,就是Task。
Task,简单的说,就是 一组以栈的模式聚集在一起的Activity组件集合。它们有潜在的前后驱关联,新加入的Activity组件,位于栈顶,并仅有在栈顶的Activity,才会有机会与用户进行交互。而当栈顶的Activity完成使命退出的时候,Task会将其退栈,并让下一个将跑到栈顶的Activity来于用户面对面,直至栈中再无更多Activity,Task结束。

事件Task栈(粗体为栈顶组件)
点开Email应用,进入收件箱(Activity A)A
选中一封邮件,点击查看详情(Activity B)AB
点击回复,开始写新邮件(Activity C)ABC
写了几行字,点击选择联系人,进入选择联系人界面(Activity D)ABCD
选择好了联系人,继续写邮件ABC
写好邮件,发送完成,回到原始邮件AB
点击返回,回到收件箱A
退出Email程序null

如上表所示,是一个实例。从用户从进入邮箱开始,到回复完成,退出应用整个过程的Task栈变化。这是一个标准的栈模式,对于大部分的状况,这样的Task模型,足以应付,但是,涉及到实际的性能、开销等问题,就会变得残酷许多。比如,启动一个浏览器,在Android中是一个比较沉重的过程,它需要做很多初始化的工作,并且会有不小的内存开销。但与此同时,用浏览器打开一些内容,又是一般应用都会有的一个需求。设想一下,如果同时有十个运行着的应用(就会对应着是多个Task),都需要启动浏览器,这将是一个多么残酷的场面,十个Task栈都堆积着很雷同的浏览器Activity,是多么华丽的一种浪费啊。于是你会有这样一种设想,浏览器Activity,可不可以作为一个单独的Task而存在,不管是来自那个Task的请求,浏览器的Task,都不会归并过去。这样,虽然浏览器Activity本身需要维系的状态更多了,但整体的开销将大大的减少,这种舍小家为大家的行为,还是很值得歌颂的。
如此值得歌颂的行为,Android当然会举双手支持的。在Android中,每一个Activity的Task模式,都是可以由 Activity提供方(通过配置文件...)和 Activity使用方(通过Intent中的flag信息...)进行配置和选择。当然,使用方对Activity的控制力,是限定在提供方允许的范畴内进行,提供方明令禁止的模式,使用方是不能够越界使用的。
在SDK中( guide/topics/fundamentals.html#acttask),将两者实现Task模式配置的方式,写的非常清晰了,我再很絮叨挑选一些来解释一下(完整可配置项,一定要看SDK,下面只是其中常用的若干项...)。提供方对组件的配置,是通过 配置文件(Manifest) <activity>项来进行的,而调用方,则是通过 Intent对象的flag进行抉择的。相对于标准的Task栈的模式,配置的主要方向有两个:一则是破坏已有栈的进出规则,或样式;另一则是开辟新Task栈完成本应在同一Task栈中完成的任务。
对于应用开发人员而言,<activity>中的 launchMode属性,是需要经常打交道的。它有四种模式:" standard", " singleTop", " singleTask", " singleInstance"。
standard模式, 是默认的也是标准的Task模式,在没有其他因素的影响下,使用此模式的Activity,会构造一个Activity的实例,加入到调用者的Task栈中去,对于使用频度一般开销一般什么都一般的Activity而言,standard模式无疑是最合适的,因为它逻辑简单条理清晰,所以是默认的选择。
而 singleTop模式,基本上于standard一致,仅在请求的Activity 正好位于栈顶时,有所区别。此时,配置成singleTop的Activity,不再会构造新的实例加入到Task栈中,而是将新来的Intent发送到栈顶Activity中,栈顶的Activity可以通过重载 onNewIntent来处理新的Intent(当然,也可以无视...)。这个模式,降低了位于栈顶时的一些重复开销,更避免了一些奇异的行为(想象一下,如果在栈顶连续几个都是同样的Activity,再一级级退出的时候,这是怎么样的用户体验...),很适合一些会有更新的列表Activity展示。一个活生生的实例是,在Android默认提供的应用中,浏览器(Browser)的书签Activity( BrowserBookmarkPage),就用的是singleTop。
singleTop模式,虽然破坏了原有栈的逻辑(复用了栈顶,而没有构造新元素进栈...),但并未开辟专属的Task。而singleTask,和singleInstance,则都采取的另辟Task的蹊径。 标志为singleTask的Activity,最多仅有一个实例存在,并且,位于 以它为根的Task中。所有对该Activity的请求,都会跳到该Activity的Task中展开进行。singleTask,很象概念中的单件模式,所有的修改都是基于一个实例,这通常用在构造成本很大,但切换成本较小的Activity中。在Android源码提供的应用中,该模式被广泛的采用,最典型的例子,还是浏览器应用的主Activity(名为Browser...),它是展示当前tab,当前页面内容的窗口。它的构造成本大,但页面的切换还是较快的,于singleTask相配,还是挺天作之合的。
相比之下, singleInstance显得更为极端一些。在大部分时候singleInstance与singleTask完全一致,唯一的不同在于,singleInstance的Activity,是它所在栈中 仅有的一个Activity,如果涉及到的其他Activity,都移交到其他Task中进行。这使得singleInstance的Activity,像一座孤岛,彻底的黑盒,它不关注请求来自何方,也不计较后续由谁执行。在Android默认的各个应用中,很少有这样的Activity,在我个人的工程实践中,曾尝试在 有道词典的 快速取词Activity中采用过,是因为我觉得快速取词入口足够方便(从notification中点选进入),并且会在各个场合使用,应该做得完全独立。
除了launchMode可以用来调配Task,<activity>的另一属性 taskAffinity,也是常常被使用。taskAffinity,是一种物以类聚的思想,它倾向于将taskAffinity属性相同的Activity,扔进同一个Task中。不过,它的约束力,较之launchMode而言,弱了许多。只有当<activity>中的 allowTaskReparen ting设置为true,抑或是调用方将Intent的flag添加 FLAG_ACTIVITY_NEW_TASK属性时才会生效。如果有机会用到Android的Notification机制就能够知道,每一个由notification进行触发的Activity,都必须是一个设成FLAG_ACTIVITY_NEW_TASK的Intent来调用。这时候,开发者很可能需要妥善配置taskAffinity属性,使得调用起来的Activity,能够找到组织,在同一taskAffinity的Task中进行运行。

进程

在大多数其他平台的开发中,每个开发人员对自己应用的进程模型都有非常清晰的了解。比如,一个控制台程序,你可以想见它从main函数开始启动一个进程,到main函数结束,进程执行完成退出;在UI程序中,往往是有一个消息循环在跑,当接受到Exit消息后,退出消息循环结束进程。在该程序运行过程中,启动了什么进程,和第三方进程进行通信等等操作,每个开发者都是心如明镜一本帐算得清清楚楚。进程边界,在这里,犹如国界一般,每一次穿越都会留下深深的印迹。
在Android程序中,开发人员可以直接感知的,往往是Task而已。倍感清晰的,是组件边界,而进程边界变得难以琢磨,甚至有了进程托管一说。Android中不但剥夺了手工锻造内存权力,连手工处置进程的权责,也毫不犹豫的独占了。
当然,Android隐藏进程细节,并不是刻意为之,而是自然而然水到渠成的。如果,我们把传统的应用称为 面向进程的开发,那么,在Android中,我们做得就是 面向组件的开发。从前面的内容可以知道,Android组件间的跳转和通信,都是在 第三方介入的前提下进行,正由于这种介入,使得两个组件一般不会直接发生联系(于Service的通信,是不需要第三方介入的,因此Android把它全部假设成为穿越进程边界,统一基于RPC来通信,这样,也是为了掩盖进程细节...),其中是否穿越进程边界也就变得不重要。因此,如果这时候,还需要开发者关注进程,就会变得很奇怪,很费解,干脆,Android将所有的进程一并托管去了,上层无须知道进程的生死和通信细节。
在Android的底层,进程构造了底部的一个 运行池,不仅仅是Task中的各个Activity组件,其他三大组件Service、Content Provider、Broadcast Receiver,都是 寄宿在底层某个进程中,进行运转。在这里,进程更像一个 资源池(概念形如线程池,上层要用的时候取一个出来就好,而不关注具体取了哪一个...),只是为了承载各个组件的运行,而各个组件直接的逻辑关系,它们并不关心。但我们可以想象,为了保证整体性,在默认情况下,Android肯定倾向于 将同一Task、同一应用的各个组件扔进同一个进程内,但是当然,出于效率考虑,Android也是允许开发者进行配置。
在Android中,整体的 <application>(将影响其中各个组件...)和底下各个组件,都可以设置 <process>属性,相同<process>属性的组件将扔到 同一个进程中运行。最常见的使用场景,是通过配置<application>的process属性,将不同的相关应用,塞进一个进程,使得它们可以同生共死。还有就是将经常和某个 Service组件进行通信的组件,放入同一个进程,因为与Service通信是个密集操作,走的是RPC,开销不小,通过配置,可以变成进程内的直接引用,消耗颇小。
除了通过<process>属性,不同的组件还有一些特殊的配置项,以 Content Provider为例(通过 <provider>项进行配置...)。<provider>项有一个 mutiprocess的属性,默认值为false,这意味着Content Provider,仅会在提供该组件的应用 所在进程构造一个实例,第三方想使用就需要经由RPC传输数据。这种模式,对于构造开销大,数据传输开销小的场合是非常适用的,并且可能提高缓存的效果。但是,如果是数据传输很大,抑或是希望在此提高传输的效率,就需要将mutiprocess设置成true,这样,Content Provider就会在每一个调用它的进程中构造一个实例, 避免进程通信的开销。
既然,是Android系统帮助开发人员托管了进程,那么就需要有一整套纷繁的算法去执行回收逻辑。Android中各个进程的生死,和运行在其中的各个组件有着密切的联系,进程们依照其上组件的特点,被排入一个 优先级体系,在需要回收时,从低优先级到高优先级回收。Android进程共分为五类优先级,分别是: Foreground Process,  Visible Process,  Service Process,  Background Process,  Empty Process。顾名思义不难看出,这说明, 越和用户操作紧密相连的,越是正与用户交互的,优先级越高,越难被回收。具体详情,参见: guide/topics/fundamentals.html#proclife。
有了优先级,还需要有良好的 回收时机。回收太早,缓存命中概率低可能引起不断的创造进程销毁进程,池的优势荡然无存;回收的太晚,整体开销大,系统运行效率降低,好端端的法拉利可能被糟蹋成一枚QQ老爷车。Android的进程回收,最重要的是考量 内存开销,以及电量等其他资源状况,此外每个进程承载的组件数量、单个应用开辟的进程数量等 数量指标,也是作为衡量的一个重要标识。另外,一些运行时的 时间开销,也被严格监控,启动慢的进程会很被强行kill掉。Android会 定时检查上述参数,也会在一些很 可能发生进程回收的时间点,比如某个组件执行完成后,来做回收的尝试。
从用户体验角度来看,Android的进程机制,会有很可喜的一面,有的程序启动速度很慢,但是在资源充沛的前提下,你反复的退出再使用,则启动变得极其快速(进程没死,只是从后台弄到了前台),这就是拜进程托管所赐的。当然,可喜的另一面就是可悲了,Android的托管算法,还时不时的展现其幼稚的一面,明明用户已经明显感觉到操作系统运行速度下降了,打开任务管理器一看,一票应用还生龙活虎的跳跃着,必须要手动帮助它们终结生命找到坟墓,这使得任务管理器基本成为Android的装机必备软件。
从开发角度上来看,Android这套进程机制,解放了开发者的手脚。开发人员不需要处心积虑的构造一个后台进程偷偷默默监听某个时间,并尝试用各种各样的守护手段,把自己的进程锻造的犹如不死鸟一辉一般,进程生死的问题,已经原理了普通开发人员需要管理的范畴内。但同时,于GC和人肉内存管理的争议一样,所有开发人员都不相信算法能比自己做得效率更高更出色。但我一直坚信一点, 所有效率的优势都会随着算法的不断改良硬件的不断提升而消失殆尽,只有开发模式的简洁不会随时间而有任何变化。

组件生命周期

任何架构上的变化,都会引起上层开发模式的变化,Android的进程模型,虽然使开发者不再需要密切关注进程的创建和销毁的时机,但仍然需要关注这些时间点对组件的影响。比如,你可能需要在进程销毁之前,将写到内存上的内容,持久化到硬盘上,这就需要关注进程退出前发生的一些事件。
在Android中,把握这些时间点,就必须了解 组件生命周期( Components Lifecycles)。所谓组件的生命在周期,就是在组件在前后台切换、被用户创建退出、被系统回收等等事件发生的时候,会有一些事件通知到对应组件上,开发人员可以选择性的处理这些事件在对应的时间点上来完成一些附加工作。
除Content Provider,其他组件都会有生命周期的概念,都需要依照这个模型定时定点处理一些状况,全部内容参见: guide/topics/fundamentals.html#lcycles。在这里,擒贼先擒王,还是拿Activity出来作楷模。



继续偷图,来自SDK。一个自然的Activity生命旅途,从 onCreate开始,到 onDestroy消亡。但月有阴晴圆缺组件有祸福旦夕,在系统需要的时候且组件位于后台时,所在的进程随时可能为国捐躯被回收,这就使得知道切入后台这个事情也变得很重要。
当组件进入栈顶,与用户开始交互,会调用 onResume函数,类似,当退出栈顶,会有 onPause函数被呼唤。onResume和onPause可以处理很多事情,最常规的,就是做一些文件或设置项的读写工作。因为,在该组件不再前台运行的时候,可能别的组件会需要读写同样一份文件和设置,如果不再onResume做刷新工作,用的可能就是一份脏数据了(当然,具体情况,还需要具体分析,如果文件不会被多头读写,可以放到onCreate里面去做读工作)。
除了前述切入后台会被其他组件骚扰的问题,另外,死无定因也是件很可怕的事情。在Android中,组件都有两种常见的死法,一种是 自然消亡,比如,栈元素ABC,变成AB了,C组件就自然消亡了。这种死发轻如鸿毛,不需要额外关心。但另一种情况,就是被 系统回收,那是死的重如泰山,为国捐躯嘛。
但这种捐躯的死法,对用户来说,比较费解。想象一下,一款游戏,不能存盘,你一直玩啊玩,三天三夜没合眼,这时候你mm打来电话鼓励一下,你精神抖擞的准备再接再厉,却发现你的游戏进程,在切入后台之后,被系统回收了,一夜回到解放前三天努力成为一场泡影,你会不会想杀做游戏的人,会不会会不会会不会,一定会嘛。这时候,如果没有Activity生命周期这码事,游戏程序员一定是被冤死的,成了Android的替罪羊。但是,Android的组件是有生命周期的,如果真的发生这样情况,不要犹豫,去杀开发的程序员吧。
为了逃生,程序员们有一块免死金牌,那就是Android的 state机制。所谓state,就是开发人员将一些当前运行的状态信息存放在一个 Bundle对象里面,这是一个 可序列化键值对集合。如果该Activity组件所处的进程需要回收,Android核心会将其上Activity组件的Bundle对象 持久化到磁盘上,当用户回到该Activity时候,系统会重新构造该组件,并将持久化到磁盘上的Bundle对象恢复。有了这样的持久化的状态信息,开发人员可以很好的区分具体死法,并有机会的使得死而复生的Activity恢复到死前状态。开发者应该做的,是通过 onSaveInstanceState函数把需要维系的状态信息(在默认的状态下,系统控件都会自己保存相关的状态信息,比如TextView,会保存当前的Text信息,这都不需要开发人员担心...),写入到Bundle对象,然后在 onRestoreInstanceState函数中读取并恢复相关信息( onCreate, onStart,也都可以处理...)。

线程

读取数据,后台处理,这些猥琐的伙计,自然少不了线程的参与。在Android核心的调度层面,是不屑于考量线程的,它关注的只有进程,每一个组件的构造和处理,都是在 进程的主线程上做的,这样可以保证逻辑的足够简单。多线程,往往都是开发人员需要做的。
Android的线程,也是通过派生Java的 Thread对象,实现 Run方法来实现的。但当用户需要跑一个具有消息循环的线程的时候,Android有更好的支持,来自于 Handler和 Looper。Handler做的是消息的传送和分发,派生其 handleMessage函数,可以处理各种收到的消息,和win开发无异。Looper的任务,则是构造循环,等候退出或其他消息的来临。在Looper的 SDK页面,有一个消息循环线程实现的标准范例,当然,更为标准的方式也许是构造一个 HandlerThread线程,将它的Looper传递给Handler。
在Android中, Content Provider的使用,往往和线程挂钩,谁让它和数据相关呢。在 前面提到过,Content Provider为了保持更多的灵活性,本身只提供了同步调用的接口,而由于异步对Content Provider进行增删改查是一个常做操作,Android通过 AsyncQueryHandler对象,提供了异步接口。这是一个Handler的子类,开发人员可以调用 startXXX方法发起操作,通过派生 onXXXComplete方法,等待执行完毕后的回调,从而完成整个异步调用的流程,十分的简约明了。

实现

整个任务、进程管理的核心实现,尽在 ActivityManagerService中。 上一篇说到,Intent解析,就是这个ActivityManagerService来负责的,其实,它是一个很名不副实的类,因为虽然名为Activity的Manager Service,但它管辖的范围,不只是Activity,还有其他三类组件,和它们所在的进程。
在ActivityManagerService中,有两类数据结构最为醒目,一个是 ArrayList,另一个是 HashMap。ActivityManagerService有大量的ArrayList,每一个组件,会有多个ArrayList来分状态存放。调度工作,往往就是从一个ArrayList里面拿出来,找个方法调一调,然后扔到另一个ArrayList里面去,当这个组件没对应的ArrayList放着的时候,说明它离死不远了。HashMap,是因为有组件是需要用名字或Intent信息做定位的,比如Content Provider,它的查找,都是依据Uri,有了HashMap,一切都顺理成章了。
ActivityManagerService用一些名曰 xxxRecord的数据结构,来表达各个存活的组件。于是就有了, HistoryRecord(保存Activity信息的,之所以叫History,是相对Task栈而言的...), ServiceRecord, BroadcastRecord, ContentProviderRecord, TaskRecord, ProcessRecord,等等。
值得注意的,是TaskRecord,我们一直再说,Task栈这样的概念,其实,真实的底层,并不会在TaskRecord中,维系一个Activity的栈。在ActivityManagerService中,各个任务的Activity,都以HistoryRecord的形式,集中存放在一个ArrayList中,每个HistoryRecord,会存放它所在TaskRecord的引用。当有一个Activity,执行完成,从概念上的Task栈中退出,Android是通过从当前HistoryRecord位置往前扫描同一个TaskRecord的HistoryRecord来完成的。这个设计,使得上层很多看上去逻辑很复杂的Task体系,在实现变得很统一而简明,值得称道。
ProcessRecord,是整个进程托管实现的核心,它存放有运行在这个进程上,所有组件的信息,根据这些信息,系统有一整套的算法来决议如何处置这个进程,如果对回收算法感兴趣,可以从ActivityManagerService的 trimApplications函数入手来看。
对于开发者来说,去了解这部分实现,主要是可以帮助理解整个进程和任务的概念,如果觉得这块理解的清晰了,就不用去碰ActivityManagerService这个庞然大物了。


ROSTEA软件下载及情感分析详细操作教程(附网盘链接) 原ROST虚拟团队出品的ROST系列文本内容挖掘分析平台,是辅助人文社会科学研究的免费计算平台。该软件可以实现文本预处理、分字、分词、词性识别、特殊名词抽取、词频统计、英文词频统计、情感计算、分类算法、聚类算法等一系列文本挖掘,是人文社科研究和论文写作的一把利器。该软件用户量超过一万人,遍布海内外100多所大学,包括剑桥大学、日本北海道大学、北京大学、清华大学、香港城市大学、澳门大学等众多高校。关于ROSTCM6的安装介绍可以参考之前的文章ROSTCM6软件下载及语义网络分析详细操作教程ROST EA。 阅读详情

相关推荐

手把手教你搭建《黑色沙漠》单机版:从下载到联机的完整指南(含GM工具使用)

本文提供《黑色沙漠》单机版从下载安装到GM工具使用及局域网联机的完整教程。详细解析不同版本选择、系统配置要求、常见问题解决,并分享GM工具高级命令和局域网联机设置技巧,帮助玩家轻松搭建个性化游戏环境。

weixin_28738165的博客 469

深入Android 【五】 —— 任务和进程

任务、进程和线程关于Android中的组件和应用,之前涉及,大都是静态的概念。而当一个应用运行起来,就难免会需要关心进程、线程这样的概念。在Android中,组件的动态运行,有一个最与众不同的概念,就是Task,翻译成任务,应该还是比较顺理成章的。Task的介入,最主要的作用,是将组件之间的连接,从进程概念的细节中剥离出来,可以以一种不同模型的东西进行配置,在很多时候,能够简化上层开发人员的理解难...

weixin_33832340的博客 250

KEIL MDK实战:如何用fromelf工具解析STM32的ELF文件结构(附完整命令行)

本文详细介绍了如何使用KEIL MDK中的fromelf工具解析STM32的ELF文件结构,包括内存段分析、符号表追踪和反汇编关键函数等实战技巧。通过完整的命令行示例,帮助嵌入式开发者优化内存占用、排查运行时问题,并提升STM32项目的开发效率。

weixin_42631411的博客 187

linux进程 android应用 区别,简单解释Android中的任务、进程和线程

一、任务要解释什么是Android中的任务,需要提到应用程序(application)和Activity。Activity:Android中最基本的应用程序组件。一个Activity通常就是一个单独的屏幕,用于呈现数据和与用户进行交互。应用程序:比如说qq软件就是一个应用程序,通常由多个Activity组成。有了上面两个概念,就可以很好理解任务了。一个Android任务通常会涵盖多个Activit...

weixin_39633102的博客 258

普冉(PUYA)单片机开发笔记 [完结篇]:使用体会

这一篇是 PY32F003 应用实验的完结篇,总结了对这颗 MCU 的使用体会。我已经把自己实验用的代码打包上传,供各位码神参考。

Tomcat0130 - 代码生涯 9606

别再为跨页读写发愁了!STM32F407模拟I2C驱动24C256/512的避坑指南

本文详细解析了STM32F407模拟I2C驱动24C256/512的跨页写入问题,揭示了24C系列存储器'写满一页不会自动翻页'的关键机制,并提供了经过验证的分页写入算法和优化方案。通过GPIO时序优化、地址计算和错误处理等技巧,帮助开发者解决数据错乱、覆盖等常见问题,实现稳定可靠的EEPROM读写操作。

weixin_42631411的博客 377

怎么构建Agent?我写了一个教程(含代码)

我们可以把不同的 LLM 或者 AI Agent 组合起来,让每个 Agent 都专注于它最擅长的领域。基准测试可以用来评估每个 Agent 在不同任务上的表现,使用已建立的数据集如 GLUE 和 FLASK,可以进行与不同最先进模型的标准化比较。AI Agent 则具备在不同互动之间保持上下文的能力,每个 Agent 可以参考前一个 Agent 的响应来完成它们预期的任务。另一方面,AI Agent 可以设计为由多个专门模型组成的团队,每个模型专注于一个特定任务,例如研究者、博客撰写者、社交媒体专家。

kiiy2的博客 2167

VS2022+Qt6保姆级配置指南:从插件安装到项目互通全流程(附常见错误解决)

本文提供了一份详细的Visual Studio 2022与Qt6集成开发环境配置指南。从插件安装、环境搭建到项目创建与互通,涵盖了全流程操作步骤,并针对常见的配置错误和调试问题提供了实用的解决方案,帮助开发者高效构建企业级桌面应用。

nginx7reverse的博客 1207

构建“任务规划”类 Agent 应用:多工具联动任务引擎设计实战

任务规划型 Agent 应用,是大模型落地最容易形成“闭环智能”的场景之一。相比普通 Chatbot,它不仅需要理解用户目标,更需要主动规划任务流程、选择合适工具、组织多阶段执行并管理状态上下文。构建这样的系统,需要解决三个核心挑战:如何定义任务流程?如何动态选择工具?如何协调多个 Agent 行为?本篇以“日报生成任务”为例,深入拆解多工具联动的 Task-Oriented Agent 架构设计,构建一个真正可执行、可组合、可追踪的任务执行系统,并提供完整的系统结构与关键代码示例,助你快速打造自己的任务型

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 1473

AI 辅助编程全景:演进、提效场景与未来趋势

本文系统梳理了AI辅助编程的发展历程与应用场景。演进路径分为三代:从代码补全工具(2023)、对话式助手(2024)到自主编程代理(2025)。在软件全生命周期中,AI可显著提升各环节效率:需求分析阶段节省30-60%文档编写时间;设计阶段缩短40-60%技术调研周期;编码阶段通过智能补全提升55%任务速度;测试阶段减少30-60%测试编写时间。数据显示,2025年84%开发者使用AI工具,41%代码由AI生成,平均每周节省3.6小时。AI正推动开发者角色从编写者转变为审核者,但复杂业务逻辑和架构设计仍需人

甘蓝的专栏 473

android 9.0Settings休眠时间项(屏幕超时)添加永不休眠功能

在9.0的系统产品开发中,系统中默认息屏时间为1分钟,可以通过在Setting中的息屏时间选项设置对应的息屏时间,但是在开发平板类的产品中,需要实现永不休眠的功能,所以需要在Settings中的息屏时间中添加永不休眠时间这一项来实现这个功能,接下来看息屏时间的相关功能,来添加这个功能

安卓兼职framework和app工程师的博客 2056

全面调研:19类AI Agent框架的对比与分析

单智能体= 大语言模型(LLM) + 观察(obs) + 思考(thought) + 行动(act) + 记忆(mem)多智能体=智能体 + 环境 + SOP + 评审 + 通信 + 成本多视角分析问题:虽然LLM可以扮演很多视角,但会随着system prompt或者前几轮的对话快速坍缩到某个具体的视角上;复杂问题拆解:每个子agent负责解决特定领域的问题,降低对记忆和prompt长度的要求;可操控性强:可以自主的选择需要的视角和人设;

m0_65555479的博客 1491

“华为杯”研究生数学建模竞赛2016年-【华为杯】A题:多无人机协同任务规划

题分别求解,保证了攻击方无人机滞留在防御方雷达有效探测范围内的时间总和最小,接着,通过提出巡检待命无人机的设想,型无人机携带炸弹的具体清单和攻击的目标清单),保证攻击方的无人机滞留防御方雷。在使用基于贪心算法的覆盖法时,覆盖的目标点中必须首先不含配备雷达站的目标点。步优化保证攻击方的无人机滞留防御方雷达有效探测范围内的时间总和最小,需首先。的“灵巧”炸弹,采用抛投方式对地攻击,即投放后炸弹以飞机投弹时的速度作抛物。运动,当炸弹接近目标后,可主动寻的攻击待打击的目标,因此炸弹落点位于目标中。

getusushu的博客 1037

一文搞懂 Linux 任务、进程和线程

一文搞懂 Linux 任务、进程和线程

安迪西_嵌入式攻城狮 2202

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

进程、线程、程序、任务和作业的联系

进程和线程关系 调度。在传统操作系统中,拥有资源和独立调度的基本单位都是进程,在引入线程的操作系统中,线程是独立调度的基本单位,进程是拥有资源的基本单位。这样一来,在同个进程内,线程之间的切换,不会引起进程之间的切换,因为进程每次切换都是有环境切换花销的。只有不同进程之间的线程切换,才会引起进程切换,2种方式平均下来减少环境切换,也就提高了系统并发度。 拥有资源。不论是传统操作系统还是引入线程的操作系统,进程都是拥有资源的基本单位,而线程不拥有系统资源(只有丁点),如果线程设置系统资源,那同一进程内的线程

Charming的博客 2503

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

02_多任务编程_Python进程和线程

多任务是指在同一时间内执行多个任务。例如: 现在电脑安装的操作系统都是多任务操作系统,可以同时运行着多个软件。① 线程是依附在进程里面的,没有进程就没有线程。② 一个进程默认提供一条线程,进程可以创建多个线程。

AGI爱好者_数仓&可视化&数据分析工程师_Vae’伯乐‘ 1314

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

线程、进程、多线程、多进程和多任务有啥关系?

点击上方“朱小厮的博客”,选择“设为星标” 后台回复"书",获取后台回复“k8s”,可领取k8s资料 可能学习操作系统开发的读者都听说过这些专业名词,但又多少人理解了?首先...

朱小厮的博客 1153

Linux线程(总结)线程、进程、多线程、多进程和多任务的关系详解

实现并发技术相当复杂,最容易理解的是“时间片轮转进程调度算法”,它的思想简单介绍如下:在操作系统的管理下,所有正在运行的进程轮流使用CPU,每个进程允许占用CPU的时间非常短(比如10毫秒),这样用户根本感觉不出来 CPU是在轮流为多个进程服务,就好像所有的进程都在不间断地运行一样。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程 所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。什么叫“多任务”呢。

Dola的博客 1701

Linux系统中 任务、进程和线程总结

任务、进程和线程基本概念 多任务处理是指用户可以在同一时间内运行多个应用程序,每个正在执行的应用程序被称为一个任务。Linux 就是一个支持多任务的操作系统(Windows也是多任务操作系统),比起单任务系统它的功能增强了许多。 多任务操作系统使用某种调度策略支持多个任务并发执行。事实上,(单核)处理器在某一时刻只能执行一个任务。每个任务创建时被分配时间片(几十到上百毫秒),任务执行(占用CP

zolalad的专栏 4013

多任务:进程和线程

一、多任务 定义: 多任务就是同一时刻多个任务同时执行。 实现多任务的原理: CPU在多个应用程序之间的高速切换。 二、进程 定义: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。 程序和进程 程序: 编写完毕的代码,在没有运行的时候,称之为程序。 ** 进程:** 正在运行着的代码,就成为进程。 对应关系:...

langdei的博客 278

操作系统中任务、进程和线程总结

多任务处理是指用户可以在同一时间内运行多个应用程序,每个正在执行的应用程序被称为一个任务。linux 就是一个支持多任务的操作系统(Windows也是多任务操作系统),比起单任务系统它的功能增强了许多。          多任务操作系统使用某种调度策略支持多个任务并发执行。事实上,(单核)处理器在某一时刻只能执行一个任务。每个任务创建时被分配时间片(几十到上百毫秒),任务执行(占用CPU)时

sunayxin的博客 4344

任务、程序、进程、线程的概念和联系

程序 程序只是一组指令的有序集合 任务 1、概念? 是最抽象的,是一个一般性的术语,指由软件完成的一个活动。一个任务既可以是一个进程,也可以是一个线程。简而言之,它指的是一系列共同达到某一目的的操作。例如,读取数据并将数据放入内存中。这个任务可以作为一个进程来实现,也可以作为一个线程(或作为一个中断任务)来实现。 2、什么是单任务? 一个程序执行完之后,才可以执行下一个任务 3、什么是多任务? 系...

ytt999的博客 1315

线程、进程、多线程、多进程 和 多任务 它们有啥关系

转自:stranger huang可能学习嵌入式开发的读者都听说过这些专业名词,但又多少人理解了?首先,从定义开始,先看一下教科书上进程和线程定义:进程:资源分配的最小单位。线程:程序执...

344

C#理解进程、线程和任务

关于 C# 中进程、线程和任务的概述,以及有关评估类型效率和监控性能和资源使用情况的详细内容

qq_42497776的博客 1296
上一篇: Android开发小技巧
下一篇: HttpUrlConnection详解
JoryShen
博客等级 码龄12年 1粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值