forground服务在最小化应用程序上销毁

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

我正在开发一个运行良好的音频播放器应用程序,但是如果我最小化该应用程序会杀死我的前台服务,那么我将面临一个问题。我不知道为什么会这样,有人可以向我提出任何解决方案吗

MainActivity

import android.Manifest
import android.app.PendingIntent
import android.content.*
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.IBinder
import android.support.v4.media.MediaDescriptionCompat
import android.support.v4.media.MediaMetadataCompat
import android.support.v4.media.session.MediaSessionCompat
import android.text.Html
import android.util.Log
import android.view.WindowManager
import android.widget.SeekBar
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.brahmakumaris.fragment.*
import com.brahmakumaris.model.getDashboard.RecentSong
import com.brahmakumaris.service.MusicPlayerService
import com.brahmakumaris.service.MyService
import com.brahmakumaris.util.*
import com.google.android.exoplayer2.DefaultLoadControl
import com.google.android.exoplayer2.ExoPlaybackException
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
import com.google.android.exoplayer2.source.ConcatenatingMediaSource
import com.google.android.exoplayer2.source.ProgressiveMediaSource
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
import com.google.android.exoplayer2.ui.PlayerNotificationManager
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
import com.google.android.exoplayer2.util.Util
import kotlinx.android.synthetic.main.activity_main.*
import java.util.*
import kotlin.collections.ArrayList

class MainActivity : AppCompatActivity(), OnFragmentInteractionListener {

    override fun onFragmentInteraction(screen: String, model: RecentSong, songList: ArrayList<RecentSong>, position: Int) {
        MyLog.e(TAG, screen)
        when (screen) {
            getString(R.string.speakers) -> {
                bottom_navigation.selectedItemId = R.id.nav_speaker
                supportFragmentManager.switch(
                    newFrag = SpeakerPageFragment.newInstance(),
                    tag = getString(R.string.speakers)
                )
            }
            getString(R.string.classes) -> {
                bottom_navigation.selectedItemId = R.id.nav_class
                supportFragmentManager.switch(
                    newFrag = ClassesPageFragment.newInstance(),
                    tag = getString(R.string.classes)
                )
            }
            getString(R.string.songs) -> {
                bottom_navigation.selectedItemId = R.id.nav_song
                supportFragmentManager.switch(
                    newFrag = SongsPageFragment.newInstance(),
                    tag = getString(R.string.songs)
                )
            }
            getString(R.string.play_song) -> {
                if(!model.name.isNullOrBlank()) {
                    songPosition = position
                    mSongList = songList
                    MyLog.e(TAG, "======= ${getString(R.string.play_song)} ${model.name}")
                    isPlaying = false       // to start new song
                    // play song
                    if (!lnPlayer.isVisible) {
                        lnPlayer.isVisible = true
                    }

                    titleTxt.setHtmlText(model.name)

                    if(mBound) {
                        startService()
                        mMusicPlayerService.playSong(mSongList,songPosition)
                        media_button.setImageResource(R.drawable.ic_pause_black_24dp)
                    }
                    setPlayPause(!mMusicPlayerService.isPlaying())
                    initSeekBar()
                }
            }
            else -> {
            }
        }
    }
    private val TAG = javaClass.simpleName
    private var isPlaying = false
    private var mediaSource: ProgressiveMediaSource? = null
    // notification
    private lateinit var mediaSessionConnector: MediaSessionConnector
    private lateinit var mediaSession: MediaSessionCompat
    private lateinit var playerNotificationManager: PlayerNotificationManager

    private var handler: Handler? = null
    private val dashUrl = "http://www.panacherock.com/downloads/mp3/01_All_Tangled_Up.mp3"
    var mSongList: ArrayList<RecentSong> = ArrayList()
    var songPosition = 0


    val MESSAGE_KEY = "message_key"
    private lateinit var mMusicPlayerService:MusicPlayerService
    private lateinit var mPlayer: SimpleExoPlayer
    private var mBound = false

    private val mServiceConnection: ServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(componentName: ComponentName, iBinder: IBinder) {
            val binder = iBinder as MusicPlayerService.MyServiceBinder
            mMusicPlayerService = binder.getService()
            mPlayer = mMusicPlayerService.getPlayerInstance()!!
            mPlayer.addListener(playerListener)

            mBound = true
            MyLog.e(TAG,"onServiceConnected: ")
        }

        override fun onServiceDisconnected(componentName: ComponentName) {
            mBound = false
            MyLog.e(TAG,"onServiceDisconnected: ")  // calles only in rare case if service destroy unexpectedly
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        if (savedInstanceState == null) {

            supportFragmentManager.switch(
                newFrag = DashboardPageFragment.newInstance(),
                tag = getString(R.string.home)
            )
        }
        getIntentData()
        bottom_navigation.setOnNavigationItemSelectedListener { item ->
            hideKeybord()
            when(item.itemId) {
                R.id.nav_home -> {
                    checkFragment()
                    supportFragmentManager.switch(
                        newFrag = DashboardPageFragment.newInstance(),
                        tag = getString(R.string.home)
                    )
                    true
                }
                R.id.nav_song -> {
                    checkFragment()
                    supportFragmentManager.switch(
                        newFrag = SongsPageFragment.newInstance(),
                        tag = getString(R.string.songs)
                    )
                    true
                }
                R.id.nav_speaker -> {
                    checkFragment()
                    supportFragmentManager.switch(
                        newFrag = SpeakerPageFragment.newInstance(),
                        tag = getString(R.string.speakers)
                    )
                    true
                }
                R.id.nav_class -> {
                    checkFragment()
                    supportFragmentManager.switch(
                        newFrag = ClassesPageFragment.newInstance(),
                        tag = getString(R.string.classes)
                    )
                    true
                }
                R.id.nav_search -> {
                    checkFragment()
                    supportFragmentManager.switch(
                        newFrag = SearchPageFragment.newInstance(),
                        tag = getString(R.string.search)
                    )
                    true
                }
                else -> false
            }

        }

        bottom_navigation.setOnNavigationItemReselectedListener {  }    //disable reselection tab

        media_button.setOnClickListener {
           // startService()
            setPlayPause(!isPlaying)
        }

        imgClose.setOnClickListener {
            isPlaying = true       // to stop song
            playerNotificationManager.setPlayer(null)
            setPlayPause(!isPlaying)
            if (lnPlayer.isVisible) {
                lnPlayer.isVisible = false
            }
        }
    }

    private fun getIntentData() {
        if (intent!=null && intent.hasExtra("internet") && !intent.getBooleanExtra("internet", false)) {
            this.changeFragment(
                DownloadPageFragment.newInstance(), Constants.DOWNLOAD_TAG
            )
        }
    }



    private fun checkFragment() {
        val fragment = getSupportFragmentManager().findFragmentByTag(Constants.SUB_CATEGORY_TAG)
        if (fragment != null) {
            getSupportFragmentManager().beginTransaction().remove(fragment).commit()
        }
        val fragment2 = getSupportFragmentManager().findFragmentByTag(Constants.DOWNLOAD_TAG)
        if (fragment2 != null) {
            getSupportFragmentManager().beginTransaction().remove(fragment2).commit()
        }
    }

    private val playerListener by lazy {
        object : Player.EventListener {
            override fun onPlayerError(error: ExoPlaybackException) {
                super.onPlayerError(error)
                //onError(error)
            }

            override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
                super.onPlayerStateChanged(playWhenReady, playbackState)
                when (playbackState) {
                    Player.STATE_BUFFERING -> Log.e(TAG,"STATE_BUFFERING")
                    Player.STATE_ENDED -> Log.e(TAG,"STATE_ENDED")
                    Player.STATE_IDLE -> Log.e(TAG,"STATE_IDLE")
                    Player.STATE_READY -> {
//                        setPlayPause(playWhenReady)
                        isPlaying = playWhenReady
                        mPlayer.setPlayWhenReady(playWhenReady)
                        if (!isPlaying) {
                            media_button.setImageResource(R.drawable.ic_play_arrow_black_24dp)
                        } else {
                            setProgress()
                            media_button.setImageResource(R.drawable.ic_pause_black_24dp)
                        }
                        if (playWhenReady) {
                            Log.e(TAG, "PlaybackStatus.PLAYING")
                        } else {
                            Log.e(TAG, "PlaybackStatus.PAUSED")
                        }
                        titleTxt.setHtmlText(mSongList[mPlayer.currentWindowIndex].name)
                        MyLog.e(TAG, "====== " + mSongList[mPlayer.currentWindowIndex].name)
                        MyLog.e(TAG, "======111 " + mSongList[mPlayer.currentWindowIndex].descripation)
                    }
                    else -> Log.e(TAG, "PlaybackStatus.IDLE")
                }

            }
        }
    }

    private fun startService() {
        val myService = Intent(this, MusicPlayerService ::class.java)
        Util.startForegroundService(this,myService)
    }

    private fun stopService() {
        val myService = Intent(this, MusicPlayerService ::class.java)
        stopService(myService)
    }


    private fun setPlayPause(play: Boolean) {
        if(mBound) {
            if(mMusicPlayerService.isPlaying()) {
                mMusicPlayerService.pause()
                media_button.setImageResource(R.drawable.ic_play_arrow_black_24dp)
            } else {
                startService()
                playerNotificationManager = mMusicPlayerService.getNotificationInstance()!!
                /* if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                     startForegroundService(intent)
                 } else {
                     startService(intent)
                 }*/
                mMusicPlayerService.play()
                setProgress()
                media_button.setImageResource(R.drawable.ic_pause_black_24dp)
            }
        }

        /*isPlaying = play
        exoPlayer.setPlayWhenReady(play)
        if (!isPlaying) {
            media_button.setImageResource(R.drawable.ic_play_arrow_black_24dp)
        } else {
            setProgress()
            media_button.setImageResource(R.drawable.ic_pause_black_24dp)
        }*/
    }

    private fun stringForTime(timeMs: Int): String {
        val mFormatBuilder: StringBuilder
        val mFormatter: Formatter
        mFormatBuilder = StringBuilder()
        mFormatter = Formatter(mFormatBuilder, Locale.getDefault())
        val totalSeconds = timeMs / 1000

        val seconds = totalSeconds % 60
        val minutes = totalSeconds / 60 % 60
        val hours = totalSeconds / 3600

        mFormatBuilder.setLength(0)
        return if (hours > 0) {
            mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString()
        } else {
            mFormatter.format("%02d:%02d", minutes, seconds).toString()
        }
    }

    private fun setProgress() {
        seekPlayerProgress.progress = 0
        seekPlayerProgress.max = mPlayer.getDuration().toInt() / 1000
        position.setText(stringForTime(mPlayer.getCurrentPosition().toInt()))
        duration.setText(stringForTime(mPlayer.getDuration().toInt()))

        if (handler == null) handler = Handler()
        //Make sure you update Seekbar on UI thread
        handler!!.post(object : Runnable {
            override fun run() {
                if (mPlayer != null && ::mPlayer.isInitialized && isPlaying) {
                    seekPlayerProgress.max = mPlayer.getDuration().toInt() / 1000
                    val mCurrentPosition = mPlayer.getCurrentPosition().toInt() / 1000
                    seekPlayerProgress.progress = mCurrentPosition
                    position.setText(stringForTime(mPlayer.getCurrentPosition().toInt()))
                    duration.setText(stringForTime(mPlayer.getDuration().toInt()))

                    handler!!.postDelayed(this, 1000)
                }
            }
        })
    }

    private fun initSeekBar() {
        seekPlayerProgress.requestFocus()

        seekPlayerProgress.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
                if (!fromUser) {
                    // We're not interested in programmatically generated changes to
                    // the progress bar's position.
                    return
                }

                mPlayer.seekTo((progress * 1000).toLong())
            }

            override fun onStartTrackingTouch(seekBar: SeekBar) {

            }

            override fun onStopTrackingTouch(seekBar: SeekBar) {

            }
        })

        seekPlayerProgress.setMax(0)
        seekPlayerProgress.setMax(mPlayer.getDuration().toInt() / 1000)

    }

    private var doubleBackToExitPressedOnce = false

    override fun onBackPressed() {
        val fragment = getSupportFragmentManager().findFragmentByTag(Constants.SUB_CATEGORY_TAG)
        if (fragment != null) {
            getSupportFragmentManager().beginTransaction().remove(fragment).commit()
            return
        }
        val fragment2 = getSupportFragmentManager().findFragmentByTag(Constants.DOWNLOAD_TAG)
        if (fragment2 != null) {
            getSupportFragmentManager().beginTransaction().remove(fragment2).commit()
            return
        }
        if (doubleBackToExitPressedOnce) {
            super.onBackPressed()
            return
        }

        this.doubleBackToExitPressedOnce = true
        this.showSnackBarToast("Please click BACK again to exit")

        Handler().postDelayed(Runnable { doubleBackToExitPressedOnce = false }, 2000)
    }

    override fun onDestroy() {
        if(::playerNotificationManager.isInitialized) {
            playerNotificationManager.setPlayer(null)
        }
        killPlayer()
//        stopService()
        MyLog.e(TAG," #### onDestroy #### ")
        super.onDestroy()
    }

    override fun onStop() {
        super.onStop()
        if(mBound) {
            unbindService(mServiceConnection)
            mBound = false
        }
        LocalBroadcastManager.getInstance(this)
            .unregisterReceiver(broadCastReceiver)
        MyLog.e(TAG," #### onStop #### ")
    }

     private fun killPlayer() {
        if (mPlayer != null) {
            mPlayer.release()
            mediaSource = null
        }
         MyLog.e(TAG,"#### killPlayer ####")
    }


    private fun getHtmlText(str:String):String {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return (Html.fromHtml(str, Html.FROM_HTML_MODE_COMPACT)).toString()
        } else {
            return (Html.fromHtml(str)).toString()
        }
    }

    private fun setMediaSession() {
        mediaSession = MediaSessionCompat(this@MainActivity,"MEDIA_SESSION_TAG")
        mediaSession.isActive = true
        playerNotificationManager.setMediaSessionToken(mediaSession.sessionToken)   //enhance media stye notification and provide artwork in lock screen
        mediaSessionConnector = MediaSessionConnector(mediaSession)
        //timeline is the internal representation of the pllaylist after the player has been prepared
        mediaSessionConnector.setQueueNavigator(object : TimelineQueueNavigator(mediaSession){
            override fun getMediaDescription(player: Player?, windowIndex: Int): MediaDescriptionCompat {
                return getMediaDescriptionData(this@MainActivity, mSongList[windowIndex])
            }

        })
        mediaSessionConnector.setPlayer(exoPlayer/*, null*/)   //sync player wth media session

    }

    fun getMediaDescriptionData(context: Context, sample: RecentSong): MediaDescriptionCompat {
        val extras = Bundle()
        val options = BitmapFactory.Options()
        options.inSampleSize = 8

//        val bitmap = BitmapFactory.decodeFile(getBitmap(context, sample.bitmapResource), options)
        val bitmap = context.getBitmap(R.drawable.bg)

        extras.putParcelable(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bitmap)
        extras.putParcelable(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, bitmap)
        return MediaDescriptionCompat.Builder()
            .setMediaId(sample.song)
            .setIconBitmap(bitmap)
            .setTitle(sample.name)
            .setDescription(sample.descripation)
            .setExtras(extras)
            .build()
    }

    override fun onStart() {
        super.onStart()
        bindService(Intent(this,MusicPlayerService::class.java),mServiceConnection,Context.BIND_AUTO_CREATE)
        LocalBroadcastManager.getInstance(this)
            .registerReceiver(broadCastReceiver, IntentFilter(MusicPlayerService().MUSIC_COMPLETED))
    }

    val broadCastReceiver = object : BroadcastReceiver() {
        override fun onReceive(contxt: Context?, intent: Intent?) {
            MyLog.e(TAG,"onReceive: ${intent?.getBooleanExtra(MESSAGE_KEY,false)}")
            if(intent!!.getBooleanExtra(MESSAGE_KEY,false)) {
                setPlayPause(intent.getBooleanExtra(MESSAGE_KEY,false))
                if (intent.getBooleanExtra(MESSAGE_KEY,false)) {
                    Log.e(TAG, "PlaybackStatus.PLAYING")
                } else {
                    Log.e(TAG, "PlaybackStatus.PAUSED")
                }
                titleTxt.setHtmlText(mSongList[mPlayer.currentWindowIndex].name)
                MyLog.e(TAG,"====== "+mSongList[mPlayer.currentWindowIndex].name)
                MyLog.e(TAG,"======111 "+mSongList[mPlayer.currentWindowIndex].descripation)
            }

        }
    }
}

MusicPlayerService

import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Binder
import android.os.IBinder
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.brahmakumaris.MainActivity
import com.brahmakumaris.R
import com.brahmakumaris.model.getDashboard.RecentSong
import com.brahmakumaris.util.MyLog
import com.brahmakumaris.util.getBitmap
import com.brahmakumaris.util.getPlaintextfromHtmlHtmlText
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
import com.google.android.exoplayer2.source.ConcatenatingMediaSource
import com.google.android.exoplayer2.source.ProgressiveMediaSource
import com.google.android.exoplayer2.ui.PlayerNotificationManager
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
import com.google.android.exoplayer2.util.Util

class MusicPlayerService : Service() {
    private val TAG = javaClass.simpleName
    private val mContext: Context = this
    private val mBinder = MyServiceBinder()
    val MUSIC_COMPLETED = "music completed"
    val mPlayer: SimpleExoPlayer by lazy { SimpleExoPlayer.Builder(this).build() }
    private lateinit var playerNotificationManager: PlayerNotificationManager
    var mSongList: ArrayList<RecentSong> = ArrayList()

    override fun onCreate() {
        super.onCreate()
        MyLog.d(TAG,"onCreate: ")

    }

    fun playSong(mSongList: ArrayList<RecentSong> = ArrayList(), position: Int = 0)/* mContext: Context = this*/ {
        this.mSongList = mSongList
        val dataSourceFactory = DefaultDataSourceFactory(mContext, Util.getUserAgent(mContext,getString(R.string.app_name)))

        val concateMediaSource = ConcatenatingMediaSource()
        for (i in mSongList) {
            val mediaSource = ProgressiveMediaSource
                .Factory(
                    DefaultDataSourceFactory(mContext, dataSourceFactory),
                    DefaultExtractorsFactory()
                )
                .createMediaSource(/*i.uri*/Uri.parse(i.musicFile))
            concateMediaSource.addMediaSource(mediaSource)
        }

        mPlayer.prepare(concateMediaSource)
        mPlayer.seekToDefaultPosition(position)
        mPlayer.playWhenReady =true

        setNotification()
    }

    private fun setNotification() {
        playerNotificationManager = PlayerNotificationManager.createWithNotificationChannel(
            this,"channel_id",R.string.channelName,R.string.channelDescription,11,
            object : PlayerNotificationManager.MediaDescriptionAdapter{
                override fun createCurrentContentIntent(player: Player): PendingIntent? {
                    val intent = Intent(mContext, MainActivity::class.java)
                    return PendingIntent.getActivity(mContext,0,intent, PendingIntent.FLAG_UPDATE_CURRENT)
                }

                override fun getCurrentContentText(player: Player): String? {
//                    return mSongList[player.currentWindowIndex].descripation // descrption
                    return mSongList[player.currentWindowIndex].descripation.getPlaintextfromHtmlHtmlText() // descrption
                }

                override fun getCurrentContentTitle(player: Player): String {
//                    return mSongList[player.currentWindowIndex].name // title
                    return mSongList[player.currentWindowIndex].name.getPlaintextfromHtmlHtmlText()
                }

                override fun getCurrentLargeIcon(
                    player: Player,
                    callback: PlayerNotificationManager.BitmapCallback
                ): Bitmap? {
                    return mContext.getBitmap(R.drawable.bg)
                }

            } ,object : PlayerNotificationManager.NotificationListener {
             override fun onNotificationStarted(notificationId: Int, notification: Notification) {
                 startForeground(notificationId,notification)
             }
             override fun onNotificationPosted(notificationId: Int, notification: Notification, ongoing: Boolean) {
                 startForeground(notificationId,notification)
             }

             override fun onNotificationCancelled(notificationId: Int, dismissedByUser: Boolean) {
                 stopSelf()
             }

             override fun onNotificationCancelled(notificationId: Int) {
                 stopSelf()
             }
         }

        )

        //show hide button
        playerNotificationManager.setUseStopAction(false)  //stop song
        playerNotificationManager.setRewindIncrementMs(0)   //hide rewind button
        playerNotificationManager.setFastForwardIncrementMs(0)  //hide fast forward button
        playerNotificationManager.setPlayer(mPlayer)
    }


    inner class MyServiceBinder : Binder() {
        fun getService(): MusicPlayerService = this@MusicPlayerService
    }

    fun getPlayerInstance(): SimpleExoPlayer? {
        return mPlayer
    }

    fun getNotificationInstance(): PlayerNotificationManager? {
        return playerNotificationManager
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        MyLog.d(TAG,"onStartCommand: ")
        return START_NOT_STICKY
    }
    override fun onBind(intent: Intent?): IBinder? {
        MyLog.d(TAG,"onBind: ")
        return mBinder

    }

    override fun onUnbind(intent: Intent?): Boolean {
        MyLog.d(TAG,"onUnbind: ")
        return true
    }

    override fun onRebind(intent: Intent?) {
        MyLog.d(TAG,"onRebind: ")
        super.onRebind(intent)
    }
    override fun onDestroy() {
        MyLog.e(TAG,"onDestroy: ")
        super.onDestroy()
        mPlayer.release()
        if(::playerNotificationManager.isInitialized) {
            playerNotificationManager.setPlayer(null)
        }
    }

    // public client method
    fun isPlaying():Boolean {
        return mPlayer.isPlaying
    }

    fun play() {
        mPlayer.setPlayWhenReady(true)
    }

    fun pause() {
        mPlayer.setPlayWhenReady(false)
    }
}

[如果我最小化该应用程序,那么它将取消绑定打印,然后直接进入onDestroy为什么会发生这种情况,任何人都可以帮助我,

高度赞赏任何帮助。

android kotlin exoplayer background-service foreground-service
2个回答
0
投票

您应该将startForeground()与一个通知一起使用,以永不停止运行的Android服务。

startForeground(1, notification)

请看一下。https://robertohuertas.com/2019/06/29/android_foreground_services/

我希望这会对您有所帮助。


0
投票

我只是删除了onStop的取消绑定和注销的代码,并设置了onDestroy,它对我有用。

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