class ForegroundService : Service() {
private var myCallback: MyCallback? = null
// Метод для установки объекта MyCallback
private fun setCallback(callback: MyCallback, data: String) {
myCallback = callback
myCallback!!.updateUI(data)
}
private val CHANNEL_ID = "1"
companion object {
fun startService(context: Context, message: String) {
val startIntent = Intent(context, ForegroundService::class.java)
startIntent.putExtra("inputExtra", message)
ContextCompat.startForegroundService(context, startIntent)
}
fun stopService(context: Context) {
val stopIntent = Intent(context, ForegroundService::class.java)
context.stopService(stopIntent)
}
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
//do heavy work on a background thread
val input = intent?.getStringExtra("inputExtra")
createNotificationChannel()
val notificationIntent = Intent(this, PostingVKActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
this,
0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
)
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service Kotlin Example")
.setContentText(input)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.build()
val firstActivity = PostingVKActivity()
val activity = ForegroundService()
activity.setCallback(firstActivity, "9999")
startForeground(2, notification)
return START_NOT_STICKY
}
override fun onBind(intent: Intent): IBinder? {
return null
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel() {
val serviceChannel = NotificationChannel(CHANNEL_ID, "2",
NotificationManager.IMPORTANCE_DEFAULT)
val manager = getSystemService(NotificationManager::class.java)
manager!!.createNotificationChannel(serviceChannel)
}
}
interface MyCallback {
fun updateUI(data: String)
}
class FirstActivity : AppCompatActivity(), MyCallback {
private lateinit var binding: ActivityFirstBinding
lateinit var gEditText: TextView
lateinit var button: Button
val currentName: MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
override fun updateUI(data: String){
// Здесь вы обновляете ваш интерфейс, например, ваш TextView
println("data updateUI: $data")
currentName.value = "8888"
println("currentName.value updateUI: ${currentName.value}")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityFirstBinding.inflate(layoutInflater)
gEditText = binding.gEditText
Button = binding.Button
val nameObserver = Observer<String> { newName ->
// Update the UI, in this case, a TextView.
gEditText.text = newName
}
currentName.observe(this, nameObserver)
Button.setOnClickListener {
currentName.value = "1"
val intentActivity = Intent(this, ForegroundService::class.java)
intentActivity.putExtra("inputExtra", "444");
startService(intentActivity)
}
setContentView(binding.root)
}
}
import android.app.IntentService
import android.content.Intent
import android.os.Handler
import android.os.Looper
class MyService : IntentService("MyService") {
private val handler = Handler(Looper.getMainLooper())
private var g = 0
override fun onHandleIntent(intent: Intent?) {
while (g < 10) {
val api = "https://test.ru/g=$g"
// Создайте и отправьте запрос
// Обновите UI через главный поток
handler.post {
// Обновите ваш UI здесь
gEditText.text = "$g"
}
g++
// Подождите 2 секунды перед следующим запросом
try {
Thread.sleep(2000)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
}
}
class Activity : AppCompatActivity() {}
// Создайте рабочего (Worker) для выполнения запросов
class MyWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
var g = 0
while (g < 10) {
// Выполняйте запрос и обновляйте UI здесь
// ...
g++
Thread.sleep(2000) // Подождите 2 секунды перед следующим запросом
}
return Result.success()
}
}
class MyService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// Ваш код выполнения запросов с задержкой
// ...
return START_STICKY
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
}
interface MyCallback {
fun updateUI(data: String)
}
class FirstActivity : AppCompatActivity(), MyCallback {
// ... остальной код активити
override fun updateUI(data: String) {
// Здесь вы обновляете ваш интерфейс, например, ваш TextView
gEditText.text = data
}
}
class Activity {
private var myCallback: MyCallback? = null
// Метод для установки объекта MyCallback
fun setCallback(callback: MyCallback) {
myCallback = callback
}
// Где-то в вашем коде, когда нужно обновить UI, вызывайте метод updateUI
private fun someMethod() {
// ...
myCallback?.updateUI("Новое значение для UI")
}
}
val firstActivity = FirstActivity()
val activity = Activity()
// Свяжите Activity и FirstActivity
activity.setCallback(firstActivity)
val firstActivity = FirstActivity()
val activity = Activity()
// Свяжите Activity и FirstActivity
activity.setCallback(firstActivity)
class ForegroundService : Service() {
private var myCallback: MyCallback? = null
// Метод для установки объекта MyCallback
private fun setCallback(callback: MyCallback) {
myCallback = callback
}
private val CHANNEL_ID = "1"
companion object {
fun startService(context: Context, message: String) {
val startIntent = Intent(context, ForegroundService::class.java)
startIntent.putExtra("inputExtra", message)
ContextCompat.startForegroundService(context, startIntent)
}
fun stopService(context: Context) {
val stopIntent = Intent(context, ForegroundService::class.java)
context.stopService(stopIntent)
}
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
//do heavy work on a background thread
val input = intent?.getStringExtra("inputExtra")
createNotificationChannel()
val notificationIntent = Intent(this, PostingVKActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
this,
0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
)
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service Kotlin Example")
.setContentText(input)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.build()
val firstActivity = FirstActivity()
val activity = ForegroundService()
activity.setCallback(firstActivity)
myCallback?.updateUI("TEST DATA")
startForeground(2, notification)
return START_NOT_STICKY
}
override fun onBind(intent: Intent): IBinder? {
return null
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel() {
val serviceChannel = NotificationChannel(CHANNEL_ID, "2",
NotificationManager.IMPORTANCE_DEFAULT)
val manager = getSystemService(NotificationManager::class.java)
manager!!.createNotificationChannel(serviceChannel)
}
}
interface MyCallback {
fun updateUI(data: String)
}
classFirstActivity : AppCompatActivity(), MyCallback {
override fun updateUI(data: String) {
// Здесь вы обновляете ваш интерфейс, например, ваш TextView
println("data: $data")
gEditText.text = data
}
}
class ForegroundService : Service() {
private var myCallback: MyCallback? = null
// Метод для установки объекта MyCallback
private fun setCallback(callback: MyCallback) {
myCallback = callback
myCallback?.updateUI("TEST DATA")
}
}
override fun updateUI(data: String) {
// Здесь вы обновляете ваш интерфейс, например, ваш TextView
println("data: $data")
gEditText.text = data
}
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
class MyWorker(context: Context, params: WorkerParameters) : Worker(context, params), MyCallback {
override fun doWork(): Result {
var g = 0
while (g < 10) {
// Выполняйте запрос и обновляйте UI здесь
// ...
// Обновление UI через callback
updateUI("Новое значение для UI")
g++
Thread.sleep(2000) // Подождите 2 секунды перед следующим запросом
}
return Result.success()
}
override fun updateUI(data: String) {
// Обновление UI, например, через LiveData, который прослушивается в вашей активности
// или каким-либо другим способом, который вы используете для обновления UI.
}
}
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
class FirstActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Создайте запрос на выполнение MyWorker
val workRequest = OneTimeWorkRequest.Builder(MyWorker::class.java).build()
// Запустите задачу с использованием WorkManager
WorkManager.getInstance(this).enqueue(workRequest)
}
}
class ForegroundService : Service() {
private var myCallback: MyCallback? = null
// Метод для установки объекта MyCallback
fun setCallback(callback: MyCallback) {
myCallback = callback
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// ...
if (myCallback != null) {
myCallback?.updateUI("TEST DATA")
}
// ...
}
}
class FirstActivity : AppCompatActivity(), MyCallback {
private lateinit var gEditText: EditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_first)
// Инициализация gEditText
gEditText = findViewById(R.id.your_edit_text_id)
// ...
}
override fun updateUI(data: String) {
gEditText.text = data
}
}
Это должно решить проблему с инициализацией myCallback и gEditText
и обеспечить корректную передачу данных и обновление UI.
Прежде чем реализовать, попробуйте понять, что и как решается.
Действительно на стороне Google многое меняется за последнее время.
Вот полный код для вашей ситуации на основе предыдущего Вашего ответа,
с учетом обновлений UI из фонового сервиса:
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
class MyWorker(context: Context, params: WorkerParameters) : Worker(context, params), MyCallback {
override fun doWork(): Result {
var g = 0
while (g < 10) {
// Выполняйте запрос и обновляйте UI здесь
// ...
// Обновление UI через callback
updateUI("Новое значение для UI")
g++
Thread.sleep(2000) // Подождите 2 секунды перед следующим запросом
}
return Result.success()
}
override fun updateUI(data: String) {
// Обновление UI, например, через LiveData, который прослушивается в вашей активности
// или каким-либо другим способом, который вы используете для обновления UI.
}
}
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
class FirstActivity : AppCompatActivity(), MyCallback {
private lateinit var gEditText: EditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_first)
// Инициализация gEditText
gEditText = findViewById(R.id.your_edit_text_id)
// Создайте запрос на выполнение MyWorker
val workRequest = OneTimeWorkRequest.Builder(MyWorker::class.java).build()
// Запустите задачу с использованием WorkManager
WorkManager.getInstance(this).enqueue(workRequest)
}
override fun updateUI(data: String) {
runOnUiThread {
gEditText.text = data
}
}
}
class ForegroundService : Service() {
private var myCallback: MyCallback? = null
// Метод для установки объекта MyCallback
fun setCallback(callback: MyCallback) {
myCallback = callback
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// ...
if (myCallback != null) {
myCallback?.updateUI("TEST DATA")
}
// ...
}
}
import android.app.Notification
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.os.IBinder
import androidx.core.app.NotificationCompat
class ForegroundService : Service() {
// ...
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// ...
// Создание уведомления для сервиса
val notification = createNotification(input)
// Запуск сервиса в режиме Foreground
startForeground(1, notification)
return START_NOT_STICKY
}
// ...
// Метод для создания уведомления
private fun createNotification(input: String?): Notification {
val notificationIntent = Intent(this, FirstActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
this,
0,
notificationIntent,
PendingIntent.FLAG_IMMUTABLE
)
return NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service Kotlin Example")
.setContentText(input)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.build()
}
}
С этими изменениями ваш фоновый сервис будет продолжать работать, даже если приложение свернуто. Убедитесь также, что у вас правильно настроена работа с уведомлениями и разрешениями на фоновую работу,, если это необходимо.
Предоставил возможные варианты, исключите в представленных вариантах излишние комментарии, код,
который возможно повторяется. Ваши знания Kotlin помогут Вам проверить значения переменных,
и скомпоновать несколько вариантов решения задачи облегчив решение сути вопроса.
Некоторый код также я опустил, просто закомментировав, проверьте, что ничего не упустили.
Также посмотрите Ваши разрешения Manifest (включая Gradle, Kotlin, Google) просмотрите все активности и разрешения, чтобы исключить серивисы влияющие на разрешения работы в фоне..
Если задача так и не решится, попробуйте предоставить не тестовый код, а боевой из проекта (именно тот кусок, который отвечает за логику фоновой обработки процесса), я попробую исправить код, предоставив вариант решения. Возможно, при энприментации кода из боевого в тестовый и обратно Вы допускаете ошибку логики или простановки знаков. Проверьте Ваш код через BagTracker в AndroidStudio, в Run & Bug
разобрал Ваш код в предоставленном Вами последнем ответе.
class ForegroundService : Service() {
private var myCallback: MyCallback? = null
// Метод для установки объекта MyCallback
fun setCallback(callback: MyCallback) {
myCallback = callback
}
}
class FirstActivity : AppCompatActivity(), MyCallback {
private lateinit var gEditText: EditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_first)
// Инициализация gEditText
gEditText = findViewById(R.id.your_edit_text_id)
// Создайте запрос на выполнение MyWorker
val workRequest = OneTimeWorkRequest.Builder(MyWorker::class.java).build()
// Устанавливаем MyCallback для ForegroundService
val serviceIntent = Intent(this, ForegroundService::class.java)
bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE)
WorkManager.getInstance(this).enqueue(workRequest)
}
override fun updateUI(data: String) {
runOnUiThread {
gEditText.text = data
}
}
private val serviceConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
val binder = service as ForegroundService.MyBinder
val service = binder.getService()
service.setCallback(this@FirstActivity)
}
override fun onServiceDisconnected(name: ComponentName?) {
// Handle disconnection, if needed
}
}
}
С этими изменениями, ваш фоновый сервис должен обновлять UI в gEditText без проблем.
И всё таки попробуйте все представленные мной ответы, попробуйте разобраться в них,
используйте разные реализации - не получится одна, исправит другая.
Пробуйте разные решения, спрашивайте, задайте дополнительно вопрос на StakOverFlow в русской и английской локализациях проекта, возможно, продвинутые кодеры знают готовый ответ.
Не бойтесь предоставить кодеру публично код из проекта, а не тестовые переменные для публичного пользования - это поможет в быстрой реализации решения.
Ваши собственные знания Kotlin и JS помогут в перекомпановке кода, проверке, правильной интерпретации и написании дополнительного кода. Пользуйтесь Debug в студио, чтобы проверить методы.
ВЫ ИЗНАЧАЛЬНО ПРЕДОСТАВИЛИ КОД, который вполне рабочий,
однако в нем имеются незначительные ошибки логики, попробуйте их исправить!
<uses-permission android:name="android.permission.INTERNET" />
Это вроде бы все значительно влияющие факторы.
Представил ниже пример улучшения кода, предоставленного изначально.
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import okhttp3.*
import java.io.IOException
class FirstActivity : AppCompatActivity() {
private val client = OkHttpClient()
private val handler = Handler(Looper.getMainLooper())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_first)
HOPO()
}
fun HOPO() {
runBlocking {
val job = launch(Dispatchers.IO) {
for (g in 0 until 10) {
val api = "https://test.ru/g=$g"
val request = Request.Builder()
.url(api)
.post(postBody.toRequestBody(MEDIA_TYPE_MARKDOWN))
.header("X-Get-Processing-Time", "1")
.removeHeader("User-Agent")
.addHeader("User-Agent", UserAgent)
.build()
try {
val response: Response = client.newCall(request).execute()
if (response.isSuccessful) {
val responseData = response.body?.string()
handler.post {
gEditText.text = "$g"
}
}
response.body?.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
job.join()
}
}
}
На данный номент это улучшение является лучшим решением задачи без дополнительных проверок и внедрений, на основе изначально предоставленного в вопросе кода.
Попробуйте для начала его, потом уже все остальные ответы, начиная с последнего Вашего ответа,
которые я предоставил. Там различные реализации и пути решения.
Описанное в этом ответе улучшение, гарантированно работает на Android 12, Android 13.
Смело можно проверить, и если не будет работать идти более сложными путями.
private val serviceConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
val service = (binder as ForegroundService.MyBinder).getService()
// Теперь у вас есть доступ к сервису и можете выполнять методы, предоставленные сервисом.
}
override fun onServiceDisconnected(name: ComponentName?) {
// Обработка отсоединения сервиса, если это необходимо.
}
}
class ForegroundService2 : Service() {
override fun onCreate() {
super.onCreate()
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
val input = intent.getStringExtra("inputExtra")
createNotificationChannel()
val notificationIntent = Intent(this, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
this,
0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
)
val notification: Notification = Notification.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText(input)
.setSmallIcon(R.drawable.alert_light_frame)
.setContentIntent(pendingIntent)
.build()
startForeground(1, notification)
//do heavy work on a background thread
//stopSelf();
return START_NOT_STICKY
}
override fun onDestroy() {
super.onDestroy()
}
@Nullable
override fun onBind(intent: Intent): IBinder? {
return null
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val serviceChannel = NotificationChannel(
Companion.CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
)
val manager = getSystemService(
NotificationManager::class.java
)
manager.createNotificationChannel(serviceChannel)
}
}
companion object {
const val CHANNEL_ID = "ForegroundServiceChannel"
}
}
class ForegroundService : Service() {
private val CHANNEL_ID = "1"
companion object {
fun startService(context: Context, message: String) {
val startIntent = Intent(context, ForegroundService::class.java)
startIntent.putExtra("inputExtra", message)
ContextCompat.startForegroundService(context, startIntent)
}
fun stopService(context: Context) {
val stopIntent = Intent(context, ForegroundService::class.java)
context.stopService(stopIntent)
}
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
//do heavy work on a background thread
val input = intent?.getStringExtra("inputExtra")
createNotificationChannel()
val notificationIntent = Intent(this, PostingVKActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
this,
0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
)
/*
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service Kotlin Example")
.setContentText(input)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.build()
startForeground(1, notification)
*/
//stopSelf();
return START_NOT_STICKY
}
override fun onBind(intent: Intent): IBinder? {
return null
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel() {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val serviceChannel = NotificationChannel(CHANNEL_ID, "1",
NotificationManager.IMPORTANCE_DEFAULT)
val manager = getSystemService(NotificationManager::class.java)
manager!!.createNotificationChannel(serviceChannel)
// }
}
}
ForegroundService.startService(this, "СТАРТ ")
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
class ForegroundService : Service() {
private val CHANNEL_ID = "1"
companion object {
fun startService(context: Context, message: String) {
val startIntent = Intent(context, ForegroundService::class.java)
startIntent.putExtra("inputExtra", message)
ContextCompat.startForegroundService(context, startIntent)
}
fun stopService(context: Context) {
val stopIntent = Intent(context, ForegroundService::class.java)
context.stopService(stopIntent)
}
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
//do heavy work on a background thread
val input = intent?.getStringExtra("inputExtra")
createNotificationChannel()
val notificationIntent = Intent(this, PostingVKActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
this,
0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
)
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service Kotlin Example")
.setContentText(input)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.build()
startForeground(1, notification)
//stopSelf();
return START_NOT_STICKY
}
override fun onBind(intent: Intent): IBinder? {
return null
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel() {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val serviceChannel = NotificationChannel(CHANNEL_ID, "1",
NotificationManager.IMPORTANCE_DEFAULT)
val manager = getSystemService(NotificationManager::class.java)
manager!!.createNotificationChannel(serviceChannel)
// }
}
}
fun HOPO(){
g = 0
while(g < 10){
api = "https://test.ru/g=$g"
val request = Request.Builder()
.url(api)
.post(postBody.toRequestBody(MEDIA_TYPE_MARKDOWN))
.header("X-Get-Processing-Time", "1")
.removeHeader("User-Agent")
.addHeader("User-Agent", UserAgent)
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
runOnUiThread {
gEditText.text = "$g"
}
}
})
g++
}//END WHILE
}//END FUN
val intentActivity = Intent(this, Activity::class.java)
startService(intentActivity)
HOPO()
Intent intent = new Intent(this, MyService.class);
intent.putExtra("param", text);
startService(intent);
Intent intent = new Intent(this, MyService.class);
А для такой задачи не лучше WorkManager?сейчас рекомендуют пользоваться именно этим, а как я понял сервисы себя дискредитировали и уже не надежны в плане фоновой работы
fun HOPO(context: Context) {
// Ваш код функции HOPO
// ...
}
val intentService = Intent(this, ForegroundService::class.java)
intentService.putExtra("inputExtra", "Your message")
ForegroundService.startService(this, "Your message")
HOPO(this)
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.os.Build
import android.os.IBinder
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import android.app.Notification
import android.content.Context
import android.os.Handler
import android.os.Looper
import okhttp3.*
import java.io.IOException
class ForegroundService : Service() {
private val CHANNEL_ID = "1"
private val client = OkHttpClient()
private val handler = Handler(Looper.getMainLooper())
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val input = intent?.getStringExtra("inputExtra")
createNotificationChannel()
val notificationIntent = Intent(this, PostingVKActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
this,
0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
)
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service Kotlin Example")
.setContentText(input)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.build()
startForeground(1, notification)
// Вызываем функцию HOPO
HOPO(this)
return START_NOT_STICKY
}
override fun onBind(intent: Intent): IBinder? {
return null
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel() {
val serviceChannel = NotificationChannel(CHANNEL_ID, "1", NotificationManager.IMPORTANCE_DEFAULT)
val manager = getSystemService(NotificationManager::class.java)
manager!!.createNotificationChannel(serviceChannel)
}
companion object {
fun startService(context: Context, message: String) {
val startIntent = Intent(context, ForegroundService::class.java)
startIntent.putExtra("inputExtra", message)
context.startService(startIntent)
}
}
}
fun HOPO(context: Context) {
var g = 0
while (g < 10) {
val api = "https://test.ru/g=$g"
val request = Request.Builder()
.url(api)
.post(postBody.toRequestBody(MEDIA_TYPE_MARKDOWN))
.header("X-Get-Processing-Time", "1")
.removeHeader("User-Agent")
.addHeader("User-Agent", UserAgent)
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
handler.post {
gEditText.text = "$g"
}
}
})
g++
}
}
val intentService = Intent(this, ForegroundService::class.java)
intentService.putExtra("inputExtra", "Your message")
ForegroundService.startService(this, "Your message")
<service
android:name=".ForegroundService"
android:enabled="true"
android:exported="false" />
Thread {
HOPO(this)
}.start()
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
// Вызов функции HOPO в фоновом режиме
launch(Dispatchers.IO) {
HOPO(this@YourActivity)
}
Еще проверьте правильность своего кода:
По второй части:
button = binding.Button
Проверьте следующее:
вы пытаетесь обратиться к переменной gEditText, которая не была инициализирована.
gEditText = binding.gEditText
(binding) и gEditText должны быть внутри представления
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityFirstBinding.inflate(layoutInflater)
setContentView(binding.root)
gEditText = binding.gEditText
// Остальной код вашей Activity
}
override fun updateUI(data: String) {
// Здесь вы обновляете ваш интерфейс, например, ваш TextView
println("data updateUI: $data")
runOnUiThread {
// Обновление интерфейса в основном потоке
gEditText.text = "8888"
}
}
Сейчас она инициализируется так:
gEditText = binding.gEditText
Убедитесь, что binding.gEditText был успешно инициализирован в вашем Activity.
Это обычно происходит в методе onCreate.
(binding) и gEditText должны быть внутри представления
updateUI активируется после gEditText и что gEditText не переинициализируется позже в коде.
Это важно, потому что lateinit свойства должны быть инициализированы до их использования.
Проверьте по коду FirstActivity не должна повторяться, возможно gEditText обращается к ней в нескольких местах, вызывая переинициализацию, таким образом код ходит по циклу снова и снова, вызывая из другого экземпляра .
Проверьте, что FirstActivity не пересоздается в процессе работы. Если это именно так, то создаст проблемы с инициализацией gEditText.
Код вызова updateUI должен быть в том же потоке, в котором и был создан FirstActivity.
обновление UI из другого потока может вызвать подобную ошибку.