【问题标题】:JobIntentService get destroyed , When app is destroyedJobIntentService 被销毁,当应用程序被销毁时
【发布时间】:2018-04-21 12:36:34
【问题描述】:

来自 android developer JobIntentService 在 Android O 或更高版本上运行时,工作将作为作业通过 JobScheduler.enqueue 分派。在旧版本平台上运行时,它将使用 Context.startService

在我的情况下,我正在学习 JobIntentService,在我的情况下,我有一个计时器,每秒钟运行一次并显示当前日期和时间,但是当我的应用程序被破坏时 @ 987654325@ 也被销毁了,应用程序被销毁时如何运行它

JobIntentService

class OreoService : JobIntentService() {

    private val handler = Handler()

    companion object {
        private const val JOB_ID = 123

        fun enqueueWork(cxt: Context, intent: Intent){
            enqueueWork(cxt,OreoService::class.java,JOB_ID,intent)
        }
    }

    override fun onHandleWork(intent: Intent) {

        toast(intent.getStringExtra("val"))

        Timer().scheduleAtFixedRate(object : TimerTask() {
            override fun run() {
                println(Date().toString())
            }

        }, Date(),1000)

    }

    override fun onDestroy() {
        super.onDestroy()
        toast("Service Destroyed")
    }

   private fun toast(msg: String){

       handler.post({
           Toast.makeText(applicationContext,msg,Toast.LENGTH_LONG).show()
       })
   }
}

清单

<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
....... >
<service android:name=".service.OreoService"
            android:permission="android.permission.BIND_JOB_SERVICE"/>
</application>

MainActivity(按下按钮时服务启动)

startServiceBtn.setOnClickListener({
            val intent = Intent()
            intent.putExtra("val","testing service")
            OreoService.enqueueWork(this,intent)
        })

【问题讨论】:

    标签: android kotlin


    【解决方案1】:

    我正在学习 JobIntentService,就我而言,我有一个每隔一秒运行一次并显示当前日期和时间的计时器

    这不适用于JobIntentService(或其他任何东西,就此而言)。

    当我的应用被销毁时,JobIntentService 也会被销毁

    JobIntentService 的目的是做一些工作——一些磁盘 I/O、一些网络 I/O 等等——然后离开。 not 用于无限期地做某事,它 not 适合启动异步工作,而您正在尝试同时做这两种工作。一旦onHandleWork() 结束,服务就会消失,并且您的进程可以在之后的任何时间点终止,这将停止您的Timer

    应用程序被销毁时如何运行它

    欢迎您使用前台Service,而不是IntentServiceJobIntentService。如果您的进程终止(例如,由于内存不足),请从 onStartCommand() 返回 START_STICKY 以要求 Android 重新启动您的服务。即使这可能被用户终止,但它是用户的设备,而不是您的设备,因此用户可以为所欲为。

    【讨论】:

    • 如果在JobIntentservice 启动后 Activity 被销毁但应用程序未从最近的屏幕中清除,JobIntentService 会发生什么情况,JobIntentService 会继续还是也会停止?用户也可以阻止(从设置中)JobIntentService 运行。
    • @RajeshK:“JobIntentService 会继续还是会停止?” -- 它与活动分离,因此它应该继续运行。 “用户也可以(从设置中)阻止 JobIntentService 运行”——用户无法阻止您启动它。用户可以停止它(例如,通过设置中的强制停止)。
    • 非常感谢您的回答。
    • 我在后台打印 1 到 1000 在最近的应用程序上工作正常,但在应用程序使用 jobintentservice 销毁时不工作任何人都知道为什么它必须在后台运行
    【解决方案2】:

    WAKE_LOCK 上android 系统如何知道运行你的Intent service?应该有一些接收器应该接收一些intent-action,它可以在其上运行您的接收器代码,您可以从您的接收器代码调用或启动您的服务或意图服务..!!


    这里是示例清单

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    
        <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    
        <service
            android:name=".WatchMan"
            android:enabled="true"
            android:exported="true" >
      </service>
    </application>
    

    上面的清单首先请求许可RECEIVE_BOOT_COMPLETED。然后告诉BOOT_COMPLETED何时启动我的接收器MyReceiver


    MyReceiver.java

    public class MyReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            Log.d("BootTest : ", "\nOnBootReceiver - Received a broadcast!");
            Toast.makeText(context, "OnBootReceiver Received a broadcast!!", Toast.LENGTH_LONG).show();
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            {
                context.startForegroundService(new Intent(context, WatchMan.class));
            }
            else
            {
                context.startService(new Intent(context, WatchMan.class));
            }
        }
    }
    

    依次开始WatchMan Service...希望对您有所帮助..

    【讨论】:

    • 代码是接收另一个意图动作,你必须根据你的意图动作改变它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多