18

アプリケーションのアクティビティ スタックのアクティビティにインスタンスを 1 つだけ持たせたいです。ListActivity であるいくつかの画面があり、その ListActivity の別のインスタンスが変更された (追加、編集、削除など) ときに、ListActivity の前のインスタンスでリストを更新するという苦痛と苦しみを経験したくありません。 (またはこれを行う簡単な方法はありますか?)。

注:singleTopがこれを達成することを読みました(ただし、戻るボタンを押すとアクティビティが破棄されます)が、機能しません。メニューがあり、Inbox 画面に移動してから QuickList 画面に移動し、次に Inbox 画面に再度移動すると、新しい Inbox アクティビティが作成されます。

現在、ListActivities で、launchMode を singleInstance に設定しています。問題は、startActivityForResult を使用して別のアクティビティを起動すると、onActivityResult ハンドラーがすぐに起動することです (新しいアクティビティが作成される前に)。結果を返すために次の画面で必要なアクションを実行すると、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

ListActivity であるいくつかの画面があり、その ListActivity の別のインスタンスが変更されたときに、ListActivity の前のインスタンスでリストを更新するという苦痛と苦しみを経験したくありません (または、これを行う簡単な方法はありますか? )。

一貫したモデルを使用してください。たとえば、データがデータベースにあるとします。それぞれListActivityCursor必要なデータベースの部分があります。それを(経由で)Cursor「管理されたカーソル」にすると、で自動的に更新されます。次に、データベースを介してモデルに変更を加えます。startManagingCursor()ListViewsonResume()

メニューがあり、Inbox 画面に移動してから QuickList 画面に移動し、次に Inbox 画面に再度移動すると、新しい Inbox アクティビティが作成されます。

それが本来の役割です。ドキュメントの引用:

「標準」モードと「singleTop」モードは、ただ 1 つの点で互いに異なります。「標準」アクティビティの新しいインテントがあるたびに、そのインテントに応答するためにクラスの新しいインスタンスが作成されます。各インスタンスは単一のインテントを処理します。同様に、「singleTop」アクティビティの新しいインスタンスを作成して、新しいインテントを処理することもできます。ただし、ターゲット タスクのスタックの最上位に既にアクティビティの既存のインスタンスがある場合、そのインスタンスは (onNewIntent() 呼び出しで) 新しいインテントを受け取ります。新しいインスタンスは作成されません。その他の状況 - たとえば、"singleTop" アクティビティの既存のインスタンスがターゲット タスクにあるがスタックの一番上にない場合、またはスタックの一番上にあるがターゲット タスクにない場合 -新しいインスタンスが作成され、スタックにプッシュされます。

(強調のために太字を追加)

現在、ListActivities で、launchMode を singleInstance に設定しています。

これをしないでください。

于 2010-07-29T23:07:08.990 に答える