【问题标题】:how to receive data from service when fragment is resumed?片段恢复时如何从服务接收数据?
【发布时间】:2016-06-06 09:59:59
【问题描述】:

我的活动中有一个侧面菜单抽屉,其中有 2 个选项(“我的文件”和“同步”),每个选项都是一个片段。当我在“同步”片段中时,有一个按钮可以开始从服务器下载文件。这是通过在后台运行的意图服务完成的。我在片段中使用了一个结果接收器,它不断从服务获取下载进度 (%) 并将其显示在片段中。

问题是,如果我在下载过程中切换到“我的文件”片段并返回到“同步”片段,则视图会重置并且进度会丢失。服务在后台继续运行,但片段不显示进度。

我的问题是,当我切换片段时,“同步”片段是否仍会从在后台继续运行的服务接收进度。当我返回“同步”片段时,如何开始从服务接收进度更新。

下面是启动服务的片段中的代码。

intent.putExtra("link", downloadLink);
syncReceiver = new SyncReceiver(new Handler());
intent.putExtra("result_receiver", syncReceiver);
getContext().startService(intent);

将下载进度发送到片段的服务中的代码。

resultReceiver = intent.getParcelableExtra("result_receiver");
link = intent.getStringExtra("link");

while ((bytesRead = inputStream.read(buffer)) != -1) {
      fileOutputStream.write(buffer, 0, bytesRead);
      byteCount += bytesRead;
      String kbs = String.valueOf(byteCount / 1024);
      bundle = new Bundle();
      bundle.putString("response", kbs);
      bundle.putString("total_data", total_file_size);
      resultReceiver.send(CONTENT_PROGRESS, bundle);
}

片段中的进度接收代码。

public class SyncReceiver extends ResultReceiver {
    private static final int CONTENT_PROGRESS = 2;

    public SyncReceiver(Handler handler) {
        super(handler);
    }

    public void onReceiveResult(int resultCode, Bundle data) {
        super.onReceiveResult(resultCode, data);

        String response = data.getString("response");
        if (resultCode == CONTENT_PROGRESS) {
            updateContentProgress(response, data.getString("total_file_size");
        }
    }
}


private void updateContentProgress(String progress, String total_file_size)  {
    double current = Double.parseDouble(progress);
    double totalData = 0;
    totalData = Double.parseDouble(total_file_size);
    String percent = String.valueOf((current / totalData) * 100);
    status.setText(R.string.download_progress);
    status.append(" " + percent + "%");
}

【问题讨论】:

  • 如果您的接收方接近,则在恢复时注册并在停止时取消注册。
  • 我正在使用 resultReceiver.send(progress_code, progress_data) 函数将 progress_data 发送回片段以在文本视图中显示。
  • 你能分享代码吗?
  • 在问题中添加了它
  • 我们需要c实现,来帮助你

标签: java android android-fragments intentservice download


【解决方案1】:

首先将进行下载的课程移动到您的活动中。然后从您对类的片段调用以使用下面的代码段检查您的下载状态...由于活动仍将保留对您的初始下载的引用,您将能够跟踪进度。当您切换片段时,您的活动会自动终止对下载线程的引用,因为片段已被删除。在活动中保持引用允许您跨多个片段进行跟踪。确保您的类是公开的。

((YourBaseActivityWithProperClasses) getActivity()).trackDownloadProgress();

【讨论】:

    【解决方案2】:

    Fragment 不会得到更新,因为它可能会被销毁并重新创建。

    我遇到了类似的问题,我的解决方案是有一个额外的背景片段来保留 ResultReceiver,它不会被设置 setRetainInstance(true) 破坏。

    可以在这里找到解释和可能的解决方案:https://stanmots.blogspot.com/2016/10/androids-bad-company-intentservice.html

    另一个关于这个问题的好读物: https://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html

    所以我的解决方案是将ResultReceiver 包含在一个额外的Fragment 中,其中包含setRetainInstance(true)

    为了在(重新)创建视图时获得正确的状态,我在onCreate() 中执行以下操作:

    final FragmentManager manager = ((Activity) getContext()).getFragmentManager();
    
    // Try to find the Fragment by tag
    final IntentObserverFragment intentObserverFragment =
                    (IntentObserverFragment) manager.findFragmentByTag(IntentObserverFragment.TAG);
    
    if (intentObserverFragment == null) {
    
        // Service is not active
        this.progressBar.setVisibility(View.GONE);
    
    } else {
    
        // Service is working - show ProgressBar or else
        this.progressBar.setVisibility(View.VISIBLE);
    
        // Stay informed and get the result when it's available 
        intentObserverFragment.setCallbackClass( this );
    
    }
    

    在我的IntentObserverFragment 中,我从onAttach() 开始工作 - 而不是onCreate(),因为所需的Context 尚不可用,这将导致NPE 使用例如getActivity()!

    @Override
    public void onAttach(Context context) {
    
        super.onAttach(context);
    
        final MyResultReceiver myResultReceiver = new MyResultReceiver();
    
        final Intent intent = new Intent( context, MyIntentService.class );
        intent.putExtra(MyIntentService.BUNDLE_KEY_RECEIVER, myResultReceiver);
        context.startService(intent);
    }
    

    【讨论】:

      猜你喜欢
      • 2019-06-02
      • 2016-08-13
      • 1970-01-01
      • 2014-04-27
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多