Androidの暗黙的な意図(Intent)はどのように一致するコンポーネントを検索します
4427 ワード
【0】Androidの基本的な設計コンセプトは、コンポーネント間の結合を減らすことを奨励することであり、Androidは、動作およびイベントを実行するためにアプリケーションと他のアプリケーションとの間でIntentを伝達することを可能にする汎用的なメッセージシステムを提供する.Intentを使用すると、Androidアプリケーションの3つのコアコンポーネント(アクティビティ、サービス、ブロードキャスト受信機)をアクティブにできます.
Intentは明示的意図と暗黙的意図に分けることができる.
明示的な意図:Intentを呼び出す.setComponent()またはIntent.setClass()メソッドは、コンポーネント名のIntentが明示的な意図であることを明確に指定し、明示的な意図は、Intentがどのコンポーネントに渡すべきかを明確に指定します.
暗黙的意図:コンポーネント名が明確に指定されていないIntentは暗黙的意図です.Androidシステムは、暗黙的な意図で設定されたアクション、カテゴリ、データ(URI、データ型)に基づいて、この意図を処理します.
【2】Androidは、暗黙的な意図に対して、この最適なコンポーネントをどのように探しているのでしょうか.
前述のアクティビティを定義する際にintent-filterを指定しましたが、Intent Filter(意図フィルタ)は実は暗黙的なIntentに一致するために使用され、1つの意図オブジェクトが1つの意図フィルタによって一致テストされると、3つの側面だけが参照されます:アクション、データ(URIおよびデータ型)、カテゴリ.
動作テスト(Actiontest)
1つの意図オブジェクトには1つのアクション名しか指定できませんが、1つのフィルタには複数のアクション名が列挙されます.意図したオブジェクトまたはフィルタにアクションが指定されていない場合、結果は次のようになります.
•フィルタにアクションが指定されていない場合、すべての意図がブロックされ、すべての意図がテストに失敗します.このフィルタを通過する意図はありません.
•一方、フィルタに少なくとも1つのアクションが含まれている限り、アクションを指定していないオブジェクトが自動的にこのテストに合格します.
カテゴリテスト(Category test)
カテゴリマッチングテストに合格できる意図については、意図オブジェクトのカテゴリがフィルタのカテゴリに一致する必要があります.このフィルタは別のカテゴリを列挙することができるが、この意図の中の任意のカテゴリを漏らすことはできない.
原則として、フィルタに何があるかにかかわらず、カテゴリのない意図オブジェクトは常にマッチングテストに合格するはずです.ほとんどの場合、これは正しいです.しかし、AndroidはstartActivity()に渡されたすべての暗黙的な意図を少なくとも1つのカテゴリ「android.intent.category.DEFAULT」(CATEGORY_DEFAULT定数)を含んでいると見なす例外がある.したがって、暗黙的な意図を受信するアクティビティには、意図フィルタに「android.intent.category.DEFAULT」を含める必要があります.(「android.intent.action.MAIN」および「android.intent.category.LAUNCHER」設定のあるフィルタは例外です)
データテスト(Data test)
1つの意図的オブジェクト内のURIが1つのフィルタ内のURIと比較するために使用される場合、比較はURIの各構成要素である.例えば、フィルタが1つのschemeのみを指定した場合、schemeのURIsはすべてこのフィルタと一致することができる.フィルタがscheme、ホスト名を指定しているが、経路部分がない場合、同じschemeとホスト名を持つURIsは、経路にかかわらず、このフィルタと一致することができる.フィルタがscheme、ホスト名、パスを指定した場合、同じscheme、ホスト名、パスを持つURIsのみがこのフィルタと一致します.もちろん、フィルタ内のパス仕様にはワイルドカードを含めることができます.これにより、部分的に一致するだけでいいです.
データテストでは、意図したオブジェクトとフィルタで指定したURIとデータ型を同時に比較します.
ルールは次のとおりです.
a.URIもデータ型も含まない意図的なオブジェクトは、フィルタも同様にURIsとデータ型も指定されていない場合にのみテストに合格する.
b.URIを含むが、データ型がない意図的なオブジェクトは、そのURIが同じように指定されたデータ型がないフィルタ内のURIと一致した場合にのみテストに合格する.これは通常mailto:とtel:のようなURIsで発生します.実際のデータは参照されません.
c.データ型を含むがURIを含まない意図オブジェクトは、このフィルタが同じデータ型を列挙し、URIも指定していない場合にのみテストに合格する.
d.URIとデータ型を同時に含む(またはURIからデータ型を推定することができる)意図オブジェクトは、フィルタに列挙されたタイプと一致する場合、テストに合格することができる.URIがこのフィルタの1つのURIと一致しているか、コンテンツcontent:またはファイルfile:URIがあり、このフィルタがURIを指定していない場合は、テストにも合格します.すなわち、コンポーネントはcontent:およびfile:データをサポートすると仮定され、フィルタが1つのデータ型のみを列挙している場合.
Intentは明示的意図と暗黙的意図に分けることができる.
明示的な意図:Intentを呼び出す.setComponent()またはIntent.setClass()メソッドは、コンポーネント名のIntentが明示的な意図であることを明確に指定し、明示的な意図は、Intentがどのコンポーネントに渡すべきかを明確に指定します.
暗黙的意図:コンポーネント名が明確に指定されていないIntentは暗黙的意図です.Androidシステムは、暗黙的な意図で設定されたアクション、カテゴリ、データ(URI、データ型)に基づいて、この意図を処理します.
【2】Androidは、暗黙的な意図に対して、この最適なコンポーネントをどのように探しているのでしょうか.
前述のアクティビティを定義する際にintent-filterを指定しましたが、Intent Filter(意図フィルタ)は実は暗黙的なIntentに一致するために使用され、1つの意図オブジェクトが1つの意図フィルタによって一致テストされると、3つの側面だけが参照されます:アクション、データ(URIおよびデータ型)、カテゴリ.
動作テスト(Actiontest)
1つの意図オブジェクトには1つのアクション名しか指定できませんが、1つのフィルタには複数のアクション名が列挙されます.意図したオブジェクトまたはフィルタにアクションが指定されていない場合、結果は次のようになります.
•フィルタにアクションが指定されていない場合、すべての意図がブロックされ、すべての意図がテストに失敗します.このフィルタを通過する意図はありません.
•一方、フィルタに少なくとも1つのアクションが含まれている限り、アクションを指定していないオブジェクトが自動的にこのテストに合格します.
カテゴリテスト(Category test)
カテゴリマッチングテストに合格できる意図については、意図オブジェクトのカテゴリがフィルタのカテゴリに一致する必要があります.このフィルタは別のカテゴリを列挙することができるが、この意図の中の任意のカテゴリを漏らすことはできない.
原則として、フィルタに何があるかにかかわらず、カテゴリのない意図オブジェクトは常にマッチングテストに合格するはずです.ほとんどの場合、これは正しいです.しかし、AndroidはstartActivity()に渡されたすべての暗黙的な意図を少なくとも1つのカテゴリ「android.intent.category.DEFAULT」(CATEGORY_DEFAULT定数)を含んでいると見なす例外がある.したがって、暗黙的な意図を受信するアクティビティには、意図フィルタに「android.intent.category.DEFAULT」を含める必要があります.(「android.intent.action.MAIN」および「android.intent.category.LAUNCHER」設定のあるフィルタは例外です)
データテスト(Data test)
1つの意図的オブジェクト内のURIが1つのフィルタ内のURIと比較するために使用される場合、比較はURIの各構成要素である.例えば、フィルタが1つのschemeのみを指定した場合、schemeのURIsはすべてこのフィルタと一致することができる.フィルタがscheme、ホスト名を指定しているが、経路部分がない場合、同じschemeとホスト名を持つURIsは、経路にかかわらず、このフィルタと一致することができる.フィルタがscheme、ホスト名、パスを指定した場合、同じscheme、ホスト名、パスを持つURIsのみがこのフィルタと一致します.もちろん、フィルタ内のパス仕様にはワイルドカードを含めることができます.これにより、部分的に一致するだけでいいです.
データテストでは、意図したオブジェクトとフィルタで指定したURIとデータ型を同時に比較します.
ルールは次のとおりです.
a.URIもデータ型も含まない意図的なオブジェクトは、フィルタも同様にURIsとデータ型も指定されていない場合にのみテストに合格する.
b.URIを含むが、データ型がない意図的なオブジェクトは、そのURIが同じように指定されたデータ型がないフィルタ内のURIと一致した場合にのみテストに合格する.これは通常mailto:とtel:のようなURIsで発生します.実際のデータは参照されません.
c.データ型を含むがURIを含まない意図オブジェクトは、このフィルタが同じデータ型を列挙し、URIも指定していない場合にのみテストに合格する.
d.URIとデータ型を同時に含む(またはURIからデータ型を推定することができる)意図オブジェクトは、フィルタに列挙されたタイプと一致する場合、テストに合格することができる.URIがこのフィルタの1つのURIと一致しているか、コンテンツcontent:またはファイルfile:URIがあり、このフィルタがURIを指定していない場合は、テストにも合格します.すなわち、コンポーネントはcontent:およびfile:データをサポートすると仮定され、フィルタが1つのデータ型のみを列挙している場合.
public class MainActivity extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) this.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Intent intent = new Intent();
intent.setAction("com.hoo.kay");
// URI
//intent.setData(data);
//intent.setType(type); setData , , setDataAndType
intent.setDataAndType(Uri.parse("hoo://www.hoo.com/person"), "image/gif");
startActivity(intent);
}
});
}
}
,intent.setType(type); setData , , setDataAndType