关闭应用程序时停止 AsyncTask
Posted
技术标签:
【中文标题】关闭应用程序时停止 AsyncTask【英文标题】:Stop AsyncTask when app is closed 【发布时间】:2018-07-17 00:35:36 【问题描述】:我正在尝试创建一个使用AsynTask
在后台播放音乐的广播流应用程序,我的应用程序还有一个使用WallpaperService
的将 Gif 设置为动态壁纸功能。
我的问题
-
当我将一些 gif 设置为壁纸并尝试关闭应用程序时
从最近的任务或向左/向右滑动,我的应用程序仍然没有
播放音乐
AsynTask
还在(doInBackground
),我发现了一个问题
当AsynTask
结束时,音乐开始播放
即使我的应用程序已关闭,也可以在后台运行。
我想要什么
-
当我将一些 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。
【参考方案1】:
删除异步任务。由于您使用 asynctask 只是为了显示进度条。您可以在 onCreate() 中设置进度条 VISIBLE,然后在 mediaPlayer.setOnPreparedListener()
中将其设置为 GONE【讨论】:
【参考方案2】:没有“停止”异步任务。您在任务上调用取消,但在您的 doInBackground
代码中,您应该检查您的任务是否被取消,如果是,则中断。
参考这里
https://***.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】:
您可以在 AsyncTask
s doInBackground()
函数中调用 cancel(true)
。为此,您可以在 AsyncTask
中保留一个布尔标志,并检查它是否在 doInBackground
和 cancel(true)
中被取消。
【讨论】:
非常感谢您的评论,但仍然无效以上是关于关闭应用程序时停止 AsyncTask的主要内容,如果未能解决你的问题,请参考以下文章