2

例如,我们在 SomeActivity 中,该活动有一个按钮,用于调用将文件从一个目录移动到另一个目录(我们称之为作业)。

在黑莓上,我会:

  1. 推送一个不可取消的弹出窗口(对话屏幕),说“请稍候......”
  2. 启动一个完成任务的线程
  3. 在线程完成时关闭弹出窗口

这种方法 99.99% 可以保证我们在任务结束后保持在同一个屏幕上,用户只是看到弹出窗口并等待任务完成。设备旋转或任何不会破坏所需工作流程的东西。

在 Android 上,情况发生了变化。我知道可能会提供 AsyncTask 来解决我的问题。甚至还有一个很好的例子来说明它应该如何使用。但由于无法保证 Activity 实例的生存时间,因此应在 onSaveInstanceState 上取消 AsyncTask(并在 onRestoreInstanceState 上重新启动)。这意味着使用 AsyncTask 并不能保证我们一旦开始就能够完全完成工作。在某些情况下,作为发送创建用户的 http 发布请求,我不想在重新运行 AsyncTask 时遇到“用户已存在此登录”的麻烦。这是可能的,因为 AsyncTask 可以在请求已经发送时被中断(并且服务器实际上正在做它的工作 - 创建一个新用户),但是 AsyncTask 在我们得到响应之前被取消。

Android上是否有任何解决方案来获得上述类似BB的行为?

4

3 回答 3

2

但由于无法保证 Activity 实例的生存时间,因此应在 onSaveInstanceState 上取消 AsyncTask(并在 onRestoreInstanceState 上重新启动)。

或者让它由一个Service.

于 2010-02-11T00:58:59.850 回答
1

如果您的 Activity 想要留在屏幕上,您可以像这样简单地启动一个线程:

final File fromFile = ...;
final File toFile = ...;

new Thread() {
    @Override
    public void run() {
      // do something with fromFile, toFile
    }
}.start();

这样 GUI-Thread 就可以做其他的事情了,比如显示一个

  android.app.ProgressDialog

另外,考虑使对话框无法取消

  ProgressDialog.setCancelable(false);

这样,用户只能通过 HOME 键离开,您会在何时收到通知

  Activity.onPause()

叫做。此外,您可能想要查看 Wakelocks,以阻止屏幕变黑,并将您的应用程序推到可能被杀死的后台。您可以在 Thread 中执行此操作:

  PowerManager pm = (PowerManager) ivContext.getSystemService(Context.POWER_SERVICE);
  Wakelock wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "MyApp");
  wakeLock.acquire();

  // ... copy stuff ...

  wakeLock.release();

当然,当用户通过 HOME 键离开时,您也必须释放 wakeLock。

最后,如果您想从后台线程调用 GUI-Elements,这仅在线程是 GUI-Event-Loop 的一部分时才有效,就像您正在运行的普通线程一样,当被调用时... -方法。为了实现这一点,您的后台线程必须通过处理程序回调到 GUI 线程。像这样:

  private Handler mHandler = new Handler() { 
      @Override
      public void handleMessage(Message msg) {
          Log.v(TAG, "Got Message "+msg.what); // prints: Got Message 77
      // ... do GUI actions ...
      }    
  };

  // ... in Thread ...

  int lvInfo = 77;
  mHandler.sendEmptyMessage(lvInfo);

您甚至可以像这样将对象放入消息中:

  Message txtMsg = Message.obtain();
  textMsg.obj = "Hello World";
  mHandler.sendMessage(lvTextMsg);
于 2010-02-11T04:42:19.253 回答
0

2010 年 5 月,Google 发布了一个名为“开发 Android REST 客户端应用程序”的新 IO 会议,它解释了如何准确地实现我的要求。

原来这个问题相当复杂,所以没有简单快捷的解决方案。该解决方案需要深入了解 Android 平台/API。这是应用程序流程/活动生命周期的灵活性造成的代价。

为什么这个信息没有从 Android 的第一个版本中提供,我感到有些奇怪。看起来 Google 知道如何编写 100% 无错误的应用程序,但出于某种营销原因并没有分享这种方法。想象一下,到 2010 年 5 月,有多少错误的应用程序被编写出来。

无论如何,我很高兴现在我有了我们称之为最佳实践方法的东西。

于 2011-04-14T20:13:07.427 回答