IntentService 已弃用,如何将其替换为 JobIntentService?

Posted

技术标签:

【中文标题】IntentService 已弃用,如何将其替换为 JobIntentService?【英文标题】:IntentService is deprecated, how do I replace it with JobIntentService? 【发布时间】:2020-09-20 02:59:54 【问题描述】:

使用IntentService(在kotlin中)实现FetchAddressIntentService

class FetchAddressIntentService  //Constructor of this service
    : IntentService(INTENTTAG) 
    //Receiver where results are forwarded from this service
    protected var resultReceiver: ResultReceiver? = null

    private val TAG by lazy  this::class.java.simpleName 

    //Intent Service handler
    override fun onHandleIntent(intent: Intent?)  //Errormessages
        var errorMessage = ""
        if (intent != null) 
            resultReceiver =
                intent.getParcelableExtra(RECEIVER)
        
        //Checks if receiver was properly registered
        if (resultReceiver == null) 
            Log.wtf(
                TAG,
                "No reciever received. There is nowhere to send the results !!"
            )
            return
        
        //Get the location passed to this service through an extra.
        var location: Location? = null
        if (intent != null) 
            location =
                intent.getParcelableExtra(LOCATION_DATA_EXTRA)
        
        //Make sure the location is really sent
        if (location == null) 
            errorMessage = getString(R.string.gis_error_no_location_data_provided)
            Log.wtf(TAG, errorMessage)
            deliverResultToReceiver(FAILURE_RESULT, errorMessage)
            return
        
        //Setting locale
        val geocoder = Geocoder(this, Locale.ROOT)
        //Address found
        var addresses: List<Address>? = null
        try 
            addresses = geocoder.getFromLocation(location.latitude, location.longitude, 1)
            Log.i(TAG,"rec: address = $addresses[0]")
         catch (ioException: IOException)  //Catches network or i/o problems
            errorMessage = getString(R.string.gis_error_service_not_available)
            Log.e(TAG, errorMessage, ioException)
         catch (illegalArgumentException: IllegalArgumentException)  //Error in latitude or longitude data
            errorMessage = getString(R.string.gis_error_invalid_lat_long_used)
            Log.e(
                TAG,
                errorMessage + ". Latitude = " + location.latitude +
                        ", Longitude = " + location.longitude,
                illegalArgumentException
            )
        
        //Handles cases where no addresses where found
        if (addresses == null || addresses.isEmpty()) 
            if (errorMessage.isEmpty()) 
                errorMessage = getString(R.string.gis_error_no_address_found)
                Log.e(TAG, errorMessage)
            
            deliverResultToReceiver(FAILURE_RESULT, errorMessage)
         else 
            val address = addresses[0]
            //deliverAddressToReceiver(SUCCESS_RESULT, address)
            deliverAddressToReceiver2(SUCCESS_ADDRESS,address)
        
    

    private fun deliverAddressToReceiver2(
        resultCode: Int,
        address: Address
    )
        val bundle = Bundle()
        bundle.putParcelable("address",address)
        resultReceiver?.send(resultCode,bundle)
    

    private fun deliverResultToReceiver(resultCode: Int, message: String) 
        val bundle = Bundle()
        bundle.putString(RESULT_DATA_KEY, message)
        resultReceiver!!.send(resultCode, bundle)
    

    companion object 
        private const val INTENTTAG = "FetchAddressIS"
    


有人建议我如何用JobIntentService 替换IntentService 吗?

IntentServiceandroid-R / Android-11 中已弃用。

我已尝试关注一些关于此的帖子,但没有人指导正确的路径如何以 AddressFetchIntentService 使用 IntentService 的方式将 IntentService 调用的可用性更改为 JobIntentService 调用。

RG

【问题讨论】:

你的onHandleIntent() 函数变成了onHandleWork() 函数。再加上你的超类从IntentServiceJobIntentService 的更改,应该是类本身所需的大部分更改。您需要对启动服务的代码进行一些更改。 JobIntentService 已弃用,请使用 WorkManager 【参考方案1】:
class FetchAddressIntentService : JobIntentService() 

    // This method is called when service starts instead of onHandleIntent
    override fun onHandleWork(intent: Intent) 
        onHandleIntent(intent)
    

    // remove override and make onHandleIntent private.
   private fun onHandleIntent(intent: Intent?) 

    // convenient method for starting the service.
    companion object 
        fun enqueueWork(context: Context, intent: Intent) 
            enqueueWork(context, FetchAddressIntentService::class.java, 1, intent)
        
    

你可以启动服务

    val intent = Intent(this, FetchAddressIntentService::class.java)
    FetchAddressIntentService.enqueueWork(this, intent)

重要:

您需要为清单添加权限。

&lt;uses-permission android:name="android.permission.WAKE_LOCK" /&gt; // pre-oreo 设备需要

还有

<service
    android:name=".FetchAddressIntentService"
    android:permission="android.permission.BIND_JOB_SERVICE" // needed for oreo and above
    android:exported="true"/>

阅读更多here


添加于 2020.06.02 19:20 GMT 作者 Roar Grønmo

我将代码更改为:

class FetchAddressJobIntentService:JobIntentService()

    private val TAG by lazy  this::class.java.simpleName 

    protected var resultReceiver: ResultReceiver? = null

    /*
    override fun onHandleWork(intent: Intent) 
        onHandleIntent(intent)
    */

    override fun onHandleWork(intent: Intent)  //Errormessages
        var errorMessage = ""

        resultReceiver = intent.getParcelableExtra(RECEIVER)

        //Checks if receiver was properly registered
        if (resultReceiver == null) 
            Log.wtf(
                TAG,
                "No reciever received. There is nowhere to send the results !!"
            )
            return
        
        //Get the location passed to this service through an extra.
        var location: Location? = null

        location = intent.getParcelableExtra(LOCATION_DATA_EXTRA)

        //Make sure the location is really sent
        if (location == null) 
            errorMessage = getString(R.string.gis_error_no_location_data_provided)
            Log.wtf(TAG, errorMessage)
            deliverResultToReceiver(FAILURE_RESULT, errorMessage)
            return
        
        //Setting locale
        val geocoder = Geocoder(this, Locale.ROOT)
        //Address found
        var addresses: List<Address>? = null
        try 
            addresses = geocoder.getFromLocation(location.latitude, location.longitude, 1)
            Log.i(TAG,"rec: address = $addresses[0]")
         catch (ioException: IOException)  //Catches network or i/o problems
            errorMessage = getString(R.string.gis_error_service_not_available)
            Log.e(TAG, errorMessage, ioException)
         catch (illegalArgumentException: IllegalArgumentException)  //Error in latitude or longitude data
            errorMessage = getString(R.string.gis_error_invalid_lat_long_used)
            Log.e(
                TAG,
                errorMessage + ". Latitude = " + location.latitude +
                        ", Longitude = " + location.longitude,
                illegalArgumentException
            )
        
        //Handles cases where no addresses where found
        if (addresses == null || addresses.isEmpty()) 
            if (errorMessage.isEmpty()) 
                errorMessage = getString(R.string.gis_error_no_address_found)
                Log.e(TAG, errorMessage)
            
            deliverResultToReceiver(FAILURE_RESULT, errorMessage)
         else 
            val address = addresses[0]
            //deliverAddressToReceiver(SUCCESS_RESULT, address)
            deliverAddressToReceiver2(SUCCESS_ADDRESS,address)
        
    

    private fun deliverAddressToReceiver2(
        resultCode: Int,
        address: Address
    )
        val bundle = Bundle()
        bundle.putParcelable("address",address)
        resultReceiver?.send(resultCode,bundle)
    

    private fun deliverResultToReceiver(resultCode: Int, message: String) 
        val bundle = Bundle()
        bundle.putString(RESULT_DATA_KEY, message)
        resultReceiver!!.send(resultCode, bundle)
    



    companion object
        fun enqueueWork(context: Context, intent: Intent)
            enqueueWork(context,FetchAddressJobIntentService::class.java, 1, intent)
        
    



【讨论】:

谢谢,Max,这让它更清楚了一点。我不知道如何获取 enqueueWork,但被你的“同伴对象”抢救了(我当然应该弄清楚我的自我!!,但我没有......)。真正让我害怕的是,它比原来的要快得多。 就是这样,当示例在 Java 中,而我们在 Kotlin 中时...... 如果我想立即执行操作,甚至在需要时使用前台服务,一个又一个操作,在队列中怎么办? IntentService 已弃用。没有其他解决办法吗? 很好的答案,尽管JobIntentService 现在也已弃用 @Max 我使用 JobIntentService 在触发确切警报时向用户触发通知。你建议我现在使用什么 JobIntentService 已被弃用?工作经理?

以上是关于IntentService 已弃用,如何将其替换为 JobIntentService?的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止 TinyMCE 用 span 替换已弃用的标签

替换 Java Awt 已弃用的方法

如何替换已弃用的 imp.load_dynamic 的用法?

如何在 Hibernate 中用 TableGenerator 替换已弃用的 MultipleHiLoPerTableGenerator

替换已弃用的函数 mysql_connect [重复]

用 Source.fromGraph 替换已弃用的 Source.actorPublisher - 如何限制?