【问题标题】:Proper way of implementing a periodic action实施定期行动的正确方法
【发布时间】:2012-08-22 22:42:49
【问题描述】:

我需要每 10 秒从 Android 的服务器发送和获取一些东西。在这里,在 StackOverflow 和文档中,我发现了几十种实现它的方法(我尝试的所有方法都可以完成工作),但似乎到处有人说这种方法有问题。

我尝试循环使用AsyncTask 直到它被取消(即直到活动被终止),我发现这不是一个好的解决方案。在此之前我尝试了普通的Threads,然后我发现它会消耗很多电池。

现在我已经使用 Runnable 和 ScheduledExecutorService 的 scheduleAtFixedRate 函数完成了它,类似于此处提出的代码: How to run an async task for every x mins in android? 。不用说,它有效。但是,如果我的 Activity 在后台运行,例如用户正在接听来电,它会起作用吗?

最后,我不知道在 Android 手机上最合适的方法是什么。

提前发送。

【问题讨论】:

  • 在此期间的任何周期性操作都会耗尽电池,因为它永远不会让 CPU(和系统)进入睡眠状态

标签: java android service scheduled-tasks task


【解决方案1】:

使用Handler 它有多种方法,如postDelayed(Runnable r, long delayMillis),postAtTime(Runnable r, Object token, long uptimeMillis) 等。

Handler mHandler =  new Handler() {
    public void handleMessage(Message msg) {

      //Start runnable here.
    }
   };

mHandler.sendMessageDelayed(msg, delayMillis)

【讨论】:

  • 是的,我试过了,但是如果传输时间长一点,它就会滞后于 UI。
  • 尝试在 handleMessage() 中调用 Asynctask。那样它就不会落后于 GUI。
  • 谢谢你,这可能是要走的路:)。
【解决方案2】:

执行重复任务很大程度上取决于任务的艰巨性/处理过程。 UI 是否会阻止您的任务。如果是这样,那么您可以使用 Handler 和 TimerTask 进行 AsyncTask。

在您的活动 onCreate 或任何通用函数中:

final Handler handler = new Handler();
    timer = new Timer();
        doAsynchronousTask = new TimerTask() {
           @Override
           public void run() {
            // TODO Auto-generated method stub
            handler.post(new Runnable() {
                 public void run() {
                try {
                 // Instantiate the AsyncTask here and call the execute method

                } catch (Exception e) {
                    e.printStackTrace();
                }

          }
        });
    timer.schedule(doAsynchronousTask,0,UPDATE_FREQUENCY)
    }

【讨论】:

    【解决方案3】:

    如果您需要在您的应用当前未运行时执行计划任务,建议您使用AlarmManagerBroadcastReceivers

    否则文档建议使用Handlers

    正如 AmitD 问题的 cmets 中所讨论的那样。如果任务需要在后台运行,您可以在处理程序回调中使用 AsyncTask 来实现。

    final Handler handler = new Handler() {
      public void handlerMessage(Message msg) {
        new AsyncTask<TaskParameterType,Integer,TaskResultType>() {
          protected TaskResultType doInBackground(TaskParameterType... taskParameters) {
            // Perform background task - runs asynchronously
          }
          protected void onProgressUpdate(Integer... progress) {
            // update the UI with progress (in response to call to publishProgress())
            // - runs on UI thread
          }
          protected void onPostExecute(TaskResultType result) {
            // update the UI with completion - runs on UI thread
          }
        }.execute(taskParameterObject);
      }
    };
    handler.postMessageDelayed(msg, delayMillis);
    

    对于重复执行,文档还提到 ScheduledThreadPoolExecutor 作为一个选项(这似乎比 java.util.Timer 更受欢迎,主要是由于额外的灵活性)。

    final Handler handler = new Handler() {
      public void handlerMessage(Message msg) {
        // update the UI - runs on the UI thread
      }
    };
    ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
    ScheduledFuture f = exec.scheduleWithFixedDelay(new Runnable() {
        public void run() {
          // perform background task - runs on a background thread
          handler.sendMessage(msg); // trigger UI update
        }
      }, 0, 10, TimeUnit.SECONDS);
    

    【讨论】:

      【解决方案4】:

      我想我会将Timer 类与TimerTask 一起使用:http://developer.android.com/reference/java/util/Timer.html

      【讨论】:

        猜你喜欢
        • 2016-02-02
        • 1970-01-01
        • 1970-01-01
        • 2020-06-27
        • 2013-03-12
        • 1970-01-01
        • 2021-11-02
        • 1970-01-01
        • 2013-08-22
        相关资源
        最近更新 更多