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

在黑莓手机上我会:

  1. 推送一个不可取消的弹出窗口(对话框屏幕),显示“请稍候...”
  2. 启动一个完成工作的线程
  3. 线程完成后关闭弹出窗口

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

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

Android 上有什么解决方案可以实现上述类似 BB 的行为吗?

有帮助吗?

解决方案 3

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

事实证明这个问题相当复杂,所以没有简单快捷的解决方案。该解决方案需要深入了解 Android 平台/API。这是app进程/Activity生命周期的灵活性所带来的代价。

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

不管怎样,我很高兴现在我有了我们称之为最佳实践方法的东西。

其他提示

但是,由于无法保证活动实例将在OnSaveInstanceState上取消多长时间(并在OnrestoreInstancestate上重新启动)。

或者让它由一个 Service.

如果你的 Activity 想要停留在屏幕上,你可以简单地启动一个线程,如下所示:

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

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

这样 GUI 线程就可以执行其他操作,例如显示

  android.app.ProgressDialog

另外,考虑使对话框不可取消

  ProgressDialog.setCancelable(false);

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

  Activity.onPause()

叫做。此外,您可能需要研究唤醒锁,以阻止屏幕变黑并将您的应用程序推送到可能被杀死的后台。你可以在线程中这样做:

  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 的一部分时,这才有效,就像您正在运行的普通线程一样,当使用 on... 调用时,这才有效。 -方法。为了实现这一点,您的后台线程必须通过处理程序回调到 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);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top