如何在 OnCreate 方法/活动之外启动Service? (初学者)

问题描述 投票:0回答:1

大家好。目前,我正在构建应用程序的一部分,按下按钮即可启用和禁用 GPS 位置跟踪。

问题是我不明白如何正确启动它并通过按按钮停止它。

这是我的代码:

package red.button.flipper_navigator.ui

import android.Manifest
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.lifecycle.ViewModel

import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import red.button.flipper_navigator.ui_logic.MainScreenLogic
import red.button.flipper_navigator.R
import red.button.flipper_navigator.databinding.ScreenMainBinding
import red.button.flipper_navigator.databinding.TextFieldBinding
import red.button.flipper_navigator.gps.LocationService
import red.button.flipper_navigator.gps.gps_activation


@Suppress("DEPRECATION")
class MainScreen : AppCompatActivity(), gps_activation {
    private lateinit var bindingMain: ScreenMainBinding
    private lateinit var bindingField: TextFieldBinding
    private var context: Context? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ActivityCompat.requestPermissions(
            this,
            arrayOf(
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.POST_NOTIFICATIONS
            ),
            0
        )

        bindingMain = DataBindingUtil.setContentView(this, R.layout.screen_main)
        bindingField = bindingMain.textField

        val viewModel = ViewModelProvider(this)[MainScreenLogic::class.java]

        bindingMain.mainview = viewModel
        bindingField.textfieldview = viewModel
        context =  getApplicationContext()

//        Intent(context, LocationService::class.java).apply {
//            action = LocationService.ACTION_START
//            startService(this)
//        }

    }

    override fun start() {
        Intent(context, LocationService::class.java).apply {
            action = LocationService.ACTION_START
            startService(this)
        }
    }

    override fun stop() {
        Intent(context, LocationService::class.java).apply {
            action = LocationService.ACTION_STOP
            startService(this)
        }
    }
}

//Organise string. Evidence link, make all strange symbols disappear
//val str: String = (" " + editText.text.toString() + " ").replace("\n", " ")

//
// Toast.makeText(this, fLink, Toast.LENGTH_SHORT).show()



这是我的gps_activation界面

package red.button.flipper_navigator.gps

import android.content.Context
import red.button.flipper_navigator.ui.MainScreen

interface gps_activation {
    fun start()
    fun stop()

    companion object {
        fun create(): gps_activation {
            return MainScreen()
        }
    }
}



这是我的视图模型,我在其中触发 Start 函数来启动服务。

package red.button.flipper_navigator.ui_logic

import android.app.Application
import android.content.Context
import android.content.Intent
import android.util.Log
import android.view.View
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
import red.button.flipper_navigator.core.impl.link_logic.TextRef
import red.button.flipper_navigator.data.remote.GetLink
import red.button.flipper_navigator.gps.LocationService
import red.button.flipper_navigator.gps.gps_activation

@OptIn(ExperimentalCoroutinesApi::class)
@Suppress("UNUSED_PARAMETER")
class MainScreenLogic() : ViewModel() {
    var link: String = ""

    val gpsSet = gps_activation.create()
    fun generateBt(view: View) {

        val linkUnzip = TextRef.create()
        val service = GetLink.create()

        val glink = viewModelScope.async {
            service.getPosts(linkUnzip.linkUnfolder(link))
        }
        glink.invokeOnCompletion {
            if (it == null) {
                Log.d("link111", linkUnzip.placeFind(glink.getCompleted())[1])

            }
        }
        Log.d("link111", "ok")

    }

    fun connectBt(view: View) {
    }


// This Button i'm trying to use to start gps //
    fun StartNavBt(view: View) {

        Log.d("gps", "ok")
        gpsSet.start()

    }


}


我收到此错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
                                                                                                        at android.content.ComponentName.<init>(ComponentName.java:131)
                                                                                                        at android.content.Intent.<init>(Intent.java:6858)
                                                                                                        at red.button.flipper_navigator.ui.MainScreen.start(MainScreen.kt:58)
                                                                                                        at red.button.flipper_navigator.ui_logic.MainScreenLogic.StartNavBt(Main_screen_logic.kt:47)
                                                                                                        at red.button.flipper_navigator.databinding.ScreenMainBindingImpl$OnClickListenerImpl1.onClick(ScreenMainBindingImpl.java:189)
                                                                                                        at android.view.View.performClick(View.java:7448)
                                                                                                        at android.view.View.performClickInternal(View.java:7425)
                                                                                                        at android.view.View.access$3600(View.java:810)
                                                                                                        at android.view.View$PerformClick.run(View.java:28305)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:938)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                        at android.os.Looper.loop(Looper.java:223)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:7656)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

按下按钮,我从界面启动一个函数,在主活动中初始化该函数,但我总是收到错误。

也许我做的完全错误?我应该用一些依赖来实现它吗?我仍在学习,它可以。

按下按钮,我从界面启动一个函数,在主活动中初始化该函数,但我总是收到错误。

也许我做的完全错误?我应该用一些依赖来实现它吗?我仍在学习,该程序可能已过时或错误。

感谢您的帮助!

android kotlin service
1个回答
0
投票

问题的根本原因在于这一行:

return MainScreen()

Android 的活动、服务和其他组件由 Android 平台管理。它们是在需要时自动创建的,它们会完成初始化过程,它们在平台创建的上下文中运行。我们无法直接创建这些对象并期望它们能够正常工作。

通常,ViewModel 应该对 Activity 一无所知,它不应该保留对 Activity 的引用或调用其方法。模型用于处理数据,而不是执行操作。我们通常做的就是以

Flow
LiveData
的形式暴露ViewModel中的一些信息。然后,我们在活动中观察这些数据,并根据变化的数据执行操作。

我没有提供可行的解决方案,因为这几乎超出了这个问题的范围。

© www.soinside.com 2019 - 2024. All rights reserved.