【问题标题】:Android: Correct way to return a result from a background thread to various activitesAndroid:将结果从后台线程返回到各种活动的正确方法
【发布时间】:2013-09-12 08:03:09
【问题描述】:

我有两个活动,ActivityA 和 ActivityB。 ActivityA 启动一个长时间运行的进程(例如,在网络上检索数据)。在任何时候,用户都可以决定继续使用 ActivityB。长时间运行的进程结束后,其结果应显示在 ActivityA 或 ActivityB 中,以当时处于活动状态的为准。

为了实现这一点,我在 ActivityA 中创建了一个工作线程,ActivityA 和 ActivityB 都依赖 LocalBroadcastManager 来通知长时间运行的进程结束并获取其结果。

这个实现似乎有效,但我想知道我是否遗漏了一些极端情况。在 SO 上,我看到有关 IntentServiceAsyncTaskHandlerThread 的讨论,所以我担心我的方法可能过于幼稚。我这样做是正确的方式吗?如果没有,我错过了什么?

这里有一些代码 sn-ps 来说明我的问题。

活动A

public class ActivityA extends Activity {

    public static final String BROADCAST_MESSAGE = "spike.workerthread.event.resultReady";
    public static final String RESULT_KEY = "spike.workerthread.result";
    private LocalBroadcastManager localBroadcastMgr;
    private BroadcastReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_a);

        localBroadcastMgr = LocalBroadcastManager.
            getInstance(getApplicationContext());
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                TextView resultTextView = (TextView) findViewById(R.id.result);
                resultTextView.setText(intent.getStringExtra(RESULT_KEY));
            }};
        localBroadcastMgr.registerReceiver(receiver,
            new IntentFilter(BROADCAST_MESSAGE));
    }       

    public void startFetchingResultFrom(final ResultProvider provider) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                String result = provider.getResult(); // Can take a long time...
                Intent intent = new Intent(BROADCAST_MESSAGE);
                intent.putExtra(RESULT_KEY, result);
                localBroadcastMgr.sendBroadcast(intent);
            }
        };
        thread.start();
    }

    public void startActivityB() {
        Intent intent = new Intent(getApplicationContext(), ActivityB.class);
        startActivity(intent);
    }

}

活动B

public class ActivityB extends Activity {

    private LocalBroadcastManager localBroadcastMgr;
    private BroadcastReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_b);

        localBroadcastMgr = LocalBroadcastManager.getInstance(getApplicationContext());
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                TextView resultTextView = (TextView) findViewById(R.id.result);
                resultTextView.setText(intent.getStringExtra(ActivityA.RESULT_KEY));
            }};
        localBroadcastMgr.registerReceiver(receiver, new IntentFilter(ActivityA.BROADCAST_MESSAGE));
    }
}

【问题讨论】:

    标签: android multithreading android-intent


    【解决方案1】:

    您还可以考虑让活动实现一个接口,并在长时间运行的任务完成时调用该接口。

    AsyncTask 主要用于执行长时间运行的任务,然后轻松更新 UI。

    IntentService 是一个在自己的线程上运行的服务,它会在您正在执行的给定任务完成时终止。

    【讨论】:

    • 让活动实现一个通用接口将是使用 LocalBroadcastManager 的替代方法。但是长时间运行的任务如何获得对 ActivityB 实例的引用呢?
    • 我已经了解了 AsyncTask 和 IntentService。我想了解的是,使用简单的 Thread 代替这些重量级的类是否有任何缺点。
    【解决方案2】:

    我的建议是考虑一个设置,它有一个 Thread f.e 模型。基于片段的服务或活动。因为如果你在活动 A 中有你的线程并且你移动到 B 比你将失去对线程的控制。你应该避免这种情况。

    正如我所说,有一个模型和一些视图,可以随时访问它并控制您的线程。

    【讨论】:

    • 您能否解释一下当我的应用程序从 Activity A 移动到 Activity B 时失去对线程的控制时会发生什么样的坏事?
    猜你喜欢
    • 2021-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多