2

我正在编写我的第一个 Android 应用程序(到目前为止很有趣!)并且遇到了障碍。我正在使用面向 Android 4.2 的 SDK 工具 21.1。

我正在尝试建立一个系统,允许活动注册以在设定的时间间隔调用方法。我想以这样一种方式执行此操作,即请求的处理将在其自己的进程中处理,以避免使 UI 无响应。

我一直在阅读并探索了一些途径。首先,我认为服务将是解决此问题的好方法,但发现相当多的信息表明这不是一个好的行动方案,因为操作系统能够不加选择地终止服务。

我现在正在考虑使用 ScheduledThreadPoolExecutor。我用一个可覆盖的方法创建了这个简单的类来传递方法:

public abstract class BaseEvent implements EventListener {

    public abstract void onFire(Object... params);
} 

我创建了这个可运行的任务调用该方法:

public class HeartBeatTask implements Runnable {


    private BaseEvent mCallback;

    private Object mParams;

    public HeartBeatTask(BaseAioEvent callback,Object... params){
        mParams = params;

        mCallback = callback;
    }

    @Override
    public void run() {
        Log.d(LOG_TAG,"Run called");
        if(mCallback != null)
        {
            mCallback.onEvent(mParams);
        }

    }
}

我将像这样使用它(在活动中)

      ScheduledThreadPoolExecutor threadPool = new ScheduledThreadPoolExecutor(1);
      BaseEvent callback = new BaseEvent() {
            public void onFire(Object... params){
                if(params[0] !=null)
                {
                    Context context = (Context)params[0];
                    Toast toast = Toast.makeText(context, "Task ran", Toast.LENGTH_SHORT);
                    toast.show();
                }
            }

      };

      threadPool.scheduleAtFixedRate(new HeartBeatTask(callback,(this)),0, 5, TimeUnit.SECONDS);

这将每 5 秒执行一次任务,尽管回调方法只运行一次。

我在想这可能不是做事的好方法。我的感觉是我把事情复杂化了。我真正需要的是能够在主线程以外的进程上执行方法的能力,并且在设定的时间间隔内,活动可以绑定多个操作。因此,例如,我可能希望在调用数据库后更新 UI 组件,并且希望每分钟都更新一次。

有人能告诉我我是否走在正确的轨道上吗?我正在尝试做的事情是实现我的目标的可行方法吗?我可以采取更好的方法吗?任何意见或建议将不胜感激。谢谢!

4

3 回答 3

3

给 Android 初学者的一些建议。

  • 不要称它为separate process. 进程是另一回事(谷歌“Linux 进程”),您想在同一进程内的单独线程上调用它们。

  • ScheduledThreadPoolExecutor 比人们在这里建议您的任何其他东西(例如 Timers 或 PostDelayed)都要好

但我认为你在这里确实有一个哲学错误,因为 UI 更新不应该以定时方式运行,而是在事件基础上运行。一旦您的数据库、磁盘或网络操作从后台线程完成,您将回调到 UI 线程以立即更新它。

有几种工具,我会列出一些,指出我最喜欢的一个,但让你对每一个做一些研究

于 2013-03-22T14:58:39.760 回答
1

Android 是一个移动平台,老实说,每次你想要运行某些东西时,你最好单独考虑它。您可能会无缘无故地耗尽电池或使用资源。我每天都讨厌 Zedge 应用程序一直在后台无缘无故地运行。特别是因为在 CyanogenMod 内核上,WiFi 进入睡眠状态,而显然它当前处于打开状态。

我猜这更像是一种练习,用于以指定的时间间隔运行任务。一次性的,最通用的可以通过 AlarmManager 类完成。但这可能不是最好的解决方案。

对于某些系统范围的事件,有 BroadcastReceiver 类。

在寻址时

因此,例如,我可能希望在调用数据库后更新 UI 组件,并且希望每分钟都更新一次。

通过接口更容易完成。

于 2013-03-22T15:03:06.503 回答
1

我认为你的方法有点复杂。考虑你的例子

So, for instance, I may want to have a UI component update after a call is made
to a database, and would want that to happen every minute.

我想我会这样做。

  1. 创建一个将更新 UI 组件的 AsyncTask。
  2. 创建一个线程,它将执行一个新的 AsyncTask 并在 while 循环中休眠一分钟。
  3. 在某个时间点启动步骤 3 中的线程。
  4. 如果您不想更新组件,请中断线程。

步骤 2 示例

while (true) {
    try {
        new updateTask.execute();
        Thread.sleep(60000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}
于 2013-03-22T15:06:20.973 回答