startActivityForResult与launchMode singleInstance无法正常工作

时间:2010-07-29 21:11:57

标签: android android-activity single-instance

我希望我的应用程序的Activity堆栈上的活动只有一个实例。我有几个是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);
                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:24)

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

换句话说,如果要使用sAFR,则需要处理多个活动实例。我建议将ListActivityonPause个实例的列表状态存储到某个应用全局点(单例或其他),然后从onResume加载。然后,即使创建了多个ListActivity实例,最上面的实例也会在旧数据恢复之前更新数据,并且列表将始终显示给用户。

请注意,如果您的数据是持久性的,那么您应该这样做,因为您的整个过程可能会在onPause调用之后随时被系统杀死,并且如果您还没有保存任何更改在返回的某个时间点,它们可能会在某些情况下(通常是罕见且不可预测的)情况下悄然失去。在这种情况下,您希望使用本地文件或SQLite数据库,而不是持久保存到网络。 onPause需要快速返回,因为用户在运行时无法与系统交互,因此请保存到本地存储,然后在其他时间同步到网络,可能是通过onPause启动的服务

答案 1 :(得分:2)

  

我有几个屏幕   ListActivities我想不去   通过痛苦和痛苦   更新以前的列表   ListActivity的实例   ListActivity的另一个实例   改变了(或者有一种简单的方法   这样做?)。

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

  

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

这就是应该做的。引用documentation

  

“标准”和“单击”模式   只有一个彼此不同   尊重:每次有新的意图   对于“标准”活动,新的   创建类的实例   回应这个意图。每个实例   处理单一意图。同样,a   “singleTop”活动的新实例   也可以创建来处理新的   意图。但是,如果是目标任务   已经有一个现有的实例   堆栈顶部的活动,   该实例将收到新的   intent(在onNewIntent()调用中);一个   未创建新实例。的在   其他情况 - 例如,如果   一个现有的实例   “singleTop”活动在目标中   任务,但不是在堆栈的顶部,   或者如果它位于堆栈的顶部,但是   不在目标任务中 - 一个新的   将创建并推送实例   在堆栈上。

(粗体添加强调)

  

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

请不要这样做。