Java 如何在Android中取消异步任务
在我的应用程序中,我有2个Java 如何在Android中取消异步任务,java,android,android-asynctask,android-thread,Java,Android,Android Asynctask,Android Thread,在我的应用程序中,我有2个AsyncTask方法,我希望当活动转到onPause取消此AsyncTasks,并在onResume中从头开始 我在下面写代码,按下home按钮,应用程序转到暂停,然后从最近的应用程序中再次打开此应用程序 我的意思是呼叫onPause和onResume 但当应用程序再次运行时(从最近的应用程序运行),请在恢复时调用onResume,但不要从一开始就启动AsyncTask 我的代码: @Override protected void onResume() { s
AsyncTask
方法,我希望当活动
转到onPause
取消此AsyncTask
s,并在onResume
中从头开始我在下面写代码,按下home按钮,应用程序转到暂停,然后从最近的应用程序中再次打开此应用程序
我的意思是呼叫
onPause
和onResume
但当应用程序再次运行时(从最近的应用程序运行),请在恢复时调用
onResume
,但不要从一开始就启动AsyncTask
我的代码:
@Override
protected void onResume() {
super.onResume();
new Handler(getMainLooper()).postDelayed(() -> {
//Get compress or upload
if (bundle == null) {
//Get video from file
getLoadOriginalVideos();
testIsSendPlans = testId;
}
}, 500);
}
@Override
protected void onPause() {
super.onPause();
new GetOriginalVideosAsync().cancel(true);
new GetCompressedVideosAsync().cancel(true);
}
private void getLoadOriginalVideos() {
if (videoList.isEmpty()) {
File directory = new File(Environment.getExternalStorageDirectory() + File.separator + APPDIR);
ArrayList<File> filesList = new ArrayList<File>();
if (directory.isDirectory() && directory.exists()) {
filesList.addAll(Arrays.asList(getOriginalVideos(directory.listFiles())));
}
new GetOriginalVideosAsync().execute(filesList.toArray(new File[filesList.size()]));
}
}
@SuppressLint("StaticFieldLeak")
class GetOriginalVideosAsync extends AsyncTask<File[], Integer, ArrayList<Video>> {
File[] files;
ContentResolver resolver;
GetOriginalVideosAsync() {
resolver = context.getContentResolver();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected void onPostExecute(ArrayList<Video> videos) {
Collections.sort(videos, Collections.reverseOrder());
getLastOriginalVideo(addVideos(videos));
}
private ArrayList<Video> addVideos(ArrayList<Video> videos) {
return new ArrayList<>(videos);
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
@Override
protected ArrayList<Video> doInBackground(File[]... arg) {
files = arg[0];
for (File file : files) {
if (!file.isDirectory() && isVideoFile(file.getPath())) {
videoList.add(new Video(file.getName(), file, new Date(file.lastModified())));
}
}
return videoList;
}
}
@SuppressLint("StaticFieldLeak")
class GetCompressedVideosAsync extends AsyncTask<File[], Integer, ArrayList<Video>> {
File[] files;
ContentResolver resolver;
GetCompressedVideosAsync() {
resolver = context.getContentResolver();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected void onPostExecute(ArrayList<Video> videos) {
Collections.sort(videos, Collections.reverseOrder());
getLastCompressedVideo(addVideos(videos));
}
private ArrayList<Video> addVideos(ArrayList<Video> videos) {
return new ArrayList<>(videos);
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
@Override
protected ArrayList<Video> doInBackground(File[]... arg) {
files = arg[0];
for (File file : files) {
if (!file.isDirectory() && isVideoFile(file.getPath())) {
videoListCompressed.add(new Video(file.getName(), file, new Date(file.lastModified())));
}
}
return videoListCompressed;
}
}
@覆盖
受保护的void onResume(){
super.onResume();
新处理程序(getMainLooper()).postDelayed(()->{
//获取压缩或上载
if(bundle==null){
//从文件中获取视频
getLoadOriginalVideos();
testisendplans=testId;
}
}, 500);
}
@凌驾
受保护的void onPause(){
super.onPause();
新建GetOriginalVideosAsync().cancel(true);
新建GetCompressedVideosAsync().cancel(true);
}
私有void getLoadOriginalVideos(){
if(videoList.isEmpty()){
文件目录=新文件(Environment.getExternalStorageDirectory()+File.separator+APPDIR);
ArrayList fileList=新的ArrayList();
if(directory.isDirectory()&&directory.exists()){
addAll(Arrays.asList(getOriginalVideos(directory.listFiles()));
}
新的GetOriginalVideosAsync().execute(filesList.toArray(新文件[filesList.size()]);
}
}
@SuppressLint(“StaticFieldLeak”)
类GetOriginalVideosAsync扩展异步任务{
文件[]文件;
内容解析器;
GetOriginalVideosAsync(){
resolver=context.getContentResolver();
}
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
}
@凌驾
受保护的void onPostExecute(ArrayList视频){
Collections.sort(视频,Collections.reverseOrder());
getLastOriginalVideo(添加视频);
}
私人ArrayList添加视频(ArrayList视频){
返回新的ArrayList(视频);
}
@凌驾
受保护的void onProgressUpdate(整型…值){
super.onProgressUpdate(值);
}
@凌驾
受保护的ArrayList doInBackground(文件[]…arg){
files=arg[0];
用于(文件:文件){
如果(!file.isDirectory()&&isVideoFile(file.getPath()){
添加(新视频(file.getName(),文件,新日期(file.lastModified()));
}
}
返回视频列表;
}
}
@SuppressLint(“StaticFieldLeak”)
类GetCompressedVideosAsync扩展异步任务{
文件[]文件;
内容解析器;
GetCompressedVideosAsync(){
resolver=context.getContentResolver();
}
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
}
@凌驾
受保护的void onPostExecute(ArrayList视频){
Collections.sort(视频,Collections.reverseOrder());
getLastCompressedVideo(添加视频(视频));
}
私人ArrayList添加视频(ArrayList视频){
返回新的ArrayList(视频);
}
@凌驾
受保护的void onProgressUpdate(整型…值){
super.onProgressUpdate(值);
}
@凌驾
受保护的ArrayList doInBackground(文件[]…arg){
files=arg[0];
用于(文件:文件){
如果(!file.isDirectory()&&isVideoFile(file.getPath()){
videoListCompressed.add(新视频(file.getName()、文件、新日期(file.lastModified()));
}
}
返回压缩的视频列表;
}
}
当您取消异步任务时,如何修复它,并在
onResume
从头开始此AsyncTask
s?中取消异步任务。您的asyncTask将一直运行,直到doInBackGround()完成其工作
因此,对于您的GetOriginalVideosSync
,请在doInBackground
中执行此操作:
@Override
protected ArrayList<Video> doInBackground(File[]... arg) {
files = arg[0];
for (File file : files) {
//add this
if(isCancelled){
return null;
}
if (!file.isDirectory() && isVideoFile(file.getPath())) {
videoList.add(new Video(file.getName(), file, new Date(file.lastModified())));
}
}
return videoList;
}
@Override
protected ArrayList<Video> doInBackground(File[]... arg) {
files = arg[0];
for (File file : files) {
//add this
if(isCancelled){
return null;
}
if (!file.isDirectory() && isVideoFile(file.getPath())) {
videoListCompressed.add(new Video(file.getName(), file, new Date(file.lastModified())));
}
}
return videoListCompressed;
}
更新
在我告诉过你的同一个地方,在两个任务中都尝试以下方法:
if(isCancelled){
break;
}
更新2
看,您的Asynctak必须是活动的成员变量
class MyActivity extends ........{
private GetOriginalVideosAsync orginalTask;
private GetCompressedVideosAsync compressedTask;
.......
}
按如下方式调用暂停:
@Override
protected void onPause() {
orginalTask.cancel(true);
compressedTask.cancel(true);
super.onPause();
}
及
private void getLoadOriginalVideos(){
if(videoList.isEmpty()){
文件目录=新文件(Environment.getExternalStorageDirectory()+File.separator+APPDIR);
ArrayList fileList=新的ArrayList();
if(directory.isDirectory()&&directory.exists()){
addAll(Arrays.asList(getOriginalVideos(directory.listFiles()));
}
orginalTask=new GetOriginalVideosAsync();
execute(filesList.toArray(新文件[filesList.size()]);
}
}
通过调用cancel(布尔值),可以随时取消任务。调用此方法将导致对isCancelled()的后续调用返回true。调用此方法后,将在doInBackground(java.lang.Object[])返回后调用onCancelled(java.lang.Object),而不是onPostExecute(java.lang.Object)。为了确保尽快取消任务,您应该始终定期检查doInBackground(java.lang.Object[])中isCancelled()的返回值,如果可能的话(例如在循环中)
资料来源:
代码中存在的问题是创建一个新实例,而不是使用您创建的同一实例,您可以通过在类级别而不是在方法/块级别声明实例,使实例全局可访问
问题
...
new GetOriginalVideosAsync().execute(...)
new GetCompressedVideosAsync().execute(...)
...
super.onPause();
new GetOriginalVideosAsync().cancel(true);
new GetCompressedVideosAsync().cancel(true);
...
正确的方法
...
getOriginalVideosAsync = new GetOriginalVideosAsync(); // Declare this in class level
getOriginalVideosAsync.execute(...) // replace old execute code with the instance
getCompressedVideosAsync = new GetCompressedVideosAsync(); // Declare this in class level
getCompressedVideoAsync.execute(...) // replace old execute code with the instance
...
super.onPause();
getOriginalVideosAsync().cancel(true);
getCompressedVideosAsync().cancel(true);
...
请看一看“java全局变量与局部变量”,以便有更多的了解,希望解释有帮助,干杯。谢谢我的朋友,但请继续
...
getOriginalVideosAsync = new GetOriginalVideosAsync(); // Declare this in class level
getOriginalVideosAsync.execute(...) // replace old execute code with the instance
getCompressedVideosAsync = new GetCompressedVideosAsync(); // Declare this in class level
getCompressedVideoAsync.execute(...) // replace old execute code with the instance
...
super.onPause();
getOriginalVideosAsync().cancel(true);
getCompressedVideosAsync().cancel(true);
...