【问题标题】:Android IntentService/Service to request/send data to web service and getting the progress to UIAndroid IntentService/Service 向 Web 服务请求/发送数据并获取 UI 的进度
【发布时间】:2015-06-03 03:14:24
【问题描述】:

基本上在 Android 上,我正在尝试从 Web 服务上传/下载数据,并有一个进度条,应该显示进度百分比。

以下是我实施的方法以及考虑它们的原因:

  1. 选择IntentService 在后台运行: 根据link,我无法使用绑定服务,因为绑定的 Activity/Fragment 被销毁时它会销毁。因此选择IntentService 而不是Service。将其移过一次,意图服务在工作线程上工作,因此会好得多。
  2. 广播接收更新: 实现 LocalBroadcastManager 以更新进度条 UI,方法是注册它以收听从上述 IntentService 接收的广播。

但是,使用这种方法,需要解决以下问题:

不维护广播的顺序。广播携带上传/下载的进度百分比。但是由于没有维护顺序,我有可能收到过时的更新(例如:我可能会在 40% 之后收到 30%)。我也尝试使用LocalBroadcastManagersendBroadcastSync 方法,但它不能始终如一地工作(我对此不太确定)。因此,我尝试通过Handler 实现Messenger,但是我知道一旦重新创建UI(活动/片段被破坏和创建),该方法将无法重新连接到正在进行的上传/下载。基本上,对 Handler 的引用与之前的活动/片段一起丢失,因此消息不会传递到 UI 进行更新。

一段时间以来,我一直在努力解决问题,但我无法完成。你的智慧之言会很有帮助。

【问题讨论】:

    标签: android file-upload broadcastreceiver intentservice localbroadcastmanager


    【解决方案1】:

    如何使用接口。 UI:在创建活动/片段时获取实例和 setCallback(),服务:获取实例并调用更新(如果未从主线程调用,则使用处理程序,handler.post(runnable {... update ...}))。

    如果要通知多个 UI 实例,请在 updater 类中保留一个 ArrayList,并将 'setCallback' 方法修改为 'addCallback',并更新 'update' 中的每个列表项。

    public class ProgressUpdater {
        private static ProgressUpdater sUpdater;
        private UpdateCallback mCallback;
    
        public interface UpdateCallback {
            public void update(long progress);
        }
    
        public void setCallback(UpdateCallback callback) {
            mCallback = callback;
        }
    
        public void update(long progress) {
            if (mCallback != null) {
                mCallback.update(progress);
            }
        }
    
        public static ProgressUpdater getInstance() {
            if (null == sUpdater) {
                sUpdater = new ProgressUpdater();
            }
            return sUpdater;
        }
    
        private ProgressUpdater() {
    
        }
    }
    

    【讨论】:

    • 这是一个单例模式,它应该在没有MessengerBroadcast 的情况下更新。我需要检查一下。但是,有一点值得关注。一旦 UI(Activity/Fragment)被销毁,mCallback 将转到null。这种情况下是不是有可能会出现空指针异常?
    • 我在显示 toast 的活动中设置了一个回调,并在服务中每 5 秒调用一次更新。结果是,即使活动已被破坏,吐司仍然出现。如果您担心泄漏活动上下文,请对回调使用弱引用。 @光辉
    【解决方案2】:

    我会以不同的方式解决这个问题,因为消息的排序可能是各种消息解决方案的问题。

    在 30% 事件之后获得 40% 事件这一事实并不是真正的问题。如果您更新 UI 以反映 30%,的问题。

    让每个事件(使用LocalBroadcastManager 作为事件总线时的每个Intent)都包含一个时间戳以及完成百分比。在您的 UI 中跟踪上次看到的事件时间戳。如果您收到的事件早于您上次看到的事件时间戳,请忽略该事件。

    如果您确定您的百分比是单调递增的——换句话说,不存在您可能从 40% 下降到 30% 完成的合法场景——您可以跳过时间戳,只应用新的百分比高于您当前显示的百分比。

    【讨论】:

      【解决方案3】:

      如果您想不断更新您的用户界面,那么我们可以从服务启动本地广播管理器并在您的活动中注册您的广播接收器。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多