【问题标题】:AsyncTask not delaying operation in HandlerAsyncTask 不会延迟 Handler 中的操作
【发布时间】:2018-05-18 18:55:30
【问题描述】:

我正在编写应用程序,我想从服务中初始化的 BroadCastReceiver 调用 AsyncTask。 我想在后台延迟 AsyncTask 做一些工作,但似乎 Handler 不起作用,因为我在 Logcat 中得到这个输出(简而言之):

05-18 20:33:01.396 19382-19382// D/AsyncTask: Sleeping for a while
Sleeping for a while
.
.
05-18 20:33:01.406 19382-19382// D/AsyncTask: Sleeping for a while
Sleeping for a while
.
.

这是我的代码:

ExampleService.java:

import java.util.*;
import android.content.*;
import com.google.firebase.messaging.*;
import timber.log.*;

public class ExampleService extends FirebaseMessagingService {

   private AnotherExample anotherExample;

   @Override
   public void onMessageReceived(final RemoteMessage message) {
       Timber.d("onMessageReceived(): message: %s", message);

       anotherExample = new AnotherExample();
       if (message.getData() != null) {
           processMessage(message.getData());
       }
   }

   private void processMessage(Map<String, String> data) {
      Timber.d("processMessage(): data: %s", data);

      IntentFilter filter = new IntentFilter();
      filter.addAction(Intent.ACTION_SCREEN_OFF);
      registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
          Timber.d("onReceiveScreenOff()");
          anotherExample.create();
          anotherExample.resume();
        }
      }, filter);

      IntentFilter filter1 = new IntentFilter();
      filter1.addAction(Intent.ACTION_SCREEN_ON);
      registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
          Timber.d("onReceiveScreenOn()");
          anotherExample.suspend();
        }
      }, filter1);
  }
}

AnotherExample.java

public class AnotherExample {

  AsyncTask asyncTask;

  public void create() {
    this.asyncTask = new MyAsyncTask();
  }

  public void resume() {
    this.asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
  }

  public void suspend() {
    this.asyncTask.cancel(true);
  }
}

MyAsyncTask.java

public class MyAsyncTask extends AsyncTask {

  private Handler handler;
  private Runnable runnable;

  private void setupRunnable() {
    runnable = new Runnable() {
      @Override
      public void run() {
        Log.d("AsyncTask", "Sleeping for a while");
      }
    };
  }

  @Override
  protected Object doInBackground(Object[] objects) {
    while (!isCancelled()) {
     handler.postDelayed(runnable, 1000);
    }

    return null;
  }

  @Override
  protected void onCancelled() {
    super.onCancelled();
    Log.d("AsyncTask", "Removing callbacks");
    handler.removeCallbacks(runnable);
  }
}

不知道问题出在哪里,我也用Thread.sleep(1000)试了一下,结果还是一样。

有没有其他方法可以实现?

另外我想问一下,AsyncTask 和 BroadCastReceiver 是使用同一个线程吗?因为它看起来像 BroadCastReceiver 在屏幕打开时没有获取信息。

感谢您的每一个建议。

【问题讨论】:

  • 我没有遇到您报告的相同问题。请检查我的答案。

标签: java android multithreading android-asynctask


【解决方案1】:

我无法重现您的问题。我的代码似乎运行良好。

就这样称呼吧:

private void testAsyncTaskDelay(){
    TestEventsData test = new TestEventsData();
    test.execute();
}

我的TestEventsData 类定义:

class TestEventsData extends AsyncTask<String, Integer, Boolean> {
    Handler testHandler = new Handler();

    @Override
    protected Boolean doInBackground(String... params) {
        Boolean success = false;
        try {
            long startTime = SystemClock.elapsedRealtime();
            Log.e(TAG, "doInBackground Start " + startTime);

            testHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    long endTime = SystemClock.elapsedRealtime();
                    long diff = endTime - startTime;
                    Log.e(TAG, "run Start " + endTime);
                    Log.e(TAG, "run Start diff " + diff);

                }
            }, 3000);

        }
        catch (Exception ex) {
            Log.e(TAG, "doInBackground --- " + ex.getMessage());
        }

        return success;
    }


    @Override
    protected void onCancelled() {
    }

    @Override
    protected void onPostExecute(Boolean success) {
        try{
            Log.e(TAG, "onPostExecute NOW");
        }
        catch(Exception ex){
            Log.e(TAG, "onPostExecute" + ex.getMessage());
        }
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }
}

我对 logcat 的输出:

05-18 15:15:51.951 24329-24345/? E/MainActivity: doInBackground Start 1471880721 
05-18 15:15:52.003 24329-24329/? E/MainActivity: onPostExecute NOW 
05-18 15:15:54.953 24329-24329/com.asb.android.mcc E/MainActivity: run Start 1471883724 
05-18 15:15:54.953 24329-24329/com.asb.android.mcc E/MainActivity: run Start diff 3003

时差3003ms!在我的postDelayed() 中设置相同的时间。

【讨论】:

  • 谢谢,我已经尝试过了,然后(经过 3 个小时的调试)我注意到我正在从 2 个不同的地方注册 BroadcastReceiver,所以我没有取消一个线程。谢谢你的帮助。
猜你喜欢
  • 2019-06-23
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
  • 1970-01-01
  • 1970-01-01
  • 2014-05-08
  • 1970-01-01
  • 2023-03-15
相关资源
最近更新 更多