74

私の主な活動はマニフェストAに設定されているとおりです。android:launchMode="singleTask"これで、そこから別のアクティビティを開始するたびに、たとえば、電話でをB押しHOME BUTTONてホーム画面に戻り、アプリのボタンを押すか、HOME BUTTON長いボタンを押して最新のアプリを表示することで、アプリに戻ります。アクティビティスタックを保持せAず、期待されるアクティビティの代わりに直接戻りますB

ここで2つの動作:

Expected: A > B > HOME > B
Actual: A > B > HOME > A (bad!)

不足している設定はありますか、それともバグですか?後者の場合、バグが修正されるまでこれに対する回避策はありますか?

参考:この質問はすでにここで説明されています。ただし、これに対する実際の解決策はまだないようです。

4

12 に答える 12

45

これはバグではありません。既存のsingleTaskアクティビティが起動されると、スタック内のその上にある他のすべてのアクティビティが破棄されます。

HOMEアクティビティをもう一度押して起動するActivityMangerと、インテントが呼び出されます

{act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER]flag=FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_RESET_IF_NEEDED cmp=A}

したがって、結果は A > B > HOME > A です。

AのlaunchModeが「Standard」の場合は異なります。A を含むタスクがフォアグラウンドに来て、以前と同じ状態を維持します。

たとえば、「標準」アクティビティを作成できます。ランチャーとしての C と C の onCreate メソッドの startActivity(A)

また

A にインテントを呼び出すたびに、フラグを削除しlaunchMode="singleTask"て設定するだけですFLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOP

于 2010-06-09T03:16:20.157 に答える
5

ステファン、これに対する答えを見つけたことがありますか? 私はこれのテストケースをまとめましたが、同じ (困惑する) 動作が見られます...誰かが来て、何か明白なことを見た場合に備えて、以下のコードを貼り付けます:

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example" >

  <uses-sdk android:minSdkVersion="3"/>

  <application android:icon="@drawable/icon" android:label="testSingleTask">

    <activity android:name=".ActivityA"
              android:launchMode="singleTask">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
    </activity>

    <activity android:name=".ActivityB"/>

  </application>
</manifest>

ActivityA.java:

public class ActivityA extends Activity implements View.OnClickListener
{
  @Override
  public void onCreate( Bundle savedInstanceState )
  {
    super.onCreate( savedInstanceState );
    setContentView( R.layout.main );
    View button = findViewById( R.id.tacos );
    button.setOnClickListener( this );
  }

  public void onClick( View view )
  {
    //Intent i = new Intent( this, ActivityB.class );
    Intent i = new Intent();
    i.setComponent( new ComponentName( this, ActivityB.class ) );
    startActivity( i );
  }
}

ActivityB.java:

public class ActivityB extends Activity
{
  @Override
  public void onCreate( Bundle savedInstanceState )
  {
    super.onCreate( savedInstanceState );
    setContentView( R.layout.layout_b );
  }
}

minSdkVersion を無駄に変更しようとしました。これは、少なくともドキュメンテーションによると、バグのようです。次のように述べています。

上記のように、「singleTask」または「singleInstance」アクティビティのインスタンスは 1 つしか存在しないため、そのインスタンスはすべての新しいインテントを処理することが期待されます。"singleInstance" アクティビティは常にスタックの一番上にあり (タスク内の唯一のアクティビティであるため)、常にインテントを処理できる位置にあります。ただし、「singleTask」アクティビティには、スタック内のその上に他のアクティビティがある場合とない場合があります。存在する場合、インテントを処理する立場にないため、インテントは破棄されます。(インテントが削除されたとしても、その到着によってタスクがフォアグラウンドに移動し、そこに残ります。)

于 2010-06-07T05:54:13.530 に答える
3

これはあなたが望む動作だと思います:

singleTask は、ホームプレスのスタックを、私には理解できない遅れた理由でリセットします。解決策は、singleTask を使用せず、代わりにランチャー アクティビティにstandardまたはsingleTopを使用することです (ただし、これまでに singleTop でのみ試しました)。

アプリは相互に親和性があるため、次のようなアクティビティを起動します。

Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
if(launchIntent!=null) {
    launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
}

古いアクティビティで新しいアクティビティを開始することなく、アクティビティスタックが元のように再表示されます(これは以前の私の主な問題でした)。フラグは重要なものです:

FLAG_ACTIVITY_NEW_TASK API レベル 1 で追加

設定されている場合、このアクティビティは、この履歴スタックの新しいタスクの開始になります。タスク (それを開始したアクティビティから次のタスク アクティビティまで) は、ユーザーが移動できるアクティビティのアトミック グループを定義します。タスクはフォアグラウンドとバックグラウンドに移動できます。特定のタスク内のすべてのアクティビティは、常に同じ順序のままです。タスクの詳細については、タスクとバック スタックを参照してください。

このフラグは通常、「ランチャー」スタイルの動作を提示したいアクティビティで使用されます。これらのアクティビティは、実行できる個別のリストをユーザーに提供します。それ以外の場合は、それらを起動するアクティビティとは完全に独立して実行されます。

このフラグを使用する場合、開始しようとしているアクティビティに対してタスクが既に実行されている場合、新しいアクティビティは開始されません。代わりに、現在のタスクが前回の状態で画面の前面に表示されます。この動作を無効にするフラグについては、FLAG_ACTIVITY_MULTIPLE_TASK を参照してください。

このフラグは、呼び出し元が起動中のアクティビティからの結果を要求している場合は使用できません。

と:

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED API レベル 1 で追加

設定されていて、このアクティビティが新しいタスクで開始されているか、既存のタスクを最上位に持ってきている場合、タスクのフロント ドアとして起動されます。これにより、そのタスクを適切な状態にするために必要なアフィニティーが適用されるか (アクティビティをそこに移動するか、そこから移動するか)、または必要に応じてそのタスクを初期状態にリセットするだけです。

それらがなければ、起動されたアクティビティは古いスタックまたはその他の望ましくない動作の上にプッシュされるだけです (この場合はもちろん)

最新のインテントを受信しないという問題は、次のように解決できると思います(私の頭から):

@Override
public void onActivityReenter (int resultCode, Intent data) {
    onNewIntent(data);
}

やってみて!

于 2014-10-14T11:09:49.923 に答える
1

A と B の両方が同じ に属している場合はApplication、削除してみてください

android:launchMode="singleTask"

Activitiesデフォルトの動作はあなたが期待どおりに説明したものだと思うので、あなたとテストから。

于 2010-03-10T15:41:24.827 に答える
0

ホームボタンを押してホーム画面に戻るたびに、アクティビティスタックは、以前に起動して実行していたアプリの一部を強制終了します。

この事実を確認するには、アプリでAからBに移動した後、通知パネルからアプリを起動し、戻るボタンを使用して戻ってみてください..........アプリは自分と同じ状態になっています。それを残しました。

于 2010-08-11T06:16:26.960 に答える
0

これが、この奇妙な動作を最終的に解決した方法です。AndroidManifest で、これは私が追加したものです:

Application & Root activity
            android:launchMode="singleTop"
            android:alwaysRetainTaskState="true"
            android:taskAffinity="<name of package>"

Child Activity
            android:parentActivityName=".<name of parent activity>"
            android:taskAffinity="<name of package>"
于 2016-11-30T16:31:27.833 に答える