【问题标题】:AsyncTask executes at the end of the functionAsyncTask 在函数结束时执行
【发布时间】:2016-06-07 12:22:31
【问题描述】:

我正在使用 AsyncTask 以便我想要的函数立即执行,而不是等到结束才执行..

但由于某种原因,我不知道为什么它会在所有进程结束时执行!

我查看了其他解决方案,发现 Thread 应该在最后执行,但对于 AsyncTask,它应该在调用时执行..

这是我的代码

    private void LogMeIn()
 {

        string CheckValue;

        // Here I call the AsyncTask

        new GCM().execute(null,null,null);

        //gcmRegID is a public variable and should has GCM value assigned to it by now, but I it is empty as  GCM() has not been executed yet

           //This is always return empty string
           CheckValue = gcmRegID;
}

这是等待结束执行的AsyncTask

//This is the AsyncTask
 private class GCM extends AsyncTask<String, String, String> {

        private String resp;
        private Context context;



        @Override
        protected String  doInBackground(String... params) {
            GCMHelper  gcmRegistrationHelper = new GCMHelper (
                    getApplicationContext());

            try {
                gcmRegID = gcmRegistrationHelper.GCMRegister("123456789");
            } catch (Exception e) {
                e.printStackTrace();
            }

            return gcmRegID;
        }


 }

我试图在 onPreExecute 中调用 GCMRegister,但我收到一个错误,它必须在主线程中

这就像我在兜圈子......

调用必须在主线程中,并且主线程将在函数结束时执行...

中间好像没办法获取GCM代码!!!

如何让这个 AsyncTask 在调用时执行?

谢谢

【问题讨论】:

  • 立即执行。但是你对它无能为力。应该更好地查看文档。
  • "gcmRegID 是一个公共变量,现在应该已经分配了 GCM 值" - 不,它不应该,因为你的任务是异步运行的,这意味着它不会阻塞,并且execute() 调用后的行立即继续。
  • 你在哪里打电话LogMeIn()?尝试使用断点。
  • 我使用了断点,它没有转到 AsyncTask !我已经尝试了 3 天没有运气!!.. Mike M. 为什么它异步运行?我在这里做错了什么??

标签: java android android-studio android-asynctask google-cloud-messaging


【解决方案1】:

如果没有看到更多你的代码,我很难说,但我会看看你在哪里调用 LogMeIn()。因为您的 AsyncTask 和执行调用嵌套在 LogMeIn() 函数中,所以在第一次调用 LogMeIn() 之前不会调用它。

AsyncTask在调用execute()后依次经过以下4个步骤:

  • onPreExecute()
  • doInBackground(参数...)
  • onProgressUpdate(进度...)
  • onPostExecute(结果)

这些可以添加到您的 GCM 类中,并根据您的喜好使用。请注意,您不要直接调用它们。 AsyncTask 在调用 .execute() 后会自动执行。

只有在 doInBackground(Params...) 中指定的任务才会在后台线程上执行。其余的都在 UI(或主)线程上完成。我建议在 onPreExecute() 和 onPostExecute() 中放入 toast 或日志,以调试 GCM().execute 实际调用的位置/时间,然后告诉您后台任务何时完成。这将使您更好地了解正在发生的事情。

确保您没有尝试在 doInBackground() 中更新 UI。

愿意提供更多帮助,但我们需要查看更多您的代码。

@Override
public void onPreExecute() {
    super.onPreExecute();

    Log.d("GCM", "onPreExecute: called");
}

@Override
public void onPostExecute(String resultOfDoInBackground) {
    super.onPostExecute(resultOfDoInBackground);

    Log.d("GCM", "onPostExecute: called");
}

【讨论】:

  • 我试图将 GCMRegister 的调用放在 onPreExecute 中,但我收到一个错误,它必须在主线程中,就像我在绕圈子一样......调用必须在主线程和主线程会在函数结束时执行……中间好像没办法拿到GCM代码!!!
  • 好吧,我想我知道你想做什么了。您正在尝试将 gcmRegId 的值设置为 AsyncTask 的 doInBackground 的返回值,对吗?
  • 我想获取GCM代码并设置在公共变量gcmRegID中
【解决方案2】:

AsyncTask保持一个任务队列和一个线程池,线程池一个一个地执行任务,所以如果你有太多的任务,你会发现它不会立即执行你的任务。

并且在一个进程中,你所有的AsyncTask共享一个线程池。这种情况下,你应该自己做一个任务队列,你可以使用HandleThread来执行一个及时的任务。

【讨论】:

    【解决方案3】:

    尝试将新的GCM().execute(null,null,null); 放入受保护的无效onCreate(Bundle savedInstanceState) 方法中。这样,一旦应用程序运行,它将被调用。这样,在您使用 LogMEIn 方法之前,您将拥有您的 GCM id。

    【讨论】:

      【解决方案4】:

      试试这个 -

      if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
          new GCM().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,params);
      } else { 
          new GCM().execute(); 
      } 
      

      【讨论】:

        猜你喜欢
        • 2017-07-08
        • 1970-01-01
        • 1970-01-01
        • 2021-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多