Android 如何检查异步任务是否已在运行

Android 如何检查异步任务是否已在运行,android,android-asynctask,Android,Android Asynctask,我有一个应用程序,需要在启动时进行密集的数据库操作。该应用程序在手机上保存联系人的本地副本,并在启动时与android联系人数据库同步 如果用户启动应用程序,则会启动一个异步任务,在后台同步数据库。如果用户关闭应用程序,操作将继续运行,这是正常的。但是,如果用户再次打开应用程序,则会启动异步任务并产生错误 是否有方法检查任务是否已从应用程序的其他实例运行?用于获取异步任务的状态。如果状态为,则您的任务正在运行 编辑:您应该重新考虑您的实现,并在服务或IntentService中保留异步任务,以从

我有一个应用程序,需要在启动时进行密集的数据库操作。该应用程序在手机上保存联系人的本地副本,并在启动时与android联系人数据库同步

如果用户启动应用程序,则会启动一个异步任务,在后台同步数据库。如果用户关闭应用程序,操作将继续运行,这是正常的。但是,如果用户再次打开应用程序,则会启动异步任务并产生错误

是否有方法检查任务是否已从应用程序的其他实例运行?

用于获取
异步任务的状态。如果状态为,则您的任务正在运行


编辑:您应该重新考虑您的实现,并在
服务
IntentService
中保留
异步任务
,以从web获取数据。

我认为您应该在
Android
中检查
应用程序
的概念。

事实上,世上没有

应用程序的不同实例

。对于所有
活动/服务,
应用程序始终相同。
这意味着您离开了
活动
并再次打开它,可能有两种情况:

  • 系统已终止您的应用程序。在这种情况下,
    AsyncTask
    已经失效,可以安全地启动一个新任务
  • 应用程序
    仍处于活动状态,因此
    异步任务
    可能仍在运行
  • 在第二种情况下,我建议使用一些静态变量,指向这个
    AsyncTask
    或它的状态。如果你的应用程序在第二次打开时仍处于活动状态-所有静态引用仍然有效,因此你可以成功操作

    顺便说一下,在当前的方法中,请注意您的应用程序可以随时被系统终止。因此,
    AsyncTask
    可以随时中断。这不适合您-请检查专门为后台操作设计的
    IntentServices
    -组件


    祝你好运

    我用某种单例模式处理了这个问题。 希望能有帮助

    // fill the places database from a JSON object
    public class myAsyncTask extends AsyncTask<Void,Integer,Integer> {
    
        Activity mContext = null;
        static AsyncTask<Void,Integer,Integer> myAsyncTaskInstance = null; 
    
        // Private Constructor: can't be called from outside this class
        private myAsyncTask(Activity iContext) {
            mContext = iContext; 
        }
    
        public static AsyncTask<Void, Integer, Integer> getInstance(Activity iContext) {
            // if the current async task is already running, return null: no new async task 
            // shall be created if an instance is already running
            if (myAsyncTaskInstance != null && myAsyncTaskInstance.getStatus() == Status.RUNNING) {
                // it can be running but cancelled, in that case, return a new instance
                if (myAsyncTaskInstance.isCancelled()) {
                    myAsyncTaskInstance = new myAsyncTask(iContext);
                } else {
                    // display a toast to say "try later"
                    Toast.makeText(iContext, "A task is already running, try later", Toast.LENGTH_SHORT).show();    
    
                    return null;
                }
            }
    
            //if the current async task is pending, it can be executed return this instance
            if (myAsyncTaskInstance != null && myAsyncTaskInstance.getStatus() == Status.PENDING) {
                return myAsyncTaskInstance;
            }
    
            //if the current async task is finished, it can't be executed another time, so return a new instance
            if (myAsyncTaskInstance != null && myAsyncTaskInstance.getStatus() == Status.FINISHED) {
                myAsyncTaskInstance = new myAsyncTask(iContext);
            }
    
    
            // if the current async task is null, create a new instance
            if (myAsyncTaskInstance == null) {
                myAsyncTaskInstance = new myAsyncTask(iContext);
            }
            // return the current instance
            return myAsyncTaskInstance;
        }
    
        @Override
        protected Integer doInBackground(Void... iUnUsed) {
            // ...
        }
    }
    
    //从JSON对象填充places数据库
    公共类myAsyncTask扩展了AsyncTask{
    活动mContext=null;
    静态AsyncTask myAsyncTaskInstance=null;
    //私有构造函数:不能从此类外部调用
    私有myAsyncTask(活动iContext){
    mContext=iContext;
    }
    公共静态异步任务getInstance(活动iContext){
    //如果当前异步任务已在运行,则返回null:无新异步任务
    //如果实例已在运行,则应创建
    if(myAsyncTaskInstance!=null&&myAsyncTaskInstance.getStatus()==Status.RUNNING){
    //它可以运行但被取消,在这种情况下,返回一个新实例
    if(myAsyncTaskInstance.isCancelled()){
    myAsyncTaskInstance=新的myAsyncTask(iContext);
    }否则{
    //展示祝酒词,说“稍后再试”
    Toast.makeText(iContext,“任务已在运行,请稍后再试”,Toast.LENGTH_SHORT.show();
    返回null;
    }
    }
    //如果当前异步任务处于挂起状态,则可以执行该任务并返回此实例
    if(myAsyncTaskInstance!=null&&myAsyncTaskInstance.getStatus()==Status.PENDING){
    返回myAsyncTaskInstance;
    }
    //如果当前异步任务已完成,则下次无法执行,因此返回一个新实例
    if(myAsyncTaskInstance!=null&&myAsyncTaskInstance.getStatus()==Status.FINISHED){
    myAsyncTaskInstance=新的myAsyncTask(iContext);
    }
    //如果当前异步任务为空,则创建一个新实例
    if(myAsyncTaskInstance==null){
    myAsyncTaskInstance=新的myAsyncTask(iContext);
    }
    //返回当前实例
    返回myAsyncTaskInstance;
    }
    @凌驾
    受保护的整数doInBackground(无效…已使用){
    // ...
    }
    }
    
    是的,没错,这些就是一些例子

    LoadMusicInBackground lmib = new LoadMusicInBackground();
    
    if(lmib.getStatus() == AsyncTask.Status.PENDING){
        // My AsyncTask has not started yet
    }
    
    if(lmib.getStatus() == AsyncTask.Status.RUNNING){
        // My AsyncTask is currently doing work in doInBackground()
    }
    
    if(lmib.getStatus() == AsyncTask.Status.FINISHED){
        // My AsyncTask is done and onPostExecute was called
    }
    

    应用程序级别的静态变量似乎就是这样。缩放getStatus()导致空指针异常,但我可以看到异步任务仍在运行。您是否使用了类似以下内容:
    (yourtask.getStatus()==AsyncTask.Status.running)
    ?这应该是答案。不需要使用intent service的asynctask,因为intent service已经有工作线程。感谢您的快速解释产生了什么错误?我的AsyncTask只是挂在preExecute上,所以我想知道它是否相关。