18

我希望我的应用程序的活动堆栈上的活动只有一个实例。我有几个屏幕是 ListActivities,当 ListActivity 的另一个实例被更改(添加到、编辑、删除等)时,我不想经历更新 ListActivity 的前一个实例中的列表的痛苦和痛苦(或者有没有简单的方法来做到这一点?)。

注意:我读过 singleTop 将完成此操作(尽管如果您点击后退按钮它会破坏 Activity),但它不起作用。我有一个菜单,如果我转到我的收件箱屏幕,然后我转到我的快速列表屏幕,然后我再次转到我的收件箱屏幕,它会创建一个新的收件箱活动。

现在,在我的 ListActivities 上,我将 launchMode 设置为 singleInstance。问题是:如果我使用 startActivityForResult 启动另一个 Activity,onActivityResult 处理程序会立即触发(在创建新 Activity 之前)。当我在下一个屏幕上执行必要的操作以返回结果时,onActivityResult 处理程序不会触发。

到底是怎么回事?

这是我触发新活动的方式:

Intent intentLaunchQuickList = new Intent(ActivityMyList.this, ActivityQuickList.class);
startActivityForResult(intentLaunchQuickList, REQUEST_QUICKLIST);

这是我返回结果的方式:

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    QuickListItem qlItem = m_Adapter.getItem(position);
    if (qlItem != null && qlItem.getQLId() != -1) {
        Intent data = new Intent();
        data.putExtra("ql_id", qlItem.getQLId());
        if (getParent() == null) {
            setResult(Activity.RESULT_OK, data);
        }
        else {
            getParent().setResult(Activity.RESULT_OK, data);
        }
    }
    finish();
}

这是我的 onActivityResult 处理程序:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_QUICKLIST) {
        if (resultCode == Activity.RESULT_OK) {
            Bundle extras = data.getExtras();
            if (extras != null) {
                int id = extras.getInt("ql_id");
                if (id > 0) {
                    launchQLItemsThread(id);
                }
            }
        }
    }
}
4

2 回答 2

23

来自文档startActivityForResult:“例如,如果您正在启动的活动使用 singleTask 启动模式,它将不会在您的任务中运行,因此您将立即收到取消结果。” singleInstance活动也是一样。

换句话说,如果您想使用 sAFR,您将需要处理多个活动实例。我建议将您的ListActivity实例的列表状态存储onPause到某个应用程序全局位置(单例或其他),然后从那里加载到onResume. 然后,即使ListActivity会创建多个实例,顶部的实例也将始终在旧实例恢复之前更新数据,并且列表将始终对用户显示为最新。

请注意,如果您的数据是持久的,则无论如何您都应该这样做,因为您的整个过程可以在onPause调用后的任何时候被系统杀死,并且如果您在返回时尚未在某处保存任何更改,它们在某些情况下——通常是罕见的和不可预测的——情况下,他们可能会默默地迷失。在这种情况下,您希望使用本地文件或 SQLite 数据库,而不是持久化到网络。 onPause需要快速返回,因为用户在系统运行时无法与系统交互,所以保存到本地存储,然后在其他时间同步到网络,可能通过onPause.

于 2010-07-29T22:03:41.020 回答
2

我有几个屏幕是 ListActivities,当 ListActivity 的另一个实例发生更改时,我不想经历更新 ListActivity 的前一个实例中的列表的痛苦和痛苦(或者有没有简单的方法来做到这一点? )。

使用一致的模型。例如,您的数据希望在数据库中。每个ListActivity都有一个Cursor它需要的数据库部分。让它Cursor成为“托管光标”(通过startManagingCursor()),您ListViews将在onResume(). 然后,您通过数据库对模型进行更改。

我有一个菜单,如果我转到我的收件箱屏幕,然后我转到我的快速列表屏幕,然后我再次转到我的收件箱屏幕,它会创建一个新的收件箱活动。

这就是它应该做的。引用文档

“标准”和“singleTop”模式仅在一个方面彼此不同:每次有“标准”活动的新意图时,都会创建一个新的类实例来响应该意图。每个实例处理一个意图。类似地,也可以创建“singleTop”活动的新实例来处理新意图。但是,如果目标任务在其堆栈顶部已经有活动的现有实例,则该实例将接收新意图(在 onNewIntent() 调用中);未创建新实例。在其他情况下——例如,如果“singleTop”活动的现有实例在目标任务中,但不在堆栈的顶部,或者如果它在堆栈的顶部,但不在目标任务中 -将创建新实例并将其推送到堆栈上。

(为强调而添加了粗体字)

现在,在我的 ListActivities 上,我将 launchMode 设置为 singleInstance。

请不要这样做。

于 2010-07-29T23:07:08.990 回答