【问题标题】:Music service crash on rotate旋转时音乐服务崩溃
【发布时间】:2019-02-01 19:16:55
【问题描述】:

我正在尝试将来自 create-a-music-player-on-android-song-playback 的代码合并到我的应用程序中,但服务在设备旋转时崩溃。

在活动中...

@Override
protected void onStart() {
    super.onStart();
    if (playIntent == null) {
        playIntent = new Intent(this, MusicService.class);
        bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
        startService(playIntent);
    }
}

@Override
protected void onStop() {
    stopPlay();
    musicSrv = null;
    playIntent = null;
    unbindService(musicConnection);
    super.onStop();
}

private void stopPlay() {
    if (musicSrv != null)
        musicSrv.stop();
}

在服务中... [在 onCreate 和 onDestroy 中添加更新以用于播放器的生命周期]

@Override
public void onCreate() {
    super.onCreate();
    songPosn = 0;
    player = new MediaPlayer();
    initMusicPlayer();
}

@Override
public void onDestroy() {
    player.stop();
    player.release();
    player = null;
    super.onDestroy();
}

public void initMusicPlayer(){
    // set player properties
    player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
    player.setAudioStreamType(AudioManager.STREAM_MUSIC);
    player.setOnPreparedListener(this);
    player.setOnCompletionListener(this);
    player.setOnErrorListener(this);
}


public void stop() {
    if (player != null)
        player.stop(); // << this line crashes after second rotation
}

public void playSong() {
    // play a song
    player.reset(); // << this line crashes after rotation and play
    Song playSong = songs.get(songPosn);
    long currSong = playSong.mId;
    Uri trackUri = playSong.getUri();

    try {
        player.setDataSource(getApplicationContext(), trackUri);
    }
    catch(Exception e) {
        Log.e("MUSIC SERVICE", "Error setting data source", e);
    }
    player.prepareAsync();
}

[更新添加 logcat]

2019-02-01 14:20:56.756 11217-11243/com.mycompany.myapp I/Adreno: Build Config                     : S L 4.0.10 AArch64
2019-02-01 14:20:56.760 11217-11243/com.mycompany.myapp I/Adreno: PFP: 0x005ff110, ME: 0x005ff066
2019-02-01 14:20:56.766 11217-11243/com.mycompany.myapp I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
2019-02-01 14:20:56.767 11217-11243/com.mycompany.myapp I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
2019-02-01 14:20:56.769 11217-11243/com.mycompany.myapp I/OpenGLRenderer: Initialized EGL, version 1.4
2019-02-01 14:20:56.769 11217-11243/com.mycompany.myapp D/OpenGLRenderer: Swap behavior 1
2019-02-01 14:20:56.889 11217-11217/com.mycompany.myapp D/CalRecycler: Calendar Count = 1
2019-02-01 14:20:56.890 11217-11217/com.mycompany.myapp I/chatty: uid=10204(com.mycompany.myapp) identical 1 line
2019-02-01 14:20:56.892 11217-11217/com.mycompany.myapp D/CalRecycler: Calendar Count = 1
2019-02-01 14:21:04.798 11217-11217/com.mycompany.myapp D/MusicService: onUnbind: 
2019-02-01 14:21:04.799 11217-11217/com.mycompany.myapp E/MediaPlayerNative: stop called in state 1, mPlayer(0x0)
2019-02-01 14:21:04.799 11217-11217/com.mycompany.myapp E/MediaPlayerNative: error (-38, 0)
2019-02-01 14:21:04.811 11217-11217/com.mycompany.myapp V/MediaPlayer: resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
2019-02-01 14:21:04.811 11217-11217/com.mycompany.myapp V/MediaPlayer: cleanDrmObj: mDrmObj=null mDrmSessionId=null
2019-02-01 14:21:04.944 11217-11217/com.mycompany.myapp I/Choreographer: Skipped 507 frames!  The application may be doing too much work on its main thread.
2019-02-01 14:21:05.072 11217-11243/com.mycompany.myapp I/OpenGLRenderer: Davey! duration=8590ms; Flags=0, IntendedVsync=626379375911582, Vsync=626387825911244, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=626387838413745, AnimationStart=626387838658172, PerformTraversalsStart=626387842406401, DrawStart=626387863394893, SyncQueued=626387940397609, SyncStart=626387940670057, IssueDrawCommandsStart=626387941099744, SwapBuffers=626387960066205, FrameCompleted=626387966297195, DequeueBufferDuration=409000, QueueBufferDuration=357000, 
2019-02-01 14:21:05.111 11217-11217/com.mycompany.myapp W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 14:21:15.280 11217-11217/com.mycompany.myapp D/MainActivity: onPause
2019-02-01 14:21:15.287 11217-11217/com.mycompany.myapp D/MainActivity: onStop
2019-02-01 14:21:15.288 11217-11217/com.mycompany.myapp D/AndroidRuntime: Shutting down VM
2019-02-01 14:21:15.306 11217-11217/com.mycompany.myapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mycompany.myapp, PID: 11217
java.lang.RuntimeException: Unable to stop activity {com.mycompany.myapp/com.mycompany.myapp.MainActivity}: java.lang.IllegalStateException
    at android.app.ActivityThread.callActivityOnStop(ActivityThread.java:4189)
    at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:4796)
    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4732)
    at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6718)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
 Caused by: java.lang.IllegalStateException
    at android.media.MediaPlayer._reset(Native Method)
    at android.media.MediaPlayer.reset(MediaPlayer.java:2178)
    at com.mycompany.myapp.util.MusicService.stop(MusicService.java:93)
    at com.mycompany.myapp.MainActivity.stopPlay(MainActivity.java:300)
    at com.mycompany.myapp.MainActivity.onStop(MainActivity.java:140)
    at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1432)
    at android.app.Activity.performStop(Activity.java:7375)
    at android.app.ActivityThread.callActivityOnStop(ActivityThread.java:4181)
    at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:4796) 
    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4732) 
    at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:193) 
    at android.app.ActivityThread.main(ActivityThread.java:6718) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 
2019-02-01 14:21:15.349 11217-11217/com.mycompany.myapp I/Process: Sending signal. PID: 11217 SIG: 9

我一直在查看有关 IllegalStateException 的几篇帖子,但我没有看到任何涉及轮换方面的帖子。我尝试将代码从onStart 移动到onResumeonStoponPause,但没有运气。奇怪的是,它在第​​一次旋转时工作,但在第二次旋转时崩溃。在第一次轮换中,我看到了E/MediaPlayerNative: stop called in state 1, mPlayer(0x0)E/MediaPlayerNative: error (-38, 0)。这发生在 onResume 之后,但此时它不会崩溃。如果我再次旋转它或尝试使用该服务并播放歌曲,它会崩溃。

[更新添加了抑制配置更改的尝试]

<application
    android:name=".util.App"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:theme="@style/AppTheme">

那没用。

有什么想法吗?有谁成功创建了自己的音乐服务?需要我的应用程序中的其他代码?顺便说一句 - 我正在使用一项服务,因为我也想从接收器中使用它。

TIA,迈克

【问题讨论】:

  • Android 会在 Activity 旋转时重新创建它,这可能是因为您尝试启动已停止的服务而导致其崩溃。也可能是您正在绑定已停止的服务。
  • 两次旋转之间经过了多长时间?
  • @ivan 我知道活动已被转储并重新创建。这就是我在活动中包含onStoponStart 代码的原因。可以看到我在onStop中解绑已有的,将playIntent设置为null,然后在onStart中新建一个。
  • @0X0nosugar 我只等了五秒钟左右,但在您发表评论后,我刚刚尝试了 30 次计数,但它仍然崩溃。
  • 那么我认为最好共享崩溃日志和更多服务代码(但尽可能少,我知道音频播放器代码可能会变得很长)。例如,我们看不到 player 的启动方式/位置。

标签: java android android-mediaplayer android-music-player


【解决方案1】:

为了摆脱重启问题只需将它放在清单中的activities props中并停止lifeCycle Restart issue android:configChanges="keyboardHidden|orientation|screenSize",那么你甚至不需要onStop 和 onDestroy 为你做点什么!

我的意思是 ActivityProp 。活动的开始标签 如下代码所示的属性

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:configChanges="orientation|screenSize|keyboard" <=== add like this
   >

      <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

</application>

有关配置更改的更多信息,请参阅此链接 https://developer.android.com/reference/android/app/Activity#ConfigurationChanges

【讨论】:

  • 此设置可防止它在旋转时崩溃,但仍然存在问题。我们从生命周期函数中删除了与服务相关的代码,但我仍然遇到了崩溃。当我退出应用程序并重新进入时,然后尝试玩...崩溃。 :(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-01
  • 1970-01-01
相关资源
最近更新 更多