如何解决来自服务 class 的“ANR 原因:执行服务”错误?

How to solve ' ANR Reason: executing service ' Error from service class?

我正在使用 IntentService 作为背景音乐。它不适用于 7.1 以上版本 (Nougat) devices.I 想在后台播放音乐,还想从应用程序 class 控制播放、暂停和停止操作。我的代码是..

申请class...

public class App extends Application {

    private Intent intent;

    @Override
    public void onCreate() {
        super.onCreate();

        OneSignal.setLogLevel(OneSignal.LOG_LEVEL.DEBUG, OneSignal.LOG_LEVEL.NONE);
        OneSignal.startInit(this)
                .inFocusDisplaying(OneSignal.OSInFocusDisplayOption.None)
                .setNotificationReceivedHandler(new OneSignalNotificationReceivedHandler())
                .setNotificationOpenedHandler(new OneSignalNotificationOpenedHandler(getApplicationContext()))
                .init();

        registerActivityLifecycleCallbacks(new MyActivityLifecycleCallbacks());
        intent = new Intent(App.this, BgSoundIntentServices.class);
        intent.setAction("");
        startService(intent);
    }


    private class MyActivityLifecycleCallbacks implements ActivityLifecycleCallbacks {

        private int numStarted = 0;

        public void onActivityCreated(Activity activity, Bundle bundle) {

            Log.e("APP",String.valueOf(appPrefDetails.getGameSound()));
            Log.e("APP",String.valueOf(activity.getLocalClassName()+" onActivityCreated"));
            if (appPrefDetails.getSound() && intent!=null) {
                if (activity.getLocalClassName().equalsIgnoreCase("Class1")) {
                    intent.setAction(BgSoundIntentServices.ACTION_PLAY);
                    startService(intent);
                }
            }
        }
        public void onActivityDestroyed(Activity activity) {

        }public void onActivityPaused(Activity activity) {

        }public void onActivityResumed(Activity activity) {

        }
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

        }
        public void onActivityStarted(Activity activity) {

        }
        public void onActivityStopped(Activity activity) {

        }
    }
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}

我的 Menifest 文件..

  <service
     android:name="com.example.music.sample.BgSoundIntentServices">
    </service>

BgSoundIntentServices 类...

public class BgSoundIntentServices extends IntentService {

    public static final String ACTION_PLAY = "com.example.music.action.ACTION_PLAY";
    public static final String ACTION_PAUSE = "com.example.music.action.ACTION_PAUSE";
    public static final String ACTION_FORCE_PAUSE = "com.example.music.action.ACTION_FORCE_PAUSE";
    public static final String ACTION_RESUME_PLAY = "com.example.music.action.ACTION_RESUME_PLAY";
    public static final String ACTION_STOP = "com.example.music.action.ACTION_STOP";
    public static final String ACTION_STOP_SERVICE = "com.example.music.action.STOP_SERVICE";

    private MediaPlayer player;
    private AudioManager audioManager;
    private Handler fadeOutHandler;
    private Handler fadeInHandler;
    private boolean FORCE_PAUSE;
//    private SharedPreferences pref;
    private AppPrefDetails prefDetails;

    public BgSoundIntentServices() {
        super(null);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {

//        System.out.println("ACTIVITY_CREATE " + intent.getAction());

    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {

        if (prefDetails==null){
            prefDetails=new AppPrefDetails(this);
        }
        if (intent != null && intent.getAction() != null) {
            String intentAction = intent.getAction();
            switch (intentAction) {
                case ACTION_PLAY:

                    Log.e("APP",String.valueOf("onStartCommand"+" ACTION_PLAY"));
                    if (player == null) {
                        requestAudioFocusForMyApp(this);
                        player = MediaPlayer.create(this, R.raw.app_bg);
                        player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                            @Override
                            public void onPrepared(MediaPlayer mp) {
                                Play();
                                player.setLooping(true);
                            }
                        });
                    }else {
                        Play();
                    }
                    break;
                case ACTION_PAUSE:
                    Log.e("APP",String.valueOf("onStartCommand"+" ACTION_PAUSE"));
                    Pause();
                    break;
                case ACTION_FORCE_PAUSE:
                    Log.e("APP",String.valueOf("onStartCommand"+" ACTION_FORCE_PAUSE"));
                    ForcePause();
                    break;
                case ACTION_RESUME_PLAY:
                    Log.e("APP",String.valueOf("onStartCommand"+" ACTION_RESUME_PLAY"));
                    ResumePlay();
                    break;
                case ACTION_STOP:
                    Log.e("APP",String.valueOf("onStartCommand"+" ACTION_STOP"));
                    StopPlayer();
                    break;
                case ACTION_STOP_SERVICE:
                    Log.e("APP",String.valueOf("onStartCommand"+" ACTION_STOP_SERVICE"));
                    StopService(intent);
                    break;
            }
        }
        return START_STICKY;
    }

    public void Play() {
        if (player != null && requestAudioFocusForMyApp(this)) {
            Log.e("APP",String.valueOf("onStartCommand"+" Play"));
//            player.start();
            FadeIn(player, 1000);
            FORCE_PAUSE = false;
        }
    }

    public void Pause() {
        if (player != null) {
            Log.e("APP",String.valueOf("onStartCommand"+" Pause"));
            FadeOut(player, 1000);
//           player.pause();
            FORCE_PAUSE = false;
        }
    }

    public void ForcePause() {
        if (fadeInHandler != null) {
            fadeInHandler.removeCallbacksAndMessages(null);
            fadeInHandler = null;
        }
        if (fadeOutHandler != null) {
            fadeOutHandler.removeCallbacksAndMessages(null);
            fadeOutHandler = null;
        }
        Log.e("APP",String.valueOf("onStartCommand"+" ForcePause"));
        player.pause();
        FORCE_PAUSE = true;

    }

    public void ResumePlay() {
        if (fadeInHandler != null) {
            fadeInHandler.removeCallbacksAndMessages(null);
            fadeInHandler = null;
        }
        if (fadeOutHandler != null) {
            fadeOutHandler.removeCallbacksAndMessages(null);
            fadeOutHandler = null;
        }
        if (player != null && FORCE_PAUSE) {
            Log.e("APP",String.valueOf("onStartCommand"+" ResumePlay"));
//            player.start();
            if (player.isPlaying()){
                player.pause();
            }
            FadeIn(player, 1000);
            FORCE_PAUSE = false;
        }
    }

    public void StopPlayer() {
        if (player != null) {
            if (player.isPlaying()) {
                Log.e("APP",String.valueOf("onStartCommand"+" StopPlayer"));
                player.stop();
                player.release();
                player = null;
            } else {
                Log.e("APP",String.valueOf("onStartCommand"+" StopPlayerRelease"));
                player.release();
                player = null;
            }
        }
        releaseAudioFocusForMyApp(this);
    }

    public void StopService(Intent intent) {
        Log.e("APP",String.valueOf("onStartCommand"+" StopService"));
        if (fadeInHandler != null) {
            fadeInHandler.removeCallbacksAndMessages(null);
            fadeInHandler = null;
        }
        if (fadeOutHandler != null) {
            fadeOutHandler.removeCallbacksAndMessages(null);
            fadeOutHandler = null;
        }
        stopService(intent);
        releaseAudioFocusForMyApp(this);
    }

    public void FadeOut(final MediaPlayer player, final int duration) {
        final float deviceVolume = getDeviceVolume();
        if (fadeOutHandler != null) {
            fadeOutHandler.removeCallbacksAndMessages(null);
            fadeOutHandler = null;
        }
        if (fadeInHandler != null) {
            fadeInHandler.removeCallbacksAndMessages(null);
            fadeInHandler = null;
        }
        fadeOutHandler = new Handler();
        fadeOutHandler.postDelayed(new Runnable() {
            private float time = duration;
            private float volume = 0.0f;

            @Override
            public void run() {
                if (!player.isPlaying())
                    player.start();
                // can call h again after work!
                time -= 100;
                volume = (deviceVolume * time) / duration;
                player.setVolume(volume, volume);
                if (time > 0)
                    fadeOutHandler.postDelayed(this, 100);
                else {
                    player.pause();
//                    _player.release();
                    fadeOutHandler.removeCallbacksAndMessages(null);
                }
            }
        }, 100); // 1 second delay (takes millis)


    }

    public void FadeIn(final MediaPlayer player, final int duration) {
        final float deviceVolume = getDeviceVolume();
        if (fadeInHandler != null) {
            fadeInHandler.removeCallbacksAndMessages(null);
            fadeInHandler = null;
        }
        if (fadeOutHandler != null) {
            fadeOutHandler.removeCallbacksAndMessages(null);
            fadeOutHandler = null;
        }
        fadeInHandler = new Handler();
        fadeInHandler.postDelayed(new Runnable() {
            private float time = 0.0f;
            private float volume = 0.0f;

            @Override
            public void run() {
                if (!player.isPlaying())
                    player.start();
                // can call h again after work!
                time += 100;
                volume = (deviceVolume * time) / duration;
                player.setVolume(volume, volume);
                if (time < duration) {
                    fadeInHandler.postDelayed(this, 100);
                } else {
                    fadeInHandler.removeCallbacksAndMessages(null);
                }
            }
        }, 100); // 1 second delay (takes millis)

    }

    public float getDeviceVolume() {
        int volumeLevel = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

        return (float) volumeLevel / maxVolume;
    }


    AudioManager.OnAudioFocusChangeListener focusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
        public void onAudioFocusChange(int focusChange) {

            switch (focusChange) {
                case AudioManager.AUDIOFOCUS_GAIN:  //RETURN TO CUT THE CALL
//                    Log.i("AUDIOFOCUS", "AUDIOFOCUS_GAIN");
                    if (prefDetails.getSound() && player != null && !App.AppIsBackground() && FORCE_PAUSE) {
                        ResumePlay();
                    }
                    break;
                case AudioManager.AUDIOFOCUS_LOSS:  //OTHER MEDIYA FOCUS
//                    Log.e("AUDIOFOCUS", "AUDIOFOCUS_LOSS");

                    break;
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: //CALL FOCUS
//                    Log.e("AUDIOFOCUS", "AUDIOFOCUS_LOSS_TRANSIENT");
                    if (prefDetails.getSound() && player != null && !App.AppIsBackground()) {
                        ForcePause();
                    }
                    break;
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
//                    Log.e("AUDIOFOCUS", "AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK");
                    // Lower the volume
                    break;
                case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
//                    Log.i("AUDIOFOCUS", "AUDIOFOCUS_GAIN_TRANSIENT");
                    break;
                case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
//                    Log.i("AUDIOFOCUS", "AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK");
                    // Play over existing audio
                    break;
            }
        }
    };



    private boolean requestAudioFocusForMyApp(Context context) {
        audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

        // Request audio focus for playback
        int result = audioManager.requestAudioFocus(focusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);

        if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
            return true;
        } else {
            return false;
        }
    }

    void releaseAudioFocusForMyApp(final Context context) {
        AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        am.abandonAudioFocus(focusChangeListener);
    }
}

当我进行调试构建时,它显示以下错误,应用未打开,显示应用未响应..

06-06 16:15:34.546 1772-1787/? E/ActivityManager: ANR in com.example.music
PID: 14500
Reason: executing service com.example.music/.sample.BgSoundIntentServices
Load: 5.74 / 5.4 / 5.26
CPU usage from 92145ms to 0ms ago (2018-06-06 16:13:59.644 to 2018-06-06 16:15:31.789):
  22% 1772/system_server: 13% user + 8.4% kernel / faults: 62105 minor 2 major
  3.7% 559/surfaceflinger: 1.7% user + 2% kernel / faults: 509 minor
  2.8% 3576/com.google.android.gms: 2.1% user + 0.7% kernel / faults: 12127 minor 37 major
  2.8% 456/logd: 1.1% user + 1.7% kernel / faults: 194 minor
  2.2% 3170/com.google.android.gms.persistent: 1.6% user + 0.5% kernel / faults: 6125 minor 13 major
  1.6% 14698/adbd: 0.5% user + 1.1% kernel / faults: 6005 minor
  1% 1436/mediaserver: 0.7% user + 0.3% kernel / faults: 49 minor
  1% 9989/kworker/u16:3: 0% user + 1% kernel
  0.4% 31702/com.android.vending: 0.3% user + 0.1% kernel / faults: 9114 minor 2 major
  0.9% 2599/com.android.systemui: 0.7% user + 0.1% kernel / faults: 3251 minor 1 major
  0.8% 11841/kworker/u16:4: 0% user + 0.8% kernel
  0.8% 358/mmc-cmdqd/0: 0% user + 0.8% kernel
  0.6% 10236/kworker/u16:8: 0% user + 0.6% kernel
  0.5% 540/healthd: 0% user + 0.5% kernel / faults: 1 minor
  0.5% 9914/logcat: 0.3% user + 0.1% kernel / faults: 40 minor
  0.4% 3356/com.miui.whetstone: 0.3% user + 0.1% kernel / faults: 962 minor 2 major
  0.3% 699/jbd2/dm-1-8: 0% user + 0.3% kernel
  0.4% 1437/netd: 0.1% user + 0.3% kernel / faults: 3666 minor
  0.1% 1432/zygote64: 0% user + 0.1% kernel / faults: 4816 minor
  0.3% 3435/com.miui.home: 0.2% user + 0% kernel / faults: 3933 minor
  0.4% 3453/com.miui.securitycenter.remote: 0.3% user + 0% kernel / faults: 3454 minor 2 major
  0.4% 2880/com.android.phone: 0.2% user + 0.1% kernel / faults: 726 minor 1 major
  0.3% 12250/kworker/u16:2: 0% user + 0.3% kernel
  0.3% 7479/mdss_fb0: 0% user + 0.3% kernel
  0.3% 8667/com.microsoft.office.outlook: 0.1% user + 0.1% kernel / faults: 1031 minor 1 major
  0.3% 558/servicemanager: 0.1% user + 0.1% kernel / faults: 47 minor
  0.2% 3862/com.miui.powerkeeper:service: 0.1% user + 0.1% kernel / faults: 878 minor 3 major
  0.2% 17441/com.xiaomi.discover: 0.2% user + 0% kernel / faults: 4426 minor
  0.1% 109/system: 0% user + 0.1% kernel
  0% 177/kswapd0: 0% user + 0% kernel
  0.2% 877/msm_irqbalance: 0% user + 0.2% kernel / faults: 45 minor
  0% 15941/com.lenovo.anyshare.gps:mobi: 0% user + 0% kernel / faults: 1659 minor 7 major
  0.1% 346/cfinteractive: 0% user + 0.1% kernel
  0% 12503/kworker/4:0: 0% user + 0% kernel
  0.1% 7/rcu_preempt: 0% user + 0.1% kernel
  0.1% 39/rcuop/4: 0% user + 0.1% kernel
  0% 1433/zygote: 0% user + 0% kernel / faults: 2177 minor
  0.1% 29599/VosTXThread: 0% user + 0.1% kernel
  0.1% 422/ueventd: 0.1% user + 0% kernel
  0.1% 53/rcuop/6: 0% user + 0.1% kernel
  0.1% 10/rcuop/0: 0% user + 0.1% kernel
  0.1% 3304/com.miui.daemon: 0% user + 0% kernel / faults: 450 minor
  0.1% 36/ksoftirqd/4: 0% user + 0.1% kernel
  0.1% 557/lmkd: 0% user + 0.1% kernel / faults: 25 minor
  0% 3757/com.lbe.security.miui: 0% user + 0% kernel / faults: 1300 minor
  0.1% 12977/kworker/5:1: 0% user + 0.1% kernel
  0.1% 29600/VosRXThread: 0% user + 0.1% kernel
  0.1% 13010/kworker/0:0: 0% user + 0.1% kernel
  0% 46/rcuop/5: 0% user + 0% kernel
  0% 25/rcuop/2: 0% user + 0% kernel
  0% 740/rild: 0% user + 0% kernel / faults: 534 minor
  0% 3087/mcd: 0% user + 0% kernel / faults: 32 minor
  0% 3/ksoftirqd/0: 0% user + 0% kernel
  0% 8/rcu_sched: 0% user + 0% kernel
  0% 43/ksoftirqd/5: 0% user + 0% kernel
  0% 3149/com.xiaomi.xmsf: 0% user + 0% kernel / faults: 482 minor
  0% 29607/wpa_supplicant: 0% user + 0% kernel / faults: 33 minor
  0% 18/rcuop/1: 0% user + 0% kernel
  0% 50/ksoftirqd/6: 0% user + 0% kernel
  0% 60/rcuop/7: 0% user + 0% kernel
  0% 210/hwrng: 0% user + 0% kernel
  0% 543/rmt_storage: 0% user + 0% kernel / faults: 38 minor
  0% 1434/audioserver: 0% user + 0% kernel / faults: 96 minor
  0% 2860/.dataservices: 0% user + 0% kernel / faults: 163 minor
  0% 3106/irq/180-408000.: 0% user + 0% kernel
  0% 1142

请任何人帮助我..

提前致谢..

感谢错误会修复,

错误是,应用程序 class 正在创建多次,因此 Intent 将创建多次,因此只显示此 ANR 错误。

现在只是在创建之前检查 intent 等于 null,它工作正常。

喜欢,

if(intent==null){
    intent = new Intent(App.this, BgSoundIntentServices.class);
    intent.setAction("");
    startService(intent);
}

它对我有用。

谢谢。