2024年最全android实现满足条件的定时任务,面试官必问的十大问题及答案大全

最后附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总)

面试成功其实是必然的,因为我做足了充分的准备工作,包括刷题啊,看一些Android核心的知识点,看一些面试的博客吸取大家面试的一些经验,下面这份PDF是我翻阅了差不多1个月左右一些Android大博主的博客从他们那里取其精华去其糟泊所整理出来的一些Android的核心知识点, 全部都是精华中的精华,我能面试到现在资深开发人员跟我整理的这本Android核心知识点有密不可分的关系,在这里本着共赢的心态分享给各位朋友。

这份PDF囊括了JVM,Java集合,Java多线程并发,Java基础,生命周期,微服务, 进程,Parcelable 接口,IPC,屏幕适配,线程异步,ART,架构,Jetpack,NDK开发,计算机网络基础,类加载器,Android 开源库源码分析,设计模式汇总,Gradle 知识点汇总…

由于篇幅有限,就不做过多的介绍,大家请自行脑补

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!


class MyJobService: JobService() {



    override fun onStartJob(params: JobParameters?): Boolean {

        // 当条件满足时就会执行这里的代码,比如有网络的情况下,5秒后执行这里,如果5秒内又没网了,则不会执行。如果等到有网了之后会立即执行(已经过了最短),不会再重新计算5秒。

        Log.i(TAG, "${getCurrentTime()}:onStartJob")

        return true

    }



    override fun onStopJob(params: JobParameters?): Boolean {

        Log.i(TAG, "${getCurrentTime()}:onStopJob")

        return true

    }



    companion object {

           fun getCurrentTime() = DateFormat.format("kk:mm:ss", System.currentTimeMillis())        

    }



}



在onStartJob方法中执行自己的具体任务逻辑,需要开子线,因为Service是运行在主线程的,而这个Service什么时候执行呢?就需要使用到JobScheduler,它就可以定义需要满足什么条件,延迟多久执行任务等一些条件设置,代码如下:


class MyJobService: JobService() {

    

    companion object {

        val TAG: String = "MyJobService"

        var jobScheduler: JobScheduler? = null



        fun getCurrentTime() = DateFormat.format("kk:mm:ss", System.currentTimeMillis())

        

        fun startScheduler(context: Context) {

            jobScheduler = context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler

            // 注:JobInfo可以声明为成员变量,只创建一次,在重复执行任务时可以复用。

            val job: JobInfo = JobInfo.Builder(1, ComponentName(context, MyJobService::class.java))

                .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)

                // 指定任务的延迟时间,即5秒后才开始此任务,即调用了jobScheduler.schedule()方法之后等5秒后再执行任务,任务就是判断如果有网络,则执行JobService的onStartJob方法

                // 如果5秒后任务条件没有满足,等到满足的时候就会立马执行JobService的onStartJob方法

                .setMinimumLatency(TimeUnit.SECONDS.toMillis(5)) // 最小为5秒,设置更小将使用5秒

                //.setOverrideDeadline(TimeUnit.SECONDS.toMillis(10)) // 设置最大延迟时间为10秒,则调用jobScheduler.schedule()方法之后如果10秒后条件还不满足也执行JobService的onStartJob方法

//                .setPeriodic(TimeUnit.SECONDS.toMillis(3)) // 最小间隔为15分钟(定义在JobInfo.getMinPeriodMillis()),不能比这个小,如果比这个小估计就会使用15分钟

                .build()

            val result = jobScheduler?.schedule(job)

            Log.i(TAG, "${getCurrentTime()}:startScheldur:${if (result == 0) "RESULT_FAILURE" else "RESULT_SUCCESS"}")

        }



        fun cancelScheldur() {

            jobScheduler?.cancelAll()

        }



    }



}



这里设置了条件,5秒后执行任务,任务的条件是有网络才执行MyJobService中的onStartJob方法。

关于onStartJob方法:JobParameters参数,由系统创建,如果想放里面存放一些内容,在JobInfo.Builder中可以设置。方法返回值,true代表任务还在执行,当自己的任务执行完成后调用jobFinished来告诉系统,此时系统会释放唤醒锁,不知道这个锁是什么东西。如果返回false,表示任务结束,系统直接释放唤醒锁。

onStopJob方法,并不是说任务结束了就会调用此方法,比如调用了jobFinished后此方法也不会执行。此方法执行的话,表示之前条件已经满足了,onStartJob方法已经执行了,但是此方法返回true,而且没有调用jobFinished,则系统并没有释放唤醒锁,如果此时条件突然不满足了则会回调此方法,比如你需要有网络才执行一个下载任务,当有网络时onStartJob开始执行,然后突然网络断开,则onStopJob开始执行,意思就是告诉你,网络没有了,你快停止下载任务吧,而且此时系统会释放唤醒锁,又或者你还没下载完,我们调用了jobScheduler.cancelAll()方法,表示取消任务,则onStopJob会执行,总之,onStopJob执行时,肯定是已经执行过了onStartJob的,onStopJob执行是告诉你条件突然不满足了,快停止你正在进行的任务。如果在onStartJob调用后,当你的任务完成时,你应该调用jobFinished方法来告诉系统你的任务完成了,此时系统释放唤醒锁,如果此时突然条件不满足了,系统也不会调用onStopJob了,因为你的任务已经完成了,即使你没完成,但是你调用了jobFinished就表示已经完成了,所以系统就没必要调用onStopJob来通知你停止任务了。 返回值:false表示工作完全结束,true表示你的工作没有结束,但你也必须停止你的任务,系统会根据你创建任务时提供的重试条件重新安排任务,即在下次条件满足时再来执行你的任务。再细说一下返回true的细节,如果d onStartJob中返回true,onStopJob中也返回true,则当条件满足后执行onStartJob,此后当条件不满足时执行onStopJob,如果设置了重试,则当条件再次满足时会再执行onStartJob,然后条件不满足时又执行onStopJob,即如果我们不调用jobFinished方法,在条件满足和不满足时就会一直执行onStartJob和onStopJob方法,实现只要条件一达到就执行一次任务。而如果onStopJob返回false,则只要onStopJob被调用一次,则表示任务已经结束了,之后 条件满足也不再执行onStartJob。 重试是通过JobInfo.Builder的setBackoffCriteria(long initialBackoffMillis, @BackoffPolicy int backoffPolicy)方法进行设置,第一个参数是设置延迟多少时间后再开始任务,开始任务不是说立马执行onStartJob,而是说指定的延迟时间之后 ,如果条件满足了则立即执行onStartJob,如果不满足则等到满足了才会执行onStartJob,第二参数是一个策略,如果指定为线性,假如延迟时间为10秒,则第一次重试延迟10秒,第二次重试时延迟20秒,第三次延迟30秒。。。

总结就是:一般onStartJob和onStopJob都返回true,在onStartJob中完成任务时再调用jobFinished,这样的话,在任务没完成时如果条件突然不满足了,则任务肯定要暂停了,则我们可以通过重试策略在将来条件再次满足时再继续我们的任务。

学完这些知识点就可以做这样一个需求了,完成一个类似定时器的功能,每5秒钟执行一次,而且是有网络的情况下才执行,如果没有网络就等到有网络才执行(如果实现定时向服务器发送心跳包),代码如下:


class MyJobService: JobService() {



    override fun onStartJob(params: JobParameters?): Boolean {

        Log.i(TAG, "${getCurrentTime()}:onStartJob")

        startScheduler(this)

        return false

    }



    override fun onStopJob(params: JobParameters?) = false



    companion object {

        val TAG: String = "MyJobService"

        var jobScheduler: JobScheduler? = null

        var job: JobInfo? = null



        fun getCurrentTime() = DateFormat.format("kk:mm:ss", System.currentTimeMillis())



        fun startScheduler(context: Context) {

            jobScheduler = context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler

            cancelScheduler()

            if (job == null) {

                job = JobInfo.Builder(1, ComponentName(context, MyJobService::class.java))

                    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)

                    .setMinimumLatency(TimeUnit.SECONDS.toMillis(5)) // 最小为5秒,设置更小将使用5秒

                    .build()

            }

            val result = jobScheduler?.schedule(job!!)

            Log.i(TAG, "${getCurrentTime()}:startScheduler:${if (result == 0) "RESULT_FAILURE" else "RESULT_SUCCESS"}")

        }



        fun cancelScheduler() {

            jobScheduler?.cancelAll()

        }



    }



}



可以看到这里onStartJob和onStopJob都返回了false,只要onStartJob一执行就会释放唤醒锁,所以onStopJob永远也不会被调用,onStopJob返回什么都没有差异了,而onStartJob中立马又开始一个新的任务,所以系统又会为新任务分配一个唤醒锁,当条件再次满足时再次执行onStartJob。

对于说应用关掉,只要条件满足这安排的任务也会被执行,或者重启后如果条件满足了即使程序没运行,任务也会被执行,这个目前也没时间实验了,如果真的是这样,那就得注意如果程序都没启动的话,直接运行任务代码要写严谨,不能出Bug,即不要用到一些应用启动才初始化的一些实例变量。

还有一个细节点,就是我们指定的条件满足后,只是系统会尽快安排执行onStartJob,并不代表会立即执行的,还要根据系统的相关设置变化的,比如一些高版本的系统,当设置了省电模式时,可能我们的任务就不执行了,比如我们的应用后台运行了,虽然我们需要的条件满足了,但是设置了省电模式可能就不执行了,系统就限制了后台应用的任务执行了,为了省电嘛!只有等到用户关闭省电模式,并且那时我们的条件还满足的话才执行onsTartJob。这个我也没有实验过,在此记录一下有这个知识点。

尾声

最后,我再重复一次,如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

这里,笔者分享一份从架构哲学的层面来剖析的视频及资料分享给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。

Android进阶学习资料库

一共十个专题,包括了Android进阶所有学习资料,Android进阶视频,Flutter,java基础,kotlin,NDK模块,计算机网络,数据结构与算法,微信小程序,面试题解析,framework源码!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

D-1715851079259)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值