Android:获取Asynctask的状态并等待

Android:获取Asynctask的状态并等待,android,android-asynctask,Android,Android Asynctask,我正在使用Asynctask从设备加载所有联系人。尽管已经讨论过很多次了,Contacts.Contract确实很慢,我需要10-15秒才能加载所有带有图像的联系人数据和所有其他数据,如电子邮件等。所以我决定在启动屏幕上启动一个带有asynctask的服务。 现在的问题是 我有活动系列A-B-C-D Asynctask在活动A中启动,我希望在活动D中加载联系人。如果在用户到达活动D之前加载所有联系人,则其为ok。但若用户到达活动D并且服务仍在运行,那个么我需要让用户等待 所以我的问题是如何在活动

我正在使用Asynctask从设备加载所有联系人。尽管已经讨论过很多次了,Contacts.Contract确实很慢,我需要10-15秒才能加载所有带有图像的联系人数据和所有其他数据,如电子邮件等。所以我决定在启动屏幕上启动一个带有asynctask的服务。 现在的问题是 我有活动系列A-B-C-D Asynctask在活动A中启动,我希望在活动D中加载联系人。如果在用户到达活动D之前加载所有联系人,则其为ok。但若用户到达活动D并且服务仍在运行,那个么我需要让用户等待

所以我的问题是如何在活动D中等待ASYNCTASK完成。我将在活动D中显示一个简单的进度条,直到ASYNCTASK完成。但是怎么做呢


要等待AsyncTask完成,可以使用get()方法。 从get()方法的文档中:

如有必要,等待计算完成,然后检索 它的结果

但这将使主线程等待异步任务的结果

另一种方法是,您可以在异步任务中显示进度对话框,直到它完成。通过这种方式,您可以获得呼叫状态:

task.getStatus() == Status.RUNNING
如果状态为
status.RUNNING
,则只显示进度对话框,直到完成。例如:

    final AsyncTask task = MyAsyncTask.getInstance();

    final Thread waitingThread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                // ...
                // show progress dialog
                while(task.getStatus() != Status.FINISHED) {
                    TimeUnit.SECONDS.sleep(1);
                }
                result = task.get();
                // ...
                // hide progress dialog
            } catch (InterruptedException e) {
                // TODO log
            }
        }
    });

    waitingThread.start();
任务
对象是您的异步任务。您可以将其设置为单例并在活动A中启动,然后在活动D中获取它的实例

public class MyAsyncTask extends AsyncTask<Void, Void, Void>{

        private static MyAsyncTask instance;

        private MyAsyncTask(){}

        public static MyAsyncTask getInstance() {
            // check status if we want to execute it again
            if (instance == null) {
                instance = new MyAsyncTask();
            } else if (instance.getStatus() == Status.FINISHED) {
                instance = new MyAsyncTask();
            }

            return instance;
        }

        @Override
        protected Void doInBackground(Void... params) {
            // do smth
            return null;
        }
}
公共类MyAsyncTask扩展了AsyncTask{
私有静态MyAsyncTask实例;
私有MyAsyncTask(){}
公共静态MyAsyncTask getInstance(){
//如果要再次执行,请检查状态
if(实例==null){
实例=新的MyAsyncTask();
}else if(instance.getStatus()==Status.FINISHED){
实例=新的MyAsyncTask();
}
返回实例;
}
@凌驾
受保护的Void doInBackground(Void…参数){
//做smth
返回null;
}
}
我还没有尝试过这个方法,但我认为它会起作用。

你可以这样做

myAsyn asyn = new myAsyn();
asyn.execute();

while(asyn.getStatus()!=Aynctask.Status.Finished)
{
Thread.sleep(100);
}
无需等待asyntask完成,只需显示进度对话框即可。

public class myAsyn extends AsyncTask<Void, Void, Void>{


    private ProgressDialog dialog;

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        dialog = new ProgressDialog(context);
        dialog.setMessage("Loading...");
        dialog.setCanceledOnTouchOutside(false);
        dialog.show();
    }

    @Override
    protected Void doInBackground(String... arg0) {
        // TODO Auto-generated method stub
        //do your work
    }

    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        dialog.dismiss();
      }
     }
公共类myAsyn扩展异步任务{
私人对话;
@凌驾
受保护的void onPreExecute(){
//TODO自动生成的方法存根
super.onPreExecute();
dialog=新建进度对话框(上下文);
setMessage(“加载…”);
对话框。setCanceledOnTouchOutside(false);
dialog.show();
}
@凌驾
受保护的Void doInBackground(字符串…arg0){
//TODO自动生成的方法存根
//做你的工作
}
@凌驾
受保护的void onPostExecute(void结果){
//TODO自动生成的方法存根
super.onPostExecute(结果);
dialog.dismise();
}
}

我会解释得很简单

您可以获得异步任务的状态…如下所示

if (o2.getStatus() == Status.FINISHED) { ////o2 is a asynch task instance...

} else if (o2.getStatus() == Status.RUNNING) {

} else if (o2.getStatus() == Status.PENDING) {

}
请试试这个

public class LoadData extends AsyncTask<Void, Void, Void> {
    ProgressDialog progressDialog;
    //declare other objects as per your need
    @Override
    protected void onPreExecute()
    {
        progressDialog= ProgressDialog.show(YourActivity.this, "Progress Dialog Title Text","Process Description Text", true);

        //do initialization of required objects objects here                
    };      
    @Override
    protected Void doInBackground(Void... params)
    {   

         //do loading operation here  
        return null;
    }       
    @Override
    protected void onPostExecute(Void result)
    {
        super.onPostExecute(result);


  progressDialog.dismiss();
    };
 }
要检查您的服务是否仍在运行,请执行以下操作:

private boolean isMyServiceRunning() {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (MyService.class.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

AsyncTask基本上有
onPreExecute
doInbackground
,并且存在
onPostExecute
。每一个的意义

onPreExecute
: 在
doInBackground(Params…)之前在UI线程上运行

对立执行
: 在
doInBackground(Params…)
之后在UI线程上运行。指定的结果是
doInBackground(Params…)
返回的值

如果任务已取消,则不会调用此方法

调用的顺序

一个<代码>onPreExecute

两个<代码>背景设置

三个<代码>onPostExecute

但是
doInbackground
在另一个线程中操作


必须非常好地处理
doInbackground
结果通过了三次,因为
onPreExecute()
创建一个进度条来结束它的
onPostExecute
可以工作。

我有一个想法,在一个异步任务中创建一个异步序列

protected Boolean doInBackground(String... params) {
            if(params[0] == "taskA") {
              //do somthing
              params[0] = "taskB";
            }
            if(params[0] == "taskB") {
              //do somthing
              params[0] = "taskC";
            }
            if(params[0] == "taskC") {
              //do somthing
              params[0] = "taskD";
            }
            if(params[0] == "taskD") {
              //do somthing
              return true;
            }
在主线程中,只需按如下方式调用异步任务:

ShowMyProgress();
new MyAsyncTask().execute("taskA");
最后,您可以隐藏onPostExecute上的进度,如:

protected void onPostExecute(final Boolean success) {
        if (success) {
            ....

            HideMyProgress();
        }
}

onpostexecute方法呢?用那个。该方法是为您设计的。Mahn my asyntask是为android服务的,在这种情况下使用onPost是不可能的,因为用户可能会或可能不会到达活动D
get()
阻止ui线程等待结果。这使得Asynctask不再是异步的。所以这个建议是错误的,你不应该阻止ui线程。这是我提出的另一种方法。请检查我的答案,“任务”对象是您的任务。您可以将其设置为单例并在活动A中启动,然后在活动D中获取其实例。如果我的asynctask是我的服务类的内部类型,该怎么办?我知道如何使用它,但如果我从服务开始并希望在活动D中等待它,该怎么办?我知道如何使用它,但如果我从服务开始并希望在活动D中等待它,该怎么办?我想在活动中实现Listview DMy asynctask是从服务启动的,并且其对象在服务中如果我想在尚未启动的活动中实现它,我应该怎么做?我知道如何使用asynctask mahn,但在一个活动中启动和处理它需要很多时间。所以我在我的活动A上启动它,这样用户就不会在单个屏幕上等待10秒,时间会被分割,因为它需要太多的时间。是的,我可以这样做,但我必须等待asynctask完成,我要检查这个方法多久?
protected void onPostExecute(final Boolean success) {
        if (success) {
            ....

            HideMyProgress();
        }
}