亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

應用程序關閉后,Android 服務不存在

應用程序關閉后,Android 服務不存在

郎朗坤 2022-07-20 16:33:36
我想要一個后臺服務,它會在應用程序關閉后保持活動狀態,并且在應用程序啟動時我可以再次綁定。為了進行測試,我將每次綁定到服務時計數器都會增加。所以理論上應用程序應該啟動,我將創建服務,然后綁定到它 -> 計數器應該向上移動。然后我關閉應用程序并再次按下綁定按鈕,它應該記錄一個“1”并再次向上移動計數器。但它沒有......每次我重新啟動應用程序并綁定到它時它都會顯示一個 0......這是我當前的測試 - 服務 - 類:package com.programm.testapp;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.util.Log;public class TestService extends Service {    /*     * Service Binder     */    private final IBinder iBinder = new TestService.LocalConnectionService();    public class LocalConnectionService extends Binder {        public TestService getService(){            return TestService.this;        }    }    /*     * Test var     * It should increase every time the app is started.     */    private int test;    @Override    public IBinder onBind(Intent intent) {        Log.d("mDEBUG", "Test: " + test);        test++;        return iBinder;    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        Log.d("mDEBUG", "Service: Start Command");        return START_STICKY;    }}
查看完整描述

1 回答

?
Qyouu

TA貢獻1786條經驗 獲得超11個贊

如果您主動關閉應用程序(通過從 Android 活動列表中關閉它),Android 很可能會終止您的服務。您可以在您的應用程序 Logcat 中看到這一點。唯一真正的解決方法是前臺服務。


此外,onBind不會在每次綁定到服務時調用。從Android 文檔:


您可以同時將多個客戶端連接到一個服務。但是,系統緩存了IBinder服務通信通道。換句話說,只有在第一個客戶端綁定時,系統才會調用服務的 onBind() 方法來生成 IBinder。然后系統將相同的 IBinder 傳遞給綁定到相同服務的所有其他客戶端,而無需再次調用 onBind()。


其次,僅調用 onStartCommand 并不意味著重新創建服務。在服務生命周期內可以多次調用。例如,每次調用 startService 時,都會執行 onStartCommand,但不一定要重新創建服務。


此外,您似乎在關閉活動時沒有取消綁定服務。這會使您的活動泄漏 ServiceConnection 并且您的應用程序崩潰。它將解釋為什么每次關閉并重新啟動應用程序時都會看到重新創建的服務。


嘗試在您的活動的 onPause 方法中添加取消綁定:


@Override

void onPause() {

    super.onPause()

    unbindService(this.serviceConnectino)

}

工作配置可能如下所示。它使用專用服務函數而不是 onBind 來實現計數器的遞增:


我的綁定服務.kt

package com.test


import android.app.Service

import android.content.Intent

import android.os.Binder

import android.os.IBinder

import android.util.Log


class MyBoundService : Service() {


    abstract class MyBinder: Binder() {

        abstract fun getService(): MyBoundService

    }


    val iBinder: MyBinder = object: MyBinder() {

        override fun getService(): MyBoundService {

            return this@MyBoundService

        }

    }


    private var counter = 0


    fun increment() {

        counter ++

        Log.i("MyBoundService", "Counter: ${counter}")

    }


    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {

        Log.i("MyBoundService", "startCommand");

        return super.onStartCommand(intent, flags, startId)

    }


    override fun onBind(p0: Intent?): IBinder? {

        counter++

        Log.i("MyBoundService", "Bound: ${counter}")

        return iBinder

    }


    override fun onUnbind(intent: Intent?): Boolean {

        Log.i("MyBoundService", "Unbound")

        return super.onUnbind(intent)

    }

}

MainActivity.kt

package com.test


import android.content.Intent

import android.support.v7.app.AppCompatActivity

import android.os.Bundle

import kotlinx.android.synthetic.main.activity_main.*

import android.content.ComponentName

import android.content.Context

import android.content.ServiceConnection

import android.os.IBinder

import android.util.Log

import com.test.MyBoundService


class MainActivity : AppCompatActivity() {



    private val serviceConnection: ServiceConnection = object: ServiceConnection {

        override fun onServiceDisconnected(p0: ComponentName?) {

            Log.i("MainActivity", "Service disconnected")

        }


        override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {

            Log.i("MainActivity", "Service connected")

            p1?.let {

                (p1 as MyBoundService.MyBinder).getService().increment()

            }

        }


    }


    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)


        btn_create.setOnClickListener {

            val i = Intent(this@MainActivity, MyBoundService::class.java)

            startService(i)

        }


        btn_bind.setOnClickListener {

            val i = Intent(this@MainActivity, MyBoundService::class.java)

            bindService(i, serviceConnection, Context.BIND_AUTO_CREATE)

        }

    }


    override fun onPause() {

        super.onPause()

        unbindService(serviceConnection)

    }

}


查看完整回答
反對 回復 2022-07-20
  • 1 回答
  • 0 關注
  • 137 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號