JobIntentService уничтожается, когда приложение уничтожается

как от разработчика android JobIntentService при работе на Android O или более поздней версии работа будет отправлена как задание через JobScheduler.enqueue. При работе на более старых версиях платформы он будет использовать Context.startService.

в моем случае я учусь JobIntentService и в моем случае у меня есть таймер, который запускается каждую секунду и отображает текущую дату и время, но когда мое приложение уничтожается JobIntentService также вам уничтожено, как я могу запустить его, когда приложение уничтожено

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)
        })

2 ответов


Я изучаю JobIntentService и в моем случае у меня есть таймер, который запускается каждую секунду и отображает текущую дату и время

это не подходящее использование для JobIntentService (или почти все остальное, если на то пошло).

когда мое приложение будет уничтожено, JobIntentService также будет уничтожен

точки JobIntentService сделать немного работы-некоторый дисковый ввод-вывод, некоторый сетевой ввод-вывод и т. д. - а потом иди прочь. Это не делать что-то бесконечно, и это не подходит для запуска асинхронной работы, и вы пытаетесь сделать как. После onHandleWork() заканчивается, служба уходит, и ваш процесс может быть завершен в любой момент времени после этого, что остановит ваш Timer.

как я могу запустить его, когда приложение будет уничтожена

вы можете использовать изображения Service, а не IntentService или JobIntentService. Возвращаться START_STICKY С onStartCommand() чтобы попросить Android перезапустить службу, если ваш процесс завершен (например, из-за низких условий памяти). Даже это может быть прекращено пользователем, но это устройство пользователя, а не ваше, и поэтому пользователь может делать все, что хочет пользователь.


On 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... Надеюсь, это поможет..