2012-07-20 101 views
6

我尝试重新打开该活动后重新启动AsyncTask时遇到了一些问题。Android重新启动AsyncTask

当我第一次打开活动,我打电话给这个开始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的新实例,我应该重新启动这些任务。

有什么我应该做的吗?

谢谢

+1

你的意思是,你不能得到它的工作?你有错误信息吗? – 2012-07-20 20:47:12

+0

对不起泰德,那是一个不好的选择。我的意思是我无法让它重新启动。我没有得到任何错误代码它没有去doInBackground – jramirez 2012-07-20 20:58:26

+0

这是'onCreate'代码? 'onResume'?同意@TedHopp,需要更多信息。 – Greyson 2012-07-20 20:58:58

回答

2

谢谢你的评论,他们帮助了很多。我决定取消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. 

这是工作至今。再次感谢你。希望这可以帮助别人

+1

AsyncTask的好处是它可以在线程池上运行任务。每次创建新线程都会更有效率。当然,你可以在你自己的线程池中运行它。 – dhaag23 2016-12-16 02:45:34

2

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

0

尝试把这个代码onResume(),如:

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

当您恢复回你Activity应该创建一个新的对象。您没有发布它,但可能在onCreate()中创建仅运行一次的对象。

我对处理Socket连接的建议只是子类Thread本身。

+0

小心......您需要将@Override注释添加到您的函数中。另外,为了澄清,每次创建活动时都会调用onCreate()。 onResume也是如此,不同之处在于onCreate可以再次调用之前的活动已经死亡。这与我20分钟前发布的答案基本相同...... – Joel 2012-07-20 21:27:44

+0

根据异步任务的执行情况,这可能是一种非常糟糕的策略。只要活动从暂停状态恢复,就会调用“onResume”,在活动处于活动状态时可能会发生多次。 (例如,拉下通知,接听电话等) – 2012-07-20 21:31:43

+0

覆盖率很高。每次创建活动时都会调用onCreate(),但似乎他在重新激活活动时会遇到问题,只需调用onResume()即可。我还建议他只用一根线来连接。 – 2012-07-20 21:33:23

2

可能对将来会遇到此问题的人有所帮助。你可以只添加一个方法:

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(); 
0

更好,使用OnPostExecute,触发任务的新实例。如果任务完成,它会启动。但使用一个布尔,以防止它触发本身每次

protected void onPostExecute(Void result) { 

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

} 
0

开发者网站上说,

当第一次推出,AsyncTasks是在单个后台线程串行执行。从DONUT开始,将其更改为允许多个任务并行操作的线程池。从HONEYCOMB开始,任务在单个线程上执行,以避免并行执行导致的常见应用程序错误。

如果您真的想要并行执行,可以使用THREAD_POOL_EXECUTOR调用executeOnExecutor(java.util.concurrent.Executor,Object [])。

从HONEYCOMB开始,AsyncTask默认使用一个Executor来执行任务,然后一次运行一个任务。这意味着,如果你调用myTask.execute()后,你已经把它称为上的任何活动(上任何地方的主线程),第二个呼叫将等到第一个任务完成时调用doInBackground方法。如果您IsSocketConnected()方法并没有立即返回它会调用AsyncTask.execute()方法再次在主线程上的任何地方后,阻止任何doInBackground()调用,直到当前任务完成。

如果您isSocketConnected()使用任何阻塞操作,例如等待()或Thread.sleep()方法,你可以解决它通过调用myTask.cancel(真)中的onDestroy()回调到您的活动,这会抛出一个InterruptedException。只要确保在一个会导致线程退出doInBackground方法的地方捕获InterruptedException。

您也可以通过使用自定义ThreadPoolExecutor并调用AsyncTask.executeOnExecutor(Executor)方法来执行解决方法。

0

代替使用: connectedTask =新myTask(); connectedTask.execute();

只需使用: newconnectTask.execute(); 在你想要重新开始任务的地方使用它!