Android重启异步任务

piah890a  于 2023-02-06  发布在  Android
关注(0)|答案(7)|浏览(126)

尝试重新打开Activity后,我在重新启动AsyncTask时遇到一些问题。
当我第一次打开Activity时,我调用它来启动AsyncTask,它第一次就工作了。

myTask connectedTask;
connectedTask = new myTask();
connectedTask.execute();

public class myTask extends AsyncTask<Integer,Integer, Integer> {

    @Override
    protected Integer doInBackground(Integer... arg0) {
        //Increase timer and wait here in a loop
        System.out.println("ASYNC TASK STARTING!");
        return IsSocketConnected();
    }

    protected void onPostExecute(Integer result) {
        //Something you want to do when done?
        System.out.println("ASYNC TASK DONE!");

        // if it was connected successfully 
        if(result == 1) {
            // remove the progress bar
            proBar.setVisibility(View.GONE);

            // Discover available devices settings and create buttons
            CreateButtons(btnList);
        }
    }
}

IsSocketConnected(); // checks for a bluetooth connections to be done.

当我返回到上一个活动并尝试再次启动该活动时,无法使AsyncTask再次启动。
我读到,只要我创建了AsyncTask的新示例,我就应该重新启动那些任务。
我还有别的事要做吗?
谢谢你,

7hiiyaii

7hiiyaii1#

很好,OP找到了解决方案,但为未来的读者回答;
您可以添加一个方法,例如:

public class MainActivity extends Activity {
    
     public static MyTask loadTextDataTask;
     
     //... methods

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

         //... methods

         public void selfRestart() {
             loadTextDataTask = new MyTask();
         }
     }

}
然后您可以从任何其他类使用它,例如:

MainActivity.loadTextDataTask.selfrestart();

注意没有真实的的方法来重新启动现有示例,即使我们调用AsyncTask.cancel(true),第二次调用AsyncTask.execute()也会引发

IllegalStateException: Cannot execute task: the task has already been executed
5lhxktic

5lhxktic2#

这是正确的,你可以简单地创建一个新的示例并执行它来重新开始。我想知道你是在哪个函数中启动任务的?在你的onResume()函数中启动它可能是一个好主意,以防Activity在回到前台之前没有被销毁。

mpbci0fu

mpbci0fu3#

谢谢你所有的意见,他们帮助了很多。我决定做了AsyncTask。我结束使用一个正常的可运行线程,并使用处理程序张贴消息回UI线程。以下是代码:

// Start thread here only for IsSocketConnected
        new Thread(new Runnable() {

            public void run() {

                //Add your code here..
                IsSocketConnected();

            }
        }).start();

// handler that deals with updating UI
public Handler myUIHandler = new Handler()
{
    @Override
    public void handleMessage(Message msg)
    {
        if (msg.what == Bluetooth.STATE_CONNECTED)
        {
            //Update UI here...
            Log.d(TAG, "Connected");



            // Discover available devices settings and create buttons
            CreateButtons(btnList);

        } else if(msg.what == Bluetooth.STATE_NONE) {

            Log.d(TAG, "NOT Connected");
        }

}

// in the IsSocketConnected() I call this 
Message theMessage = myUIHandler.obtainMessage(Bluetooth.STATE_CONNECTED);
myUIHandler.sendMessage(theMessage);//Sends the message to the UI handler.

到目前为止,这是有效的。再次感谢。希望这对某人有帮助

ehxuflar

ehxuflar4#

尝试将以下代码放入onResume()中:

@Override
public void onResume()
{
    super.onResume();
    myTask connectedTask = new myTask();
    connectedTask.execute();
}

当你恢复到Activity时,它应该会创建一个新的对象。你没有发布它,但可能是在onCreate()中创建了一个只运行一次的对象。
处理Socket连接时,我的建议是只对Thread本身进行子类化。

pw9qyyiw

pw9qyyiw5#

最好使用OnPostExecute来触发任务的一个新示例。如果任务完成,它将触发。但是使用一个布尔值来防止它每次都触发自己

protected void onPostExecute(Void result) {

if(someboolean==true) { 
                            new instance of task;
                            instance.execute;
                someboolean=false;
                }

}
ldfqzlk8

ldfqzlk86#

开发商网站上说
首次引入时,AsyncTasks在单个后台线程上串行执行。从DONUT开始,这被更改为允许多个任务并行操作的线程池。从HONEYCOMB开始,任务在单个线程上执行,以避免并行执行导致的常见应用程序错误。
如果确实需要并行执行,可以使用THREAD_POOL_EXECUTOR调用executeOnExecutor(java.util.concurrent.Executor,Object[])。
从HONEYCOMB开始,AsyncTask默认使用单个Executor执行任务,然后一次运行一个任务。这意味着如果调用myTask.execute()在您已在任何活动中调用它之后(主线程上的任何位置),第二个调用将等待调用doInBackground方法,直到第一个任务完成。如果您的IsSocketConnected()方法不会立即返回,它将在主线程上的任何位置再次调用AsyncTask.execute()方法后阻止任何doInBackground()调用,直到当前任务完成。
如果您的isSocketConnected()使用了任何阻塞操作,如wait()或Thread.sleep(),您可以通过在Activity的onDestroy()回调中调用myTask.cancel(true)来解决此问题,这将引发InterruptedException。只需确保在导致线程退出doInBackground方法的位置捕获InterruptedException。
您还可以通过使用自定义
ThreadPoolExecutor
并调用AsyncTask.executeOnExecutor(Executor)方法来执行变通方法。

db2dz4w8

db2dz4w87#

不使用:连接的任务=新的我的任务();执行();
简单地使用:新连接任务。执行();使用它的地方,你正是想重新启动任务!!

相关问题