使用 WorkManager 实现定期通知

Android WorkManager入门(一) 在当今快节奏的生活中,移动设备已经成为我们日常工作和生活不可或缺的一部分。然而,随着应用程序的复杂性不断增加,开发人员面临着一个重要的挑战:如何在后台执行任务,而不会影响用户的体验和设备的性能?在过去,开发人员通常使用传统的后台服务或定时任务来解决这个问题。然而,这些方法往往很复杂,需要大量的代码和资源,并且很难管理和调度任务。幸运的是,谷歌最近推出了一个新的解决方案:安卓WorkManager。安卓WorkManager是一个灵活、强大的后台任务调度库,旨在帮助开发人员轻松管理和执行后台任务。 阅读详情

今天早上我有一些空闲时间,所以我决定为我的应用程序Transactions解决一个问题。问题是添加一个循环通知功能,提醒应用程序的用户记录他们当天的交易。

所以,我做了一些研究,并决定使用以下两种方法之一:

1. Firebase 云消息传递(简单的方法)

Firebase Cloud Messaging 是一项服务,可让您向 Android、iOS 或 Web 应用程序发送通知或数据负载。发送后台通知(仅当您的应用程序在后台时才有效)相当容易。您可以admin-sdk在 Firebase 控制台中使用 firebase 或通知编写器向目标令牌、客户端设备订阅的主题或所有用户发送带有可选负载(图像或键值对)的通知整个应用程序。当应用程序在后台时,通知会出现在系统托盘中,点击它会启动应用程序。设置定期通知也非常简单,您只需更改频率即可。

对于Transactions,我只是将 SDK 依赖项添加到我的build.gradle文件中,运行应用程序,退出应用程序(这样它就在后台,前台通知的工作方式非常不同),然后使用通知编写器发送测试通知。一旦成功,我就设置了每天晚上 10 点的定期通知。


FCM 还允许您随时随地修改通知,这是一个额外的优势。但是,我想要更多的功能:

  • 用户应该能够将默认的提醒时间晚上 10 点更改为他们喜欢的时间
  • 如果愿意,用户应该能够选择退出此功能。

虽然第二个功能可以通过让应用注册或注销daily-reminderFCM 中的主题来实现,但第一个功能需要云功能或合适的后端,我希望将此实现保留在设备上。所以,我转向了第二个选项。

2. 带有定期工作请求的 WorkManager

我之前参加过一个codelab ,它教授了如何使用WorkManager设置通知。尽管它专注于即时的一次性请求,但我知道它WorkManager具有可以以固定间隔重复执行的延迟、定期工作请求的功能。我可以为此添加一些初始延迟以获得我想要的行为。

我首先设置了一个NotificationHelperKotlin 单例对象,其目的是创建通知通道(在 Android 8+ 上需要)、在PendingIntent点击通知时启动应用程序以及通知本身。

通知处理程序

object NotificationHandler {
    private const val CHANNEL_ID = "transactions_reminder_channel"

    fun createReminderNotification(context: Context) {
        //  No back-stack when launched
        val intent = Intent(context, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        }
        val pendingIntent = PendingIntent.getActivity(context, 0, intent,
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_IMMUTABLE
            else PendingIntent.FLAG_UPDATE_CURRENT)

        createNotificationChannel(context) // This won't create a new channel everytime, safe to call

        val builder = NotificationCompat.Builder(context, CHANNEL_ID)
            .setSmallIcon(R.mipmap.ic_launcher_round)
            .setContentTitle("Remember to add your transactions!")
            .setContentText("Logging your transactions daily can help you manage your finances better.")
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setContentIntent(pendingIntent) // For launching the MainActivity
            .setAutoCancel(true) // Remove notification when tapped
            .setVisibility(VISIBILITY_PUBLIC) // Show on lock screen

        with(NotificationManagerCompat.from(context)) {
            notify(1, builder.build())
        }
    }

    /**
     * Required on Android O+
     */
    private fun createNotificationChannel(context: Context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = "Daily Reminders"
            val descriptionText = "This channel sends daily reminders to add your transactions"
            val importance = NotificationManager.IMPORTANCE_HIGH
            val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
                description = descriptionText
            }
            // Register the channel with the system
            val notificationManager: NotificationManager =
                context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }
}

我计划createReminderNotification从调用该方法Worker时开始调用该方法。所以,我开始为WorkManager. 在我们查看代码之前WorkManager,根据 AndroidX 团队的说法,这就是:

WorkManager是持久工作的推荐解决方案。当通过应用程序重新启动和系统重新启动保持计划时,工作是持久的。因为大多数后台处理最好通过持久工作来完成,所以WorkManager 是推荐用于后台处理的主要 API。

WorkManager 抽象出 Android 拥有的无数后台处理 API,包括 FirebaseJobDispatcher、GcmNetworkManager 和 Job Scheduler。它提供一个单一的表面,然后根据上下文和 API 级别将工作委托给这些 API。这些是支持的Work请求类型WorkManager:


它的功能无法在一篇文章中描述,所以我希望代码和注释能够传达正在发生的事情的含义。首先WorkManager,我们将此依赖项添加到我们的build.gradle(针对 Kotlin):

implementation "androidx.work:work-runtime-ktx:2.7.1"

提醒通知工作者

这些是以固定间隔运行的请求TimeUnit,例如天、小时、分钟等。这里要注意的重要一点是,WorkManager它不能保证 aWork将在设定的时间执行。由于电池优化等原因,它可能会延迟,但它确实保证Work迟早会执行。我从扩展Worker类开始创建一个新Worker的,其doWork()方法WorkManager在它被触发时执行。

class ReminderNotificationWorker(private val appContext: Context, workerParameters: WorkerParameters) : Worker(appContext, workerParameters) {
    override fun doWork(): Result {
        NotificationHandler.createReminderNotification(appContext)
        return Result.success()
    }
}

每当ReminderNotificationWorker执行时,它都会创建一个新的提醒通知。我在这里没有包含任何错误处理,我计划稍后添加。

之后,我定义了一个静态的,或者 Kotlin 喜欢称之为的companion object方法,被称为schedule,它接受一个Context,以及每天应该生成通知的时间。此方法还处理某些情况,例如当用户选择的时间早于当前时间时,它将第一次触发延迟到第二天。这听起来很容易,但手动实现却出奇地复杂,Calendar最后我求助于课堂。

companion object {

        /**
         * @param hourOfDay the hour at which daily reminder notification should appear [0-23]
         * @param minute the minute at which daily reminder notification should appear [0-59]
         */
        fun schedule(appContext: Context, hourOfDay: Int, minute: Int) {
            log("Reminder scheduling request received for $hourOfDay:$minute")
            val now = Calendar.getInstance()
            val target = Calendar.getInstance().apply {
                set(Calendar.HOUR_OF_DAY, hourOfDay)
                set(Calendar.MINUTE, minute)
            }

            if (target.before(now)) {
                target.add(Calendar.DAY_OF_YEAR, 1)
            }

            log("Scheduling reminder notification for ${target.timeInMillis - System.currentTimeMillis()} ms from now")

            val notificationRequest = PeriodicWorkRequestBuilder<ReminderNotificationWorker>(24, TimeUnit.HOURS)
                .addTag(TAG_REMINDER_WORKER)
                .setInitialDelay(target.timeInMillis - System.currentTimeMillis(), TimeUnit.MILLISECONDS).build()
            WorkManager.getInstance(appContext)
                .enqueueUniquePeriodicWork(
                "reminder_notification_work",
                ExistingPeriodicWorkPolicy.REPLACE,
                notificationRequest
            )
        }
    }

我们UniquePeriodicWork用来确保我们只存在一个实例,ReminderNotificationWorker因为我不想用不正确的通知来惹恼用户。Work如果用户选择退出,该标签稍后用于识别和取消所有请求。我意识到此时我需要处理用户偏好,因此我编写了一个SharedPreferences帮助类来帮助我们与SharedPreferencesAndroid 提供的键值存储进行交互。

偏好商店

class PreferenceStore(context: Context) {
    private val sharedPref: SharedPreferences = context.getSharedPreferences("transactions_shared_pref", Context.MODE_PRIVATE)

    /**
     * @return the hour of the day in which the reminder should be shown, default is 22, if canceled -1
     * @return the minute at which the reminder should be shown, default is 0, if canceled -1
     */
    fun getReminderTime(): Pair<Int, Int> {
        return Pair(
            sharedPref.getInt(SHARED_PREF_REMINDER_HOUR, 22),
            sharedPref.getInt(SHARED_PREF_REMINDER_MINUTE, 0)
        )
    }

    fun setReminderTime(hour: Int, minute: Int) {
        sharedPref.edit {
            putInt(SHARED_PREF_REMINDER_HOUR, hour)
            putInt(SHARED_PREF_REMINDER_MINUTE, minute)
        }
    }

    fun cancelReminder() {
        sharedPref.edit {
            putInt(SHARED_PREF_REMINDER_HOUR, -1)
            putInt(SHARED_PREF_REMINDER_MINUTE, -1)
        }
    }

    fun isDefaultReminderSet() = sharedPref.getBoolean("is_default_reminder_set", false)

    fun saveDefaultReminderIsSet() {
        sharedPref.edit { putBoolean("is_default_reminder_set", true) }
    }
}

首次启动应用程序时,我们将默认提醒设置为晚上 10 点,然后由用户自定义。我可能已经删除了底部的一些冗余方法,但找不到可行的解决方案。现在,让我们转到 ViewModel。

主视图模型

class MainViewModel(application: Application) : AndroidViewModel(application) {

    private val app = application
    private val prefStore = PreferenceStore(application)

    fun scheduleReminderNotification(hourOfDay: Int, minute: Int) {
        prefStore.setReminderTime(hourOfDay, minute)
        ReminderNotificationWorker.schedule(app, hourOfDay, minute)
    }

    fun getReminderTime() = prefStore.getReminderTime()

    fun cancelReminderNotification() {
        log("Cancelling reminder notification")
        prefStore.cancelReminder()
        WorkManager.getInstance(app).cancelAllWorkByTag(TAG_REMINDER_WORKER)
    }

    /**
     * This sets the default time at the first launch of the app
     */
    private fun checkAndSetDefaultReminder() {
        if (!prefStore.isDefaultReminderSet()) {
            scheduleReminderNotification(DEFAULT_REMINDER_HOUR, DEFAULT_REMINDER_MINUTE)
            prefStore.saveDefaultReminderIsSet()
        }
    }

我们扩展类,因为初始化数据库实例和共享首选项存储需要AndroidViewModel应用程序实例,或者更确切地说是. 我计划很快将使用 Hilt 的依赖注入添加到应用程序中,这将消除对此的需求。在我们的 ViewModel 中,每次初始化 ViewModel 时都会调用该方法。现在这没问题(或者是吗?:p),因为我们只使用一个跨片段共享的 ViewModel,因为 Transactions 是一个相对较小的应用程序,但它很快就会迁移到更合适的地方,比如 Application 类。其他方法的意图应该通过名称足够清楚。现在,让我们看看允许用户配置通知的方法:ContextWorkManagercheckAndSetDefaultReminderBottomSheetDialogFragment

通知BottomSheet

class NotificationsBottomSheet : BottomSheetDialogFragment() {
    private lateinit var binding: FragmentNotificationsBottomSheetBinding
    private val viewModel by viewModels<MainViewModel>()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentNotificationsBottomSheetBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        setInitial()

        binding.checkboxReminder.setOnCheckedChangeListener { buttonView, isChecked ->
            if (isChecked) {
                // Was previously removed by user, now user wants to re-enable.
                viewModel.scheduleReminderNotification(DEFAULT_REMINDER_HOUR, DEFAULT_REMINDER_MINUTE)
                binding.textViewReminderTime.isEnabled = true
                binding.textViewReminderTime.text = get12HourTime(DEFAULT_REMINDER_HOUR, DEFAULT_REMINDER_MINUTE)
            } else {
                viewModel.cancelReminderNotification()
                binding.textViewReminderTime.isEnabled = false
                binding.textViewReminderTime.text = "Not set"
            }
        }

        binding.textViewReminderTime.setOnClickListener {
            val time = viewModel.getReminderTime()

            val picker = MaterialTimePicker.Builder()
                .setTimeFormat(TimeFormat.CLOCK_12H)
                .setHour(time.first)
                .setMinute(time.second)
                .setTitleText("Select Reminder Time")
                .build()
            picker.show(parentFragmentManager, "notification-time-picker")

            picker.addOnPositiveButtonClickListener {
                val hour = picker.hour
                val minute = picker.minute
                viewModel.scheduleReminderNotification(hour, minute)
                val newTime = viewModel.getReminderTime()
                binding.textViewReminderTime.text = get12HourTime(newTime.first, newTime.second)
            }
        }
    }

    private fun setInitial() {
        val setTime = viewModel.getReminderTime()
        if (setTime.first == -1 || setTime.second == -1 ) {
            binding.checkboxReminder.isChecked = false
            binding.textViewReminderTime.isEnabled = false
            binding.textViewReminderTime.text = "Not set"
        } else {
            binding.checkboxReminder.isChecked = true
            binding.textViewReminderTime.isEnabled = true
            binding.textViewReminderTime.text = get12HourTime(setTime.first, setTime.second)
        }
    }
}

从首选项中获取和设置初始值。用户可以通过单击复选框来启用或禁用通知。时间可以通过点击文本来配置,默认值为 10 PM。我们使用 MaterialTimePicker小部件让用户可以轻松选择时间,而且与TimerPickerDialog在应用程序其他地方使用的单独的 相比,它的实现也非常简单。

每隔24小时,WorkManager会触发提醒通知Worker。然后,工作人员创建一个通知(这就是工作),点击它可以将用户直接带到应用程序。这使我们能够实现上述功能,同时利用WorkManager的强大AndroidX库,在设备上保持实现。

总结

写到这里也结束了,在文章最后放上一个小小的福利,以下为小编自己在学习过程中整理出的一个关于Flutter的学习思路及方向,从事互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。
由于内容较多就只放上一个大概的大纲,需要更及详细的学习思维导图的文末卡片免费获取。

还有免费的高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术资料,并且还有技术大牛一起讨论交流解决问题。

Android WorkManager详细介绍和示例 在Android应用开发中,后台任务处理是一个常见的需求。这些任务可能包括数据同步、定期更新、通知发送等。然而,管理这些任务可能会变得复杂,特别是在处理周期性任务、延迟任务和可靠性要求较高的任务时。为了简化这一过程,Google在Android架构组件库中引入了WorkManager。 阅读详情

相关推荐

Android Jetpack WorkManager 基础

hl=zh-cnWorkManager是一个Android Jetpack库,用于在满足特定约束条件下,在后台执行可延迟的、异步的任务。它能够有效地管理后台工作任务,确保任务在合适的时机执行,同时也考虑到了电池优化、设备资源管理等因素。立即执行:必须立即开始且很快就完成的任务,可以加急。长时间运行:运行时间可能较长(有可能超过 10 分钟)的任务。可延期执行:延期开始并且可以定期运行的预定任务。

嗯... 1571

推送 Push\通知\渠道推送 JobScheduler 本地推送 WorkManager以及是否适用国内 后台执行限制

解析之后拉起应用首页时,Context的类型为application,因此,需要拉起首页的intent消息中要添加下面的Flag标志位,表示如果当前没有存在activity的task任务栈的话,则创建task任务栈,如果存在task任务栈,则将activity压入task任务栈。因为小米渠道Android12版本在点击推送消息时会拉起activity,因此小米渠道没法判断无法根据应用在前台或后台,从而进行不同的处理,比如应用在前台时,仅传递自定义参数不拉起界面,应用在后台时,即传递参数又拉起界面。

qq_42015021的博客 1058

Android Jetpack学习系列之WorkManager

WorkManager 是 Android Jetpack 架构中的关键组件之一,主要用于处理后台任务。它提供了一种简单而可靠的方法来确保即使在应用进程可能被系统杀死、设备可能进入休眠状态、以及操作系统对后台服务的各种限制等困难条件下,后台任务也能可靠地执行。WorkManager 提供了一个强大且灵活的框架来处理 Android 应用中的后台任务。尽管它有一定的学习曲线,但它的可靠性和对电池寿命的优化使得它成为许多应用场景的理想选择。

工宗浩生财指南针 1175

Android JetPack组件(六)DataBinding

Android 布局文件通常只负责UI的布局工作,页面通过setContentView()关联布局文件,再通过UI控件的id找到控件,接着在页面中通过代码对控件进行操作,因此,页面承担了很大的工作量。为了减轻页面的工作量,Google推出了DataBinding,使得页面和布局之间的耦合度降低。

八归少年 2395

Android本机定时推送通知Demo

利用闹钟alarmmanager来定时的发送通知,在通知栏显示,点击后跳转到指定activity

Android使用JobScheduler定期推送本地通知实例代码

Android5.0之后提供了JobService和JobScheduler,用于在稍后的某个时间点或者当满足某个特定的条件时执行一个任务。使用JobScheduler,我们可以在用户一段时间没有使用我们的app的情况下,推送本地通知来提高app的用户留存率。废话不多说,上代码: 先在app的MainActivity启动时用JobScheduler来schedule一个job。注意在onCreate中我们把用户启动app的时间记录在了shared preference里面: @Override protected void onCreate(Bundle savedInstanceSta

【安卓app开发三】基于Fragment构建底部导航栏与个人中心模块

本期内容主要是实现app底部导航栏与个人中心模块的构建。 底部导航栏一共有四个模块(游戏、新闻、充值、我的),其主要是利用“bottomnavigation+fragment”来实现的,bottomnavigation可以理解为底部导航菜单,fragment本意是碎片,在这里是指每一个模块里边所对应的内容; 个人中心的构建主要是利用Glide来实现头像的高斯模糊,再利用自定义View作为模板实现个人中心里边各个板块的复用。

半夜不熬夜的博客 2528

stata 代码实现熵值法计算 含常见问题解答

2.标准化①正向指标②负向指标。

m0_74825360的博客 1218

android定时推送通知,使用workManager实现每日定时推送通知

写这篇博客的缘由来自一个需求:每日定时推送通知,提醒用户完成签到。如果后台被清理,则在打开App后立即推送。众所周知,如今的Android国产ROM想要实现定时操作需要做极强的保活。然而一旦做了保活,那么程序就可能会消耗没有必要的资源,变得很流氓,这并不是我们想要看到的。于是jobSchedule应运而生,这个库应该是最完美的解决方案,但有api限制,并不能满足我的需要。后来尝试了AlarmMan...

weixin_28856717的博客 923

三维重建笔记_光束平差法(Bundle Adjustment, BA)

目录 1 光束平差法(Bundle Adjustment, BA) 1.1 SFM (Structure‐from‐Motion) 定义 问题描述 1.2 重投影误差 (Reprojection Error) 目标函数 1.3 使用 Levenberg‐Marquardt Algorithm 进行优化 问题描述 简化目标函数 参考 Gauss‐Newton Method ...

惊鸿一博 2万+

金属粘结剂喷射3D打印技术:工艺流程与后处理关键

金属粘结剂喷射(Binder Jetting)是一种创新的增材制造技术,通过逐层喷射粘合剂将金属粉末粘结成型,再经过脱脂和烧结等后处理工序获得最终零件。这项技术的核心优势在于无需支撑结构、可实现批量生产,并且材料利用率高。在3D打印领域,金属BJ技术特别适合中小尺寸、结构复杂且表面质量要求高的零件生产。其工艺流程包括前期数据处理、打印生胚阶段、拆包与清粉,以及关键的渗透、脱脂和烧结后处理环节。后处理工艺的控制直接决定了零件的机械性能和尺寸精度,其中烧结工艺尤为关键,需要精确控制温度曲线和气氛环境。金属BJ打

weixin_35751194的博客 86

如何使用Python制作一款任务计划,到达指定时间进行弹窗提示,并播放提示音,需详细代码...

您可以使用 Python 的 time 库和 tkinter 库来实现这个任务计划。 以下是实现这个功能的代码: import time import tkinter as tk import winsound def show_alarm(): # 创建 Tkinter 窗口 window = tk.Tk() window.title("闹钟") # 显示弹窗...

weixin_42612405的博客 808

fMRI独立成分分析方法(ICA)工具GIFT

详细介绍了进行fmri数据进行ICA分析的工具包GIFT的使用,和进行ICA分析的流程。

m0_58256026的博客 1万+

Instant Weather通知系统:WorkManager + NotificationHelper实现智能提醒

Instant Weather是一款基于MVVM架构的Android天气应用,集成了Retrofit2、Dagger Hilt、LiveData等Android Jetpack组件。本文将深入解析其通知系统的实现原理,展示如何通过WorkManager和NotificationHelper实现高效智能的天气提醒功能。 ## 应用架构概览 Instant Weather采用现代化的MVVM架构,

gitblog_01031的博客 886

Imatest-Star模块(西门子星图)

星图分析指南:基于ISO12233标准的MTF测试方法,通过放射状射线和正弦灰度变化评估相机SFR性能。

weixin_64706696的博客 1573

ZYNQ通过AXI DMA实现PL发送连续大量数据到PS DDR

方案二是在PS端的MPU配置中,将DMA缓冲区所在的内存区域标记为“不缓存”(Device或Strongly Ordered类型),但这样CPU访问这些内存区的速度会大幅降低,需要根据实时性和数据正确性的需求做权衡。更妙的是,描述符链表可以做成一个环状队列,放在DDR里让DMA循环取走,从而实现持续不断的“流式”传输。用FPGA实现FFT硬件加速的系统中也是如此:PS向PL提交待处理的FFT数据,PL硬件加速计算后,DMA把结果写回DDR,全程CPU几乎只做配置调度,大量数据吞吐留给了硬件通道。

QQ_778132974的博客 175

Android Jetpack 的WorkManager的使用简介

222

weixin_42324979的博客 738

AI硬件加速:CPU vs GPU性能对比

AI硬件加速:CPU vs GPU性能对比 关键词:人工智能、硬件加速、CPU、GPU、性能对比、硬件架构、并行计算、优化策略、项目实战 摘要: 本文将深入探讨AI

AI天才研究院 1914

WorkManager笔记: 一、基础入门

Android jetpack WorkManager 使用入门; 本篇内容为: 工作创建, 区分一次性及定期工作, 灵活时段工作. 启用工作约束, 重试退避政策等

孟老板的博客 906

AUTOSAR从入门到精通-【自动驾驶】特斯拉全自动驾驶(FSD)

特斯拉全自动驾驶系统(Full-Self Driving,简称FSD)是特斯拉公司开发的高级驾驶辅助系统,旨在通过神经网络技术实现环境感知与车辆控制,在驾驶员监督下完成导航、转向、变道、泊车等操作。‌ 该系统自2021年发布Beta测试版以来持续迭代,最新版本为2025年10月推出的v14版本。‌FSD v14版本基于端到端神经网络架构,取代了传统代码逻辑,通过数百万视频片段训练模型,以模仿人类驾驶决策。‌ 其功能覆盖住宅区街道、城市道路及高速公路,支持交通信号识别、自动变道和环岛通行等场景。

getusushu的博客 571

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Jetpack架构组件库:WorkManager

工作使用Worker类定义。Worker类的doWork()方法在提供的后台线程上异步运行。如需为创建一些要运行的工作,请继承Worker类并重写doWork()方法。从doWork()返回的Result会通知服务工作是否成功,以及工作失败时是否应重试工作。:工作成功完成。:工作失败。:工作失败,应根据其重试政策在其他时间尝试。默认情况下,当您的应用启动时,WorkManager 使用适合大多数应用的合理选项自动进行配置。

川峰的博客 1739

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

使用 WorkManager 管理后台和前台工作

WorkManager 是应对长执行时间工作的推荐方案,推荐您使用 WorkManager 实现请求和取消长时间运行的工作任务。通过本文了解到如何以及何时使用加急工作 API,如何编写可靠的高性能多进程应用。

hao_qi 3025

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Chocolatey choco source深度解析:5种Source类型与私有软件源配置教程

Chocolatey 是 Windows 平台事实上的软件包管理器,而 `choco source` 正是它用来管理所有软件源(Source)的核心命令。本文带你从查看源列表、理解 5 种 Source 类型,到一步步配置带认证的私有软件源,全程图解 Chocolatey 源管理的关键细节,让你快速搭好团队专属的 Windows 软件仓库。 ## 📋 choco source 命令总览:5个子

gitblog_00885的博客 1067

Android Jetpack组件之WorkManager后台任务管理的介绍与使用(一)

WorkManager 是适合用于持久性工作的推荐解决方案。如果工作始终要通过应用重启和系统重新启动来调度,便是持久性的工作。由于大多数后台处理操作都是通过持久性工作完成的,因此 WorkManager 是适用于后台处理操作的主要推荐 API。

1063

Instant Weather后台任务管理:WorkManager实现定时天气更新

想要在Android应用中实现可靠的定时天气更新吗?Instant Weather应用通过WorkManager后台任务管理,为用户提供了智能的定时天气更新功能。这款基于MVVM架构的天气应用,巧妙地将Android Jetpack的WorkManager组件与实时天气数据同步相结合,让用户无需手动刷新就能获取最新的天气信息。📱🌤️ ## 为什么选择WorkManager进行后台任务管理?

gitblog_00842的博客 1039

Android Jetpack 之 WorkManager

1. 前言 最近在 API 30 中准备使用 IntentService,结果发现在 API 30 中,IntentService 已经是deprecated 状态了。关于IntentService 的使用和原理可以参考我之前写的:IntentService 的使用和源码分析。Google 建议使用 WorkManager 或者 JobIntentService 来替代IntentService。 使用 WorkManager API 可以轻松地调度即使在应用退出或设备重启时仍应运行的可延迟异步任...

接受自己的普通,然后拼尽全力去与众不同 847
上一篇: 清理空的 Jetpack Compose 应用程序模板
下一篇: 使用 MERN 堆栈构建登录/注册 - 第 1 部分(后端)
不秃头de程序猿
博客等级 码龄5年 4089粉丝 1478原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值