现代 WorkManager API 已发布

2023-12-20 16:20
文章标签 api 发布 现代 workmanager

本文主要是介绍现代 WorkManager API 已发布,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

5a2ecb0e01bef93de14acf81f73f4c17.jpeg

/   今日科技快讯   /

北京时间2022年6月27日23时46分,我国在酒泉卫星发射中心使用长征四号丙运载火箭,成功将高分十二号03星发射升空,卫星顺利进入预定轨道,发射任务获得圆满成功。该卫星主要用于国土普查、城市规划、土地确权、路网设计、农作物估产和防灾减灾等领域。

/   前言   /

随着设备性能提升和软件生态发展,越来越多的 Android 应用需要执行相对更复杂的网络、异步和离线等任务。例如用户想要离线观看某个视频,又不想一直停留在应用界面等待下载完成,那么就需要以一定的方式让这些离线的过程在后台运行。再比如您想将一段精彩的 Vlog 分享到社交媒体,肯定也会希望视频上传时不会影响到自己继续使用设备。这就涉及到了我们今天分享的主题: 使用 WorkManager 管理后台和前台工作。

如果您更喜欢通过视频了解此内容,请点击此处查看。

本文将着重探讨 WorkManager 的 API 以及用法,帮助您深入了解它的运行机制,以及在实际开发中的使用方式。近期也将会有另一篇关于在 Android Studio 中如何更好地使用 WorkManager 的文章,敬请关注。

/   WorkManager的基础API   /

从首个稳定版本发布以来,WorkManager 提供了一些基础 API,帮助您定义工作、放入队列、依次执行,且在工作完成时通知您的应用。以功能划分分类,这些基础 API 包括:

延迟执行

最初的版本中,这些工作只能被定义为延迟执行,也就是它们会在定义之后延期再开始执行。通过这种延期执行策略,一些不紧急或优先级不高的任务将会推后执行。

WorkManager 的延期执行会充分考虑设备的低电耗状态,以及应用的待机存储分区,因此您不必考虑工作需要在哪个具体时间被执行,这些都交给 WorkManager 考虑即可。

工作约束

WorkManager 支持对给定工作运行设定约束条件,约束 可确保将工作延迟到满足最佳条件时运行。例如,仅在设备采用不按流量计费的网络连接时、当设备处于空闲状态或者有足够的电量时运行。您可以专心开发应用的其他功能,将对工作条件的检查交给 WorkManager。

工作间的依赖关系

我们知道,工作之间是可能存在依赖关系的。比如您正在开发一个视频编辑应用,当剪辑完成后用户可能需要分享到社交媒体,于是您的应用需要依次渲染若干个视频片段,然后将它们一起上传到视频服务。这个过程是具有先后次序的,也就是上传工作依赖渲染工作的完成。

再举另外一个例子,当您的应用完成与后端同步数据后,也许您希望同步过程中产生的本地日志文件被及时清理,或者是将来自后端的新数据填充到本地数据库中。于是您可以请求 WorkManager 按照顺序或者并行执行这些工作,从而实现各个工作之间无缝衔接。而 WorkManager 会在确保所有给定条件都满足后再运行后续的 Worker。

多次执行的工作

很多具备与服务器同步功能的应用都具有这样的特点: 应用与后端服务器的同步往往不是一次性的,它可能是需要多次执行的。比如当您的应用提供在线编辑服务时,一定需要频繁将本地的编辑数据同步到云端,这就产生了定期执行的工作。

工作状态

由于您可以随时检查某个工作的状态,因此对于定期执行的工作而言,整个生命周期是透明的。您可以知道一个工作是处于队列等待、运行中、阻塞还是已完成状态。

/   WorkManager现代API   /

上述的基础 API 早在我们发布 WorkManager 的第一个稳定版时就已经提供了。首次在 Android 开发者峰会中谈到 WorkManager 时,我们把它看作是管理可延期后台工作的一个库。如今从底层的角度来看,这种观点仍然是成立的。但后来我们又添加了更多新功能,并让 API 更符合现代规范。

立即执行

现在,当您的应用处于前台时,您可以请求立即执行某项工作。随后即便应用被置于后台,这项工作也不会被中断,而是继续进行。所以,即使用户切换到别的应用去使用,您的应用仍然可以继续实现为照片添加滤镜、保存到本地、上传等一系列工作。

对于大型应用的开发商来说,他们需要在优化资源使用方面投入更多的资源和精力。但 WorkManager 可以凭借优秀的资源分配策略大大减轻他们的负担。

多进程 API

由于使用了新的多进程库处理工作,WorkManager 引入了新的 API,并进行了底层优化来帮助大型应用更有效地安排和执行工作。这得益于新的 WorkManager 可以在一个独立的进程中更高效地进行调度和处理。

强化的工作测试 API

应用发布到商店或是分发给用户之前,测试是非常重要的一个环节。因此我们增加了 API 来帮助您测试单独的 Worker 或是一组具备依赖关系的 Worker。

工具改进

在发布库的同时,我们还改进了众多开发者工具。作为开发者,您可以直接使用 Android Studio 来访问详尽的调试日志和检查信息。

/   开始使用 WorkManager   /

这些新引入的 API 和改进的工具在为开发者提供更大便利的同时,也促使我们重新思考使用 WorkManager 的最佳时机。虽然从技术角度,我们设计 WorkManager 的核心思想仍然是正确的,但对于日益复杂的开发生态而言,WorkManager 的能力已经大大超过我们的设计预期。

工作的 "持久化" 特性

WorkManager 可以处理您指派给它的任何类型的工作,因此它已经进化成了一个专门处理任务且值得信赖的好工具。WorkManager 在全局作用域中执行您定义的 Worker,这意味着只要您的应用还在运行,不论是设备方向的变化,还是 Activity 被回收等,您的工作会被一直留存。不过单凭这一点,还不能称之拥有 "持久化" 特性,因此 WorkManager 在底层还使用了 Room 数据库来保证当进程被结束或设备重启后,您的工作仍然可以执行,并有可能从中断位置继续执行。

执行需要长时间运行的工作

WorkManager 2.3 版本引入了对长时间运行的工作的支持。当我们谈到长时间运行的工作时,指的是运行时间超过 10 分钟执行窗口期的工作。通常情况下,一个 Worker 的执行窗口期被限定为 10 分钟。为了能实现长时间运行的工作,WorkManager 将 Worker 的生命周期与前台服务的生命周期捆绑在一起。JobScheduler 和进程内调度程序 (In-Process Scheduler) 仍然能感知到这种工作的存在。

由于前台服务掌握着工作执行的生命周期,而前台服务又需要向用户展示通知信息,所以我们向 WorkManager 添加了相关的 API。用户的注意力持续时间是有限的,所以 WorkManager 提供了 API 让用户能方便地通过通知停止长时间运行的工作。我们来分析一个长时间运行工作示例,代码如下:

class DownloadWorker(context: Context, parameters: WorkerParameters) : CoroutineWorker(context, parameters) {fun notification(progress: String): Notification = TODO()// notification 方法根据进度信息生成一条 Android 通知消息。suspend fun download(inputUrl: String,outputFile: String,callback: suspend (progress: String) -> Unit) = TODO()// 定义一个用于分块下载的方法fun createForegroundInfo(progress: String): ForegroundInfo {return ForegroundInfo(id, notification(progress))}override suspend fun doWork(): Result {download(inputUrl, outputFile) { progress -> val progress = "Progress $progress %"setForeground(createForegroundInfo(progress))} // 提供了一个 suspend 标记的 doWork 方法,其中调用下载方法,并显示最新进度信息。return Result.success() } //下载完成后,Worker 只需要返回成功即可
}

△ DownloadWorker 类

这里有一个 DownloadWorker 类,它扩展自 CoroutineWorker 类。我们会在这个类当中定义一些辅助方法来简化我们的工作。首先是一个 notification 方法,它可以根据所给定的进度信息生成一条 Android 通知消息。接下来我们要定义一个用于分块下载的方法,这个方法接受三个参数: 下载文件的 URL、文件保存的本地位置、suspend 回调函数。每当某个分块下载状态变化时,此回调就会被执行一次。于是,回调中携带的信息就可以被用来生成一条通知。

有了这些辅助方法,我们就可以将 WorkManager 执行长时间运行工作所需要的 ForegroundInfo 实例保存起来。ForegroundInfo 是由通知 ID 和通知实例组合构造而成的,请继续参照上述 CoroutineWorker 类的代码示例。

在这段代码里,我们提供了一个 suspend 标记的 doWork 方法,其中调用了刚才提到的分块下载辅助方法。由于每次回调发生时都会提供一些最新的进度信息,所以我们可以利用这些信息来构建通知,并调用 setForeground 方法来向用户显示这些通知。这里调用 setForeground 的操作正是导致 Worker 长时间运行的原因。下载完成后,Worker 只需要返回成功即可,随后 WorkManager 会将 Worker 的执行与前台服务解耦分离、清理通知消息,并在必要时结束相关的服务。因此我们的 Worker 本身并不需要执行服务管理工作。

终止已提交执行的工作

用户可能会突然改变主意,比如想要取消某个工作。某个前台运行服务的通知是无法简单滑动取消的,此前的做法是为这条通知消息添加一个动作,当用户点击时会向 WorkManager 发送一个信号,从而按照用户的意图终止某项工作。您也可以通过执行加急工作来终止,详见后文。

fun notification(progress: String): Notification {val intent = WorkManager.getInstance(context).createCancelPendingIntent(getId())return NotificationCompat.Builder(applicationContext, id).setContentTitle(title).setContentText(progress)// 其他一些操作.addAction(android.R.drawable.ic_delete, cancel, intent).build()
}

△ 派生自 CoroutineWorker 类的 DownloadWorker 类

首先需要创建一个待处理的 Intent,它可以很方便地取消某项工作。我们需要调用 getId 方法来获取这个工作创建时的工作请求 ID,然后调用 createCancelPendingIntent API 创建这个 Intent 实例。当此 Intent 被触发时,它会向 WorkManager 发送取消工作的信号,从而实现取消工作的目的。

接下来就要生成带有自定义动作的通知消息了。我们使用 NotificationCompat.Builder 设置通知的标题,然后添加一些文字说明。随后调用 addAction 方法将通知中的 "取消" 按钮与上一步创建的 Intent 关联起来。于是,当用户点击 "取消" 按钮时,这个 Intent 就会被发送到当前正在执行这个 Worker 的前台服务,从而将其终止。

执行加急工作

Android 12 中引入了新的前台服务限制,当应用在后台时是无法启动前台服务的。因此从 Android 12 开始,调用 setForegroundAsync 方法会抛出 Foreground Service Start Not Allowed Exception (不允许启动前台服务) 异常。这种情况下,WorkManager 就派上用场了。WorkManager 2.7 版本中增加了对加急工作 (expedited work) 的支持,所以接下来将会向您介绍如何使用 WorkManager 实现终止已提交执行的工作。

从用户的角度来说,加急工作是由用户发起的,因此对用户而言非常重要。甚至应用不在前台时,这些工作也需要被启动执行。比如聊天应用需要下载一条消息中的附件,或者应用需要处理付款订阅的流程。在早于 Android 12 的 API 版本中,加急工作都是由前台服务执行的,而从 Android 12 开始,它们将由加急作业 (expedited job) 实现。

系统以配额的形式限制了加急工作的数量。当应用处于前台时,加急工作不存在任何配额限制,但是当应用转到后台运行时,就必须遵从这些限制。配额的大小取决于应用的待机存储分区和进程重要性 (如优先级)。从字面意思来看,加急工作就是需要尽快启动执行的工作,这意味着此类工作对于延迟相当敏感,所以也就不支持设定初始延迟或是定期执行的设置。由于受到配额限制,加急工作也不可以取代长时间运行的工作。当您的用户想要发送一条重要信息时,WorkManager 会尽可能保证这条消息尽快发送。

class SendMessageWorker(context: Context, parameters: WorkerParameters): CoroutineWorker(context, parameters) {override suspend fun getForegroundInfo(): ForegroundInfo {TODO()}override suspend fun doWork(): Result {TODO()}
}

△ 加急工作示例代码

例如,一个同步聊天应用消息的案例使用了加急工作 API。SendMessageWorker 类扩展自 CoroutineWorker,而它的作用是负责从后台为聊天应用同步消息。加急工作需要在某个前台服务的上下文中运行,这很类似于 Android 12 之前版本中的长时间运行的工作。因此我们的 Worker 类还需要实现 getForegroundInfo 接口,方便生成和显示通知消息。但是在 Android 12 上 WorkManager 不会显示其他的通知,这是因为我们定义的 Worker 背后是由加急作业实现的。您需要像平常那样实现一个 suspend 标记的 doWork 方法。需要注意的是,当您的应用占用了全部的配额后,加急作业可能会被中断。因此我们的 Worker 最好能跟踪某些状态,以便在重新安排执行时间后能够恢复运行。

val request = OneTimeWorkRequestBuilder<ForegroundWorker>().setExpedited(OutOfQuotaPolicy.DROP_WORK_REQUEST).build()WorkManager.getInstance(context).enqueue(request)

△ setExpedited API 示例代码

您可以使用 setExpedited API 来安排加急工作,这个 API 会告诉 WorkManager,用户认为给定的工作请求非常重要。由于所能安排的工作存在配额限制,所以您需要表明当应用的配额用尽时该怎么处理,有两种备选方案: 其一是将加急请求变成常规工作请求,其二是在配额耗尽时放弃新的工作请求。

/   WorkManager多进程API   /

从 2.5 版本开始,WorkManager 对支持多进程的应用进行了若干项改进。如果您需要使用多进程 API,就需要定义 work-multiprocess 工件的依赖项,多进程 API 的目标是在辅助进程中对 WorkManager 的冗余部分或高开销部分进行大范围初始化操作。比如有多个进程在同时获取统一底层 SQLite 数据库的事务锁,这时就会发生 SQLite 争用;而这种争用正是我们想要通过多进程 API 减少的。另一方面,我们还想确保进程内调度程序在正确的进程中运行。

为了解 WorkManager 初始化时哪些部分是冗余的,我们需要清楚它会在后台执行哪些操作。

单进程的初始化

81d1f191f09e2d0d11e1e37b1925839f.png

△ 单进程的初始化过程

首先观察一下单进程初始化过程。应用启动后,第一件事是有平台调用 Application.onCreate 方法。随后在进程生命周期的某个时间点,WorkManager.getInstance 会被调用以启动 WorkManager 的初始化。当 WorkManager 初始化完毕后,我们运行 ForceStopRunnable。这个过程很重要,因为此时 WorkManager 会检查应用之前是否被强制停止过,它会比较 WorkManager 存储的信息与 JobScheduler 或 AlarmManager 中的信息,确保作业都被准确编入执行计划中。同时,我们也可以重新安排此前中断的某些工作,比如进程崩溃后进行的一些恢复工作。

大家都知道,这样做的开销非常高,我们需要在多个子系统中比较和协调状态,但是理想状态下,这种操作只应该被执行一次。另外需要注意,进程内调度程序只在默认进程中运行。

多进程的初始化

9cee6f0699f4334328b07eafe7156f5d.png

△ 多进程的初始化过程

接着我们再看看如果应用有第二个进程会发生什么。假如应用有第二个进程,基本上它会重复在第一个进程中完成的各项操作。首先第一个进程如上文那样初始化,并且由于这是主进程 (primary process),所以进程内调度程序 (In-Process Scheduler) 也会在其中运行。对于第二个进程,我们会重复刚才的过程,再次调用 Application.onCreate,然后重新初始化 WorkManager。这意味着,我们将重复在第一个进程中所做的所有工作。

根据前面的分析,您也许会感到疑惑,为什么还需要再次执行 ForceStopRunable 呢?这是由于 WorkManager 并不知道这些进程中哪一个优先级较高。如果应用是屏幕键盘或者微件 (Widget),那么主进程可能并不等同于默认进程。另外,辅助进程 (secondary processes) 中也没有运行进程内调度程序 (因为它不是默认进程)。其实进程内调度程序所在的进程选择非常重要,由于它不受其他持久性调度器的限制影响,所以调整其所在的进程可以显著提升数据吞吐量。例如,JobScheduler 的作业上限是 100 个,而进程内调度程序则没有这个限制。

val config = Configuration.Builder().setDefaultProcessName("com.example.app").build()

△ 指定应用的默认进程示例代码

通过 WorkManager 定义主进程

我们来看看如何定义指定的默认进程。首先根据自己的意愿设置默认进程的名称,这通常是应用的软件包名称,一旦定义了应用的默认进程,那么进程内调度程序就会在其中运行。但是辅助进程怎么办?有没有办法能够防止在其中再次初始化 WorkManager?事实证明这是可以办到的。其实我们真正需要的是完全不必初始化 WorkManager。

为了实现这个目标,我们引入了 RemoteWorkManager。这个类需要绑定到指定进程 (主进程),并使用绑定服务将次要进程的所有工作请求转发到这个指定的主进程。这样一来,您就可以完全避免所有刚才提到的跨进程 SQLite 争用,因为从开始到结束只有唯一一个进程在向底层 SQLite 数据库写入数据。您可以跟往常一样在辅助进程中创建工作请求,但是此处应该使用 RemoteWorkManager 而不是 WorkManager。使用 RemoteWorkManager 后,会通过绑定服务绑定到主进程中,并将所有工作请求进行转发,然后存储到特定队列等待执行。您可以通过将 RemoteWorkManager 服务合并到应用的 Android Manifest RXML 中实现这个绑定。

val request = OneTimeWorkRequestBuilder<DownloadWorker>().build()RemoteWorkManager.getInstance(context).enqueue(request)
△ 使用 RemoteWorkManager 示例代码
<!-- AndroidManifest.xml -->
<serviceandroid:name="androidx.work.multiprocess.RemoteWorkManagerService"android:exported="false" />

△ Manifest 注册服务示例代码

不同进程中运行 Worker

我们已经了解如何通过 WorkManager 定义主进程来避免争用,但有时候,您也希望能够在不同的进程中运行 Worker。举个例子,如果您在某应用的辅助进程中运行机器学习工作流 (ML Pipeline),而且该应用还有专门的界面进程,那么您可能需要在不同的进程中运行不同的 Worker。比如在辅助进程中隔离执行某个工作,这样一来即使这个进程内出现错误而崩溃也不会导致应用的其他部分瘫痪而整体退出,尤其是要保障界面进程正常工作。要实现在不同进程中执行 Worker,您需要扩展 RemoteCoroutineWorker 类。这个类与 CoroutineWorker 类似,扩展之后您需要自己实现 doRemoteWork 接口。

public class IndexingWorker(context: Context,parameters: WorkerParameters
): RemoteCoroutineWorker(context, parameters) {override suspend fun doRemoteWork(): Result {doSomething()return Result.success()}
}

△ IndexingWorker 类示例代码

由于这个方法是在辅助进程中执行的,我们仍然要定义 Worker 需要与哪个进程绑定。为此,我们还需要在 Android Manifest RXML 中添加一个条目。一个应用可以定义多项 RemoteWorker 服务,每项服务都在独立的进程中运行。

<!-- AndroidManifest.xml -->
<serviceandroid:name="androidx.work.multiprocess.RemoteWorkerService"android:exported="false"android:process=":background" />

△ Manifest 注册服务示例代码

这里您可以看到,我们为名为 background 的辅助进程添加了新服务。现在,您已经在 RXML 中定义好了服务,还需要进一步在工作请求中指明要绑定的组件名称。

val inputData = workDataOf(ARGUMENT_PACKAGE_NAME to context.packageName,ARGUMENT_CLASS_NAME to RemoteWorkerService::class.java.name
)val request = OneTimeWorkRequestBuilder<RemoteDownloadWorker>().setInputData(inputData).build()WorkManager.getInstance(context).enqueue(request)

△ 将 RemoteWork 对象放入队列示例代码

组件名称是软件包名和类名的组合,您需要将其添加到工作请求的输入数据中,然后用这个输入数据创建工作请求,这样一来 WorkManager 就知道要绑定哪项服务了。我们照常将工作放入队列中,当 WorkManager 准备执行这项工作时,它首先根据输入数据中定义的内容找到绑定的服务,并执行 doRemoteWork 方法。这样一来,所有复杂繁琐的跨进程通信的任务都交给 WorkManager 来处理了。

/   总结   /

WorkManager 是应对长执行时间工作的推荐方案,推荐您使用 WorkManager 实现请求和取消长时间运行的工作任务。通过本文了解到如何以及何时使用加急工作 API,如何编写可靠的高性能多进程应用。希望这篇文章对您有所帮助,下一篇文章将对新的后台任务检查器做出简单介绍,敬请关注!

推荐阅读:

我的新书,《第一行代码 第3版》已出版!

Android车机初体验

一个Android沉浸式状态栏上的黑科技

欢迎关注我的公众号

学习技术或投稿

81edc6454979ef1e8087aa020f4a72cb.png

c9bb59272ba9e531da16476157cfe574.jpeg

长按上图,识别图中二维码即可关注

这篇关于现代 WorkManager API 已发布的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/516662

相关文章

高效+灵活,万博智云全球发布AWS无代理跨云容灾方案!

摘要 近日,万博智云推出了基于AWS的无代理跨云容灾解决方案,并与拉丁美洲,中东,亚洲的合作伙伴面向全球开展了联合发布。这一方案以AWS应用环境为基础,将HyperBDR平台的高效、灵活和成本效益优势与无代理功能相结合,为全球企业带来实现了更便捷、经济的数据保护。 一、全球联合发布 9月2日,万博智云CEO Michael Wong在线上平台发布AWS无代理跨云容灾解决方案的阐述视频,介绍了

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大,但不同的语言在不同领域都有着自己的优势,为了强强联合,LabVIEW提供了强大的外部程序接口能力,包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等。通过DLL可以使用户很方便地调用C、C++、C#、VB等编程语言写的程序以及windows自带的大

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令 在日常的工作中由于各种原因,会出现这样一种情况,某些项目并没有打包至mvnrepository。如果采用原始直接打包放到lib目录的方式进行处理,便对项目的管理带来一些不必要的麻烦。例如版本升级后需要重新打包并,替换原有jar包等等一些额外的工作量和麻烦。为了避免这些不必要的麻烦,通常我们

如何更优雅地对接第三方API

如何更优雅地对接第三方API 本文所有示例完整代码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/third 我们在日常开发过程中,有不少场景会对接第三方的API,例如第三方账号登录,第三方服务等等。第三方服务会提供API或者SDK,我依稀记得早些年Maven还没那么广泛使用,通常要对接第三方

禅道Docker安装包发布

禅道Docker安装包发布 大家好, 禅道Docker安装包发布。 一、下载地址 禅道开源版:   /dl/zentao/docker/docker_zentao.zip  备用下载地址:https://download.csdn.net/download/u013490585/16271485 数据库用户名: root,默认密码: 123456。运行时,可以设置 MYSQL_ROOT_P

Java基础回顾系列-第五天-高级编程之API类库

Java基础回顾系列-第五天-高级编程之API类库 Java基础类库StringBufferStringBuilderStringCharSequence接口AutoCloseable接口RuntimeSystemCleaner对象克隆 数字操作类Math数学计算类Random随机数生成类BigInteger/BigDecimal大数字操作类 日期操作类DateSimpleDateForma

Restful API 原理以及实现

先说说API 再说啥是RESRFUL API之前,咱先说说啥是API吧。API大家应该都知道吧,简称接口嘛。随着现在移动互联网的火爆,手机软件,也就是APP几乎快爆棚了。几乎任何一个网站或者应用都会出一款iOS或者Android APP,相比网页版的体验,APP确实各方面性能要好很多。 那么现在问题来了。比如QQ空间网站,如果我想获取一个用户发的说说列表。 QQ空间网站里面需要这个功能。

京东物流查询|开发者调用API接口实现

快递聚合查询的优势 1、高效整合多种快递信息。2、实时动态更新。3、自动化管理流程。 聚合国内外1500家快递公司的物流信息查询服务,使用API接口查询京东物流的便捷步骤,首先选择专业的数据平台的快递API接口:物流快递查询API接口-单号查询API - 探数数据 以下示例是参考的示例代码: import requestsurl = "http://api.tanshuapi.com/a