NewIntentの詳細

初めて学び始めたときは、意図はとてもシンプルだと感じていたのを覚えていますが、今ではいつも意図に悩まされ、素朴すぎます。わかりやすくするために、まとめてみましょう。

1つ、onNewIntent

古いルール、最初に公式を見てください:
ここに画像の説明を挿入
おそらく、アクティビティがsingleTopモードで開始するように設定されているとき、そしてこのアクティビティのアクティベーション要求に再度応答する必要があるとき、スタックの一番上にある既存のアクティビティを再利用することを意味しますonNewIntentメソッドを呼び出します。また、新しく送信されたインテント(onNewIntentメソッド)を受け入れる前に、onPauseメソッドを最初に実行する必要があります。

2つ目は、onNewIntentとスタートアップモードです。

前提条件:ActivityAが開始されており、現在のアプリケーションのアクティビティタスクスタックにあります。

ActivityAのLaunchModeが標準の場合:

ActivityAの各開始は新しいインスタンスを開始することであるため、元の開始とは関係がなく、元のActivityAのonNewIntentメソッドは呼び出されません。

ActivityAのLaunchModeがSingleTopの場合:

ActivityAがスタックの最上位にあり、ActivityAを今すぐ開始する場合、この時点でonNewIntent()メソッドが呼び出され、ライフサイクルシーケンスは次のようになります。

onCreate—> onStart—> onResume— onPause—> onNewIntent—>onResume

LaunchMode ActivityAがSingleInstance、の場合SingleTask

ActivityAがすでにタスクスタックにある場合は、ActivityAを再度開始すると、この時点でonNewIntent()メソッドが呼び出され、ライフサイクルの呼び出しシーケンスは次のようになります。

onPause—>他のページにジャンプ—> onCreate—> onStart—> onResume—onPause—>ジャンプA—> onNewIntent—> onRestart—> onStart—>onResume

一般に、SingleTop(およびスタックの最上位にある)、SingleTaskおよびSingleInstance(およびタスクスタックにすでにインスタンスが存在する)場合にのみ、それらは再起動時に呼び出されます。つまり、startActivityに対してのみ有効であり、フォアグラウンドへのバックグラウンド再度開始されない場合、onNewIntentはトリガーされません。

3.例:

Androidでは、別のアクティビティから新しいアクティビティを開始し、それにデータを渡すことは簡単で基本的なことです。ただし、すでに実行中のアクティビティをフォアグラウンドに表示してデータを渡す場合は、少し注意が必要です。
まず、デフォルトでは、インテントを使用してアクティビティを呼び出すと、別のインスタンスがすでに実行されている場合でも、アクティビティの新しいインスタンスが作成されて表示されます。この状況を回避するには、アクティビティを複数回インスタンス化しないようにマークする必要があります。これを実現するために、AndroidManifest.xmlでアクティビティのlaunchModeをsingleTopに設定します

<activity android:name=".SecondActivity"
            android:launchMode="singleTop"
            ></activity>
        <activity
            android:name=".FirstActivity"
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

このように、インテントを使用してこのアクティビティを呼び出すと、既存のインスタンスが存在する場合、システムはリクエストをそのインスタンスにリダイレクトします。今回は通常のonCreateメソッドは実行されません。
その名前が示すように、アクティビティが作成されたときに実行され、今回はすでに存在しているため、onNewIntent()メソッドが呼び出されます。

protected void onNewIntent(Intent intent) {
    
    
  super.onNewIntent(intent);
  setIntent(intent);//must store the new intent unless getIntent() will return the old one
  processExtraData();
}

onCreateでは通常の方法でデータを受信できることを忘れないでください。アクティビティが初めて作成されるとき、システムはリターンラウンドでアクティビティを簡単に終了できるため、これが発生した場合は、代わりにonCreateメソッドが呼び出されます。 onNewIntentの。
したがって、洗練されたソリューションでは、同じ関数を呼び出して、onCreateとonNewIntentからのジャンプを処理できます。

public void onCreate(Bundle savedInstanceState) {
    
    
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  processExtraData();
}
 
protected void onNewIntent(Intent intent) {
    
    
  super.onNewIntent(intent);
  setIntent(intent);//must store the new intent unless getIntent() will return the old one
  processExtraData()
}
 
private void processExtraData(){
    
    
  Intent intent = getIntent();
  //use the data received here
}

完全なコードは次のとおりです。

FirstActivity.java

public class FirstActivity extends AppCompatActivity {
    
    

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

        displayIntentData();

        findViewById(R.id.sendButton).setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
                intent.putExtra("key",((EditText)findViewById(R.id.dataToSend)).getText().toString());
                startActivity(intent);
                //注意我们在这里没有调用finish()方法
            }
        });

    }

    @Override
    protected void onNewIntent(Intent intent) {
    
    
        super.onNewIntent(intent);
        Log.e("onNewIntent","First Activity OnNewIntent is called");
        setIntent(intent);//must store the new intent unless getIntent() will return the old one
        displayIntentData();
    }

    private void displayIntentData(){
    
    
        Intent intent = getIntent();
        TextView tv = (TextView)findViewById(R.id.intentData);
        Bundle extras=intent.getExtras();
        if(extras!=null){
    
    
            tv.setText("Data received: "+extras.getString("key"));
        }else{
    
    
            tv.setText("No extradata received");
        }
    }
}

SecondActivity.java

public class SecondActivity extends AppCompatActivity {
    
    

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

        displayIntentData();

        findViewById(R.id.sendButton).setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                Intent intent = new Intent(SecondActivity.this,FirstActivity.class);
                intent.putExtra("key",((EditText)findViewById(R.id.dataToSend)).getText().toString());
                startActivity(intent);
                //注意我们在这里没有调用finish()方法
            }
        });
    }

    @Override
    protected void onNewIntent(Intent intent) {
    
    
        super.onNewIntent(intent);
        setIntent(intent);
        displayIntentData();
    }

    private void displayIntentData(){
    
    
        Intent intent = getIntent();
        TextView tv = (TextView)findViewById(R.id.intentData);
        Bundle extras=intent.getExtras();
        if(extras!=null){
    
    
            tv.setText("Data received: "+extras.getString("key"));
        }else{
    
    
            tv.setText("No extradata received");
        }
    }
}

AndroidManifest.xml

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".SecondActivity"
            android:launchMode="singleTop"
            ></activity>
        <activity
            android:name=".FirstActivity"
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FirstActivity">

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:id="@+id/intentData"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />

        <EditText
            android:layout_height="wrap_content"
            android:id="@+id/dataToSend"
            android:layout_width="fill_parent"
            android:hint="Data to send"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/intentData"
            />

        <Button
            android:text="Send"
            android:id="@+id/sendButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toBottomOf="@id/dataToSend"
            />

</androidx.constraintlayout.widget.ConstraintLayout>

おすすめ

転載: blog.csdn.net/i_nclude/article/details/105472751