【问题标题】:Stop AsyncTask when app is closed关闭应用程序时停止 AsyncTask
【发布时间】:2018-07-17 00:35:36
【问题描述】:

我正在尝试创建一个使用AsynTask 在后台播放音乐的广播流应用程序,我的应用程序还有一个使用WallpaperService 的将 Gif 设置为动态壁纸功能。

我的问题

  1. 当我将一些 gif 设置为壁纸并尝试关闭应用程序时 从最近的任务或向左/向右滑动,我的应用程序仍然没有 播放音乐AsynTask 还在(doInBackground),我发现了一个问题 当AsynTask 结束时,音乐开始播放 即使我的应用程序已关闭,也可以在后台运行。

我想要什么

  1. 当我将一些 gif 设置为壁纸时,当我关闭我的应用程序时,我想 停止AsynTask

主活动:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        playerTask = new PlayerTask();
        playerTask.execute("URL_STREAM");

}

@Override
    protected void onDestroy() {
        super.onDestroy();
        MApplication.sBus.post(PlaybackEvent.CLOSE);
        try {
            MApplication.sBus.unregister(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

   @Subscribe
    public void handlePlaybackEvent(PlaybackEvent event) {
        switch (event) {
            case PAUSE:
                if (mediaPlayer.isPlaying()) {
                    mediaPlayer.pause();
                    MusicButton.setChecked(true);
                }
                break;
            case PLAY:
                if (!mediaPlayer.isPlaying()) {
                    mediaPlayer.start();
                    MusicButton.setChecked(false);
                }
                break;
            case CLOSE:
                MApplication.sBus.post(PlaybackEvent.PAUSE);
                NotificationManager nMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                assert n != null;
                n.cancelAll();
                playerTask.cancel(true);

    }

 @SuppressLint("StaticFieldLeak")
    public class PlayerTask extends AsyncTask<String, Void, Boolean> {
        ProgressBar loadingRL = findViewById(R.id.progressBar);

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                AudioAttributes attribs = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build();
                mediaPlayer.setAudioAttributes(attribs);

            } else {
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            }
            loadingRL.setVisibility(View.VISIBLE);
            beforradio.start();
        }

        @Override
        protected Boolean doInBackground(String... strings) {
             if(!isCancelled()){
            try {
                mediaPlayer.setDataSource(strings[0]);
                mediaPlayer.prepare();
                prepared = true;
            } catch (IOException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
                    mediaPlayer.start();

                }
            });
        }
            return prepared;
        }

        @Override
        protected void onPostExecute(Boolean aBoolean) {
            super.onPostExecute(aBoolean);
            MusicButton.setVisibility(View.VISIBLE);
            MusicButton.setChecked(true);
            loadingRL.setVisibility(View.GONE);
             /*get details : */
            Uri uri = Uri.parse(JsonData.NightWavePlazaRadioStream);
            OnNewMetadataListener ilistener = new OnNewMetadataListener() {
                @Override
                public void onNewHeaders(String stringUri, List<String> name, List<String> desc, List<String> br, List<String> genre, List<String> info) {
                }

                @Override
                public void onNewStreamTitle(String stringUri, String streamTitle) {
                    Animation a = AnimationUtils.loadAnimation(MainActivity.this, R.anim.textanim);
                    a.reset();
                    songinfo.setText("Song : " + streamTitle);
                    createNotification(getApplicationContext(), streamTitle, "notificationchannel", notificationManager);

                }
            };
            AudiostreamMetadataManager.getInstance()
                    .setUri(uri)
                    .setOnNewMetadataListener(ilistener)
                    .setUserAgent(UserAgent.WINDOWS_MEDIA_PLAYER)
                    .start();
            Rlsong.setVisibility(View.VISIBLE);
        }
    }

【问题讨论】:

  • 我也处理过这些问题,并通过使用服务而不是 asynctask 找到了自己的解决方案。
  • @statosdotcom 非常感谢您的评论,请您给我一些关于使用service 流式广播的教程或文档
  • AsyncTask 专为需要定期更新 UI 的短任务而构建。您应该寻找其他线程解决方案,例如 HandlerThread 或 IntentService。

标签: android service android-asynctask android-mediaplayer


【解决方案1】:

删除异步任务。由于您使用 asynctask 只是为了显示进度条。您可以在 onCreate() 中设置进度条 VISIBLE,然后在 mediaPlayer.setOnPreparedListener()

中将其设置为 GONE

【讨论】:

    【解决方案2】:

    没有“停止”异步任务。您在任务上调用取消,但在您的 doInBackground 代码中,您应该检查您的任务是否被取消,如果是,则中断。

    参考这里

    https://stackoverflow.com/a/6053943/599346

    【讨论】:

    • 非常感谢您的评论,但仍然无法正常工作,请查看我的新更新帖子
    • 您不需要异步任务来播放音乐,因此您通过添加异步任务来做不必要的工作。试图阻止它不会为你做任何事情。你应该使用prepareAsync() 然后你就不需要它了
    • 来自文档的For streams, you should call prepareAsync(), which returns immediately, rather than blocking until enough data has been buffered. developer.android.com/reference/android/media/…
    • 实际上我使用asynctask 只是为了在尚未播放音乐时显示progressbar。所以我在onPreExecute 中显示progressbar 并将其隐藏在onPostExecute 请如果我可以使用其他东西请告诉我
    【解决方案3】:

    您可以在 AsyncTasks doInBackground() 函数中调用 cancel(true)。为此,您可以在 AsyncTask 中保留一个布尔标志,并检查它是否在 doInBackgroundcancel(true) 中被取消。

    【讨论】:

    • 非常感谢您的评论,但仍然无效
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    • 2013-12-01
    相关资源
    最近更新 更多