【问题标题】:How can stop a IntentService on Android?如何在 Android 上停止 IntentService?
【发布时间】:2020-04-03 03:59:20
【问题描述】:

我有一个 IntentService 在我的应用程序中运行。我想在用户按下取消按钮时停止,但 onHandleIntent 仍在运行,即使调用了 onDestroy (IntentService)。

我在执行过程中尝试了 stopSelf(),stopSelf(int) 和 stopService(intent),但是没有用。

class DownloadIntentService : IntentService("DownloadIntentService") {

    val TAG: String = "DownloadIntentService"

    val AVAILABLE_QUALITIES: Array<Int> = Array(5){240; 360; 480; 720; 1080}

    // TODO Configurations
    val PREFERED_LANGUAGE = "esLA"
    val PREFERED_QUALITY = AVAILABLE_QUALITIES[0]

    @Inject
    lateinit var getVilosDataInteractor: GetVilosInteractor

    @Inject
    lateinit var getM3U8Interactor: GetM3U8Interactor

    @Inject
    lateinit var downloadDataSource: DownloadsRoomDataSource

    companion object {
        var startedId: Int = 0
    }

    override fun onCreate() {
        super.onCreate()
        (application as CrunchApplication).component.inject(this)
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d(TAG, "onStartComand ${startId}")

        startedId = startId

        super.onStartCommand(intent, flags, startId)
        return Service.START_NOT_STICKY
    }

    override fun onHandleIntent(intent: Intent?) {
        Log.d(TAG, "starting download service")

        val download = downloadDataSource.getDownloadById(intent?.getLongExtra(MEDIA_ID_EXTRA, 0) ?: 0)

        Log.d(TAG, "A new download was found: ${download.id} ${download.serieName} ${download.collectionName} ${download.episodeName}")

        val vilosResponse = getVilosDataInteractor(download.episodeUrl)

        val stream: StreamData? = vilosResponse.streams.filter {
            it.hardsubLang?.equals(PREFERED_LANGUAGE) ?: false
        }.getOrNull(0)

        if(stream == null) {
            Log.d(TAG, "Stream not found with prefered language ($PREFERED_LANGUAGE)")
            return
        }

        Log.d(TAG, "Best stream option: " + stream.url)
        val m3u8Response = getM3U8Interactor(stream.url)

        val m3u8Data: M3U8Data? = m3u8Response.playlist.filter { it.height == PREFERED_QUALITY }[0]

        if(m3u8Data == null) {
            Log.d("M3U8","Resolution ${PREFERED_QUALITY}p not found")
            return
        }

        Log.d(TAG, m3u8Data.url)

        val root = Environment.getExternalStorageDirectory().toString()
        val myDir = File(root + "/episodes/");
        if (!myDir.exists()) {
            myDir.mkdirs()
        }

        val output = myDir.getAbsolutePath() + "EPISODENAME.mp4";
        val cmd = "-y -i ${m3u8Data.url} ${output}"

        when (val result: Int = FFmpeg.execute(cmd)) {
            Config.RETURN_CODE_SUCCESS -> Log.d(TAG, "Success")
            Config.RETURN_CODE_CANCEL -> Log.d(TAG, "Cancel")
            else -> Log.d(TAG, "Default: $result")
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "onDestroy")
    }
}

我尝试从片段中停止

val intent = Intent(requireContext(), DownloadIntentService::class.java)
requireContext().stopService(intent)

提前致谢

【问题讨论】:

  • 这能回答你的问题吗? How to stop intentservice in android?
  • 我已经尝试过 stopSelf,但没有成功。我知道 IntentService 在工作完成后会自行停止,但是当用户按下按钮时我真的需要取消。也许我必须做另一个实现,另一个类来完成这项工作或其他事情
  • 如果你需要手动停止服务,你应该使用Service而不是IntentService

标签: android kotlin service intentservice


【解决方案1】:

基本上你不能。 OnHandleIntent 在工作线程上运行。要阻止它,您必须做与其他线程相同的事情,即在 onHandleIntent 内部进行布尔标志检查,然后在对该标志进行操作检查之前检查是否为真。现在当你想取消更新标志为 false。

这也取决于你在做什么。如果某些事情已经在进行中,那么它将继续运行。不是你必须有状态机才能让它停止。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多