Android開発アート探索(ノートを読む)——02-Activityの起動モード

18361 ワード

Android開発アート探索(ノートを読む)

  • ブログ:Dimon
  • GitHub:Dimon94

  • 02-Activityの起動モード


    ActivityのLaunchMode


    復習:Activityを起動すると、システムはインスタンスを作成し、タスクスタックに入れます.タスクスタックは「後進先出」のスタック構造です.Activityの4種類の起動モード:
  • standard:標準モード、デフォルトモード.インスタンスが既に存在するかどうかにかかわらず、Activityを起動するたびに新しいインスタンスが再作成されます.このモードでは、あるActivityが1番Activityを起動し、1番Activityが起動したそのActivityが存在するスタックで実行される.
  • singleTop:スタックトップ多重モード.新しいActivityがすでにタスクスタックのスタックトップにある場合、このActivityは再作成されず、そのonNewIntentメソッドはコールバックされ、このメソッドのパラメータに基づいて現在のリクエストの情報を取得することができる.
  • singleTask:スタック内多重モード.このような単一インスタンスモードでは、Activityが1つのスタックに存在する限り、このActivityを複数回起動してもインスタンスは再作成されず、システムはonNewIntentを呼び出す.
  • singleInstance:シングルインスタンスモード.これは、singleTaskモードのすべての特性に加えて、singleTaskモードの強化されたsingleTaskモードであり、具体的には、このモードのActivityは、1つのタスクスタックに単独でのみ存在することができる.

  • 注意:ジャンプの場合は、まず、本ActivityonPauseを呼び出し、ジャンプします.ジャンプされたactivityが起動方式のために新しいインスタンスを作成しなかった場合、onNewIntentが呼び出され、通常のライフサイクルで呼び出されます.
    次のようになります.
  • A→B,A:onPause;B:onCreate,onStart,onResume.
  • A(singleTop)→A,A:onPause;A:onSaveInstanceState;A:onResume.

  • いくつかの具体的な問題と状況

  • 一:
  • まず、タスクスタックはフロントタスクスタックとバックグラウンドタスクスタックに分けられ、バックグラウンドタスクスタックのActivityは一時停止状態にある.
    フロントタスクスタックABでActivity Dが開始されると、DはバックグラウンドタスクスタックCDのスタックトップとなる.バックグラウンドタスクスタック内のActivityの起動モードがsingleTaskであると仮定し、Dの起動を要求すると、バックグラウンドタスクスタック全体がフロントに切り替えられ、フロントタスクスタックのスタックトップ、すなわちABCDを直接占有する.前に起動を要求したのがCであれば、ABCになります.singleTaskモードのActivityをスタックトップに切り替えると、その上にあるスタック内のActivityがスタックを出ます.
  • 二:
  • TaskAffinity:タスク依存性.Activityに必要なタスクスタックの名前を識別します.
    adnroid:taskAffinity="com.dimon.task1"
    

    デフォルトでは、Activityに必要なタスクスタックの名前は、アプリケーションのパッケージ名です.

    Activityに起動モードを指定するにはどうすればいいですか?


    1つ目の方法:Android MenifestでActivityの起動モードを指定します。

    <activity
        android:name="com.dimon.SecondActivity"
        android:configChanges="screenLayout"
        adnroid:taskAffinity="com.dimon.task1"
        android:launchMode="singleTask"
        android:label="@string/app_name"/>
    

    第2の方法:Intentにフラグビットを設定することでActivityの起動モードを指定します。

    Intent intent = new Intent();
    intent.setClass(MainActivity.this, SecondActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
    

    区別する

  • 優先度:第2の方法は第1の方法よりも優先度が高く、両方が存在する場合、第2の方法を基準とする.
  • 限定範囲:1つ目はFLAG_ACTIVITY_NEW_TASK識別子を設定できませんが、2つ目はsingleTaskモードを指定できません.

  • Acticityでよく使われるFlagsのいくつか

  • FLAG_ACTIVITY_NEW_TASK

  • このタグビットの役割は、Activityに「singleTask」起動モードを指定することであり、その効果はXMLで指定した起動モードと同じである.
  • FLAG_ACTIVITY_SINGLE_TOP

  • このタグビットの役割は、Activityに「singleTop」起動モードを指定することであり、その効果はXMLで指定した起動モードと同じである.
  • FLAG_ACTIVITY_CLEAR_TOP

  • このタグビットを持つActivityは、起動すると、同じタスクスタック内のすべてのActivityがスタックから出ます.singleTaskデフォルトでは、このタグビットの効果があります.起動されたActivitystandard起動モードを採用している場合、それ以上のActivityがスタックから出るように接続され、新しいActivityインスタンスが作成され、スタックの上部に格納されます.
  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

  • このタグを有するActivityは、履歴Activityのリストには表示されません.場合によっては、ユーザが履歴リストを介して私たちのActivityに戻ることを望んでいない場合に便利です.XMLでActivityのプロパティandroid:excludeFromRecents="true"を指定するのと同じです.

    IntentFilterの照合規則


    Actionのマッチングルール

    actionの適合要件Intentのうちのactionは存在し、フィルタリングルールの1つのactionと同じでなければならない.大文字と小文字を区別する.

    categorydのマッチングルール

    Intentcategoryが含まれている場合、categoryはいずれもフィルタルールの1つcategoryと同じでなければならない.Intentcategoryが含まれていない場合、システムはstartActivityまたはstartActivityForResultを呼び出すときにデフォルトでIntentに「android.intent.category.DEFAULT」というcategoryを加えるので、私たちのActivityが暗黙的な呼び出しを受信できるようにするには、intent-filterに「android.intent.category.DEFAULT」を指定する必要があります.

    dataのマッチングルール


    ルールはactionと似ています.
    <intent-filter>
      <data android:mimeType="image/*"/>
      ...
    intent-filter>
    

    以上の規則は、IntentmimeType属性が「image/*」でなければ一致しないことを示しています.URIは定義されていませんが、URIのデフォルト値はcontentfileです.すなわち、URIがなくてもIntentURI部分のschemacontentまたはfileでなければ一致しない.
    intent.setDataAndType(uri.parse("file://abc"),"image/png");
    

    Intentに完全なdataを指定する場合は、setDataAndTypeメソッドを呼び出す必要があります.setDataを呼び出してからsetTypeを呼び出すことはできません.この2つの方法は互いに相手の値をクリアするからです.ソースコードは次のとおりです.
    public Intent setData(Uri data){
      mData = data;
      mType = null;
      return this;
    }
    
    
    dataの構造はやや複雑で、文法は以下の通りである.
    <data android:scheme="string"
      android:host="string"
      android:port="string"
      android:path="string"
      android:pathPattern="string"
      android:pathPrefix="string"
      android:mimeType="string"/>
    
    dataは、mimeTypeURIの2つの部分から構成される.mimeTypeは、image/jpeg、audio/mpeg 4-generic、video/*などのメディアタイプを指す.URIの構成は次のとおりです.
    ://:/[||]
    
  • Scheme:URIのパターン、例えばhttp、file、contentなど.
  • Host:URIのホスト名、例えばwww.baidu.com
  • Port:URIのポート番号.
  • Path、pathPattern、pathPrefix:この3つはパス情報を表し、pathはパス情報を完全に表す.pathPatternは完全なパス情報も表していますが、ワイルドカード「*」を含めて正規表現に注意することができます.pathPrefixはパスのプレフィックス情報を表します.

  • IntentFilter統合例

    <intent-filter>
      <action android:name="com.dimon.1"/>
      <action android:name="com.dimon.2"/>
      <category android:name="com.dimon.1a"/>
      <category android:name="com.dimon.2b"/>
      <category android:name="android.intent.category.DEFAULF"/>\
      <data android:mimeType="text/plain"/>
    intent-filter>
    
    
    Intent intent = new Intent("com.dimon.1");
    intent.addCategory("com.dimon.2b");
    intent.setDataAndType(Uri.parse("file://abc"),"text/plain");
    startActivity(intent);
    

    Some Tips


    暗黙的にActivityを起動する場合は、Activityが私たちの暗黙的Intentに一致するかどうかを判断したほうがいいです.
    メソッドには、PackageManagerresolveActivityメソッドまたはIntentresolveActivityメソッドがあり、一致しない場合はnullに戻ります.
    さらに、PackageManagerは、最適マッチングqueryIntentActivities情報を返すのではなく、すべての成功マッチングActivity情報を返すActivity方法を提供する.
    public abstract List<ResolveInfo> queryIntentActivities(Intent intent, int flags);
    public abstract ResolveInfo resolveActivity(Intent intent, int flags);
    

    2番目のパラメータは、MATCH_DEFAULT_ONLYというタグビットを使用します.このタグビットは、intent-filterと宣言されたcategoryと一致するだけです.上記の2つの方法がActivityを返さない限り、nullは必ず成功する.startActivityというDEFAULTを含まないcategoryは暗黙的Activityを受信できないからである.
    前編は昨日のノートを整理して、これは今日の読書ノートです.実はね、メモといっても、実は知識点を転載しているだけで、入れない自分の理解と言えるでしょう.ノートの中の知識は私にとってすべて新しい知識で、いわゆるノートを書くのはただ自分の印象を深めるためで、後で探しやすいと言えます.
    その後、いくつかのプロジェクトのメモを整理するかもしれませんが、それらのプロジェクトには自分の粗浅な理解が加わる可能性があります.
    私は大学4年生で、仕事を探しています.Androidの仕事があれば、連絡してください.
    あなたは私のノートを読む时、もし间违いを発见するならば、直ちにありがとうございますを指摘することを渇望します
    千里の旅は足元から始まり、私はただよろよろ歩く人形で、巨人の肩の上でもっと遠くまで行けることを祈っています.
  • Good Luck!