Kata pengantar
Artikel ini terutama memperkenalkan niat Android, dan menganalisis proses pencocokan permintaan niat dari perspektif kode sumber Android.
PENDAHULUAN INTTEN
Intent's China berarti "niat", dan niat adalah konsep yang sangat abstrak. Oleh karena itu, sistem Android dengan jelas menentukan bahwa niat dapat diukur dengan dua aspek.
Atribut utama: termasuk tindakan dan data. Di antara mereka, tindakan digunakan untuk mewakili niat tindakan yang diungkapkan oleh niat, dan data digunakan untuk mewakili data yang dioperasikan oleh tindakan.
Atribut Sekunder: Termasuk Kategori, Jenis, Komponen, dan Ekstra. Kategori ini mewakili kategori, tipe mewakili tipe data data, dan komponen dapat digunakan untuk menentukan respons dari niat tertentu (misalnya, menentukan niat untuk menjadi kelas kelas di bawah paket), dan ekstra digunakan untuk membawa orang lain informasi.
Ada dua jenis niat utama dalam sistem Android, yang menunjukkan maksud (niat eksplisit) dan niat tersembunyi (niat implisit).
Niat Eksplisit: Jenis niat ini dengan jelas menunjukkan komponen mana yang akan ditemukan. Dalam kode, Anda dapat mengunci objek target melalui SetClassName atau setComponent.
Niat implisit: Jenis niat ini tidak secara jelas menunjukkan komponen mana yang akan dimulai, tetapi mengatur tindakan, data, dan kategori untuk menjadikan layar sistem komponen yang sesuai.
Selanjutnya, tulis dua contoh kode untuk memperkenalkan niat eksplisit dan menirukan inent. Yang pertama adalah niat eksplisit:
Private Void StartExplicitIntentWithComponent () {Intent Intent = new Intent (); Intent);} Private Void StartExplicitIntentWithClassName () {Intent Intent = New Intent ();Namun, dari kode sumber, saya menemukan bahwa SetClassName juga menggunakan ComponentName untuk mencapai niat eksplisit. Kode sumber adalah sebagai berikut:
Public Intent SetClassName (String Packagename, String ClassName) {mComponent = new ComponentName (PackageName, ClassName);Kemudian, contoh kode dari niat yang tersirat. Di sini saya menggunakan aktivitas untuk menandai beberapa niat filter sebagai contoh, dan kemudian menulis niat untuk memulainya.
<Aktivitas android: name = ". SendIntentType"> <intent-filter> <action android: name = "justtest"/> <kategori android: name = "justcategory" </intent-f ilter> </active>
Di Androidmanifest.xml saat ini diterapkan, niat-filter ditambahkan ke kelas SendIntentType. Kode yang memulai aktivitas adalah sebagai berikut:
Private Void StartImpllictent () {Intent Intent = new Intent ();Dalam proses pencocokan proses niat yang tersirat, tiga item yang terdaftar oleh Intent Filter akan digunakan sebagai standar referensi.
Manajemen Informasi Aktivitas
Dari analisis di atas, dapat dilihat bahwa dalam proses niat pencocokan sistem, Anda pertama -tama perlu mengelola semua informasi aktivitas dalam sistem saat ini. Informasi aktivitas dikumpulkan dan dikelola oleh Packagemanagerservice saat memindai APK. Kode sumber terkait adalah sebagai berikut:
// Proses informasi atture yang terlampir n = pkg.activities.size (); A .info.processName = fixProcessName (pkg.applicationInfo.processName, A.info.processname, pkg.applicationInfo.uid);
Dalam kode di atas, ada dua struktur data penting, seperti yang ditunjukkan pada gambar di bawah ini.
Dikombinasikan dengan struktur data kode dan gambar di atas, dapat dilihat:
Macitivity adalah tipe ActivityIntentResolver. Ada juga variabel mactivies di dalam struktur data ini.
Semua informasi terkait informasi yang diperoleh dari APK (termasuk label IntentFilter yang dinyatakan dalam XML) disimpan oleh PackageParser.Activity.
Kode sebelumnya memanggil fungsi addactivity untuk menyelesaikan publisitas informasi pribadi. Kode fungsi addactivity adalah sebagai berikut:
Addactivity void akhir publik (PackageParser.Activity A, Tipe String) {Final Boolean SystemApp = Issystemapp (A.info.ApplicationInfo); Int j = 0; / prioritas APK non -system harus 0 intent.setpriority (0);} addFilter (intent);}}Mari kita lihat fungsi AddFilter. Kode sumber fungsi adalah sebagai berikut:
Public void addFilter (f f) {// mfilters untuk menyimpan semua IntentFilter informasi mfilters.add (f); Ketik: "); if (nums == 0 && numt == 0) {register_intent_filter (f.actionsitTerTor (), mactintofilter," action: ");} if (numt! = 0) {filter (f, f.actionsitatratoror (), MtipeDactIntofilter, "Typedaction:");}}}}Ada beberapa struktur data lagi di sini.
Setelah memahami perkiraan struktur data, mari kita lihat implementasi fungsi register_intent_filter:
Private final int register_intent_filter (filter, iterator <string> i, arraymap <string, f [] dest, string, string, if (i == null) {return 0;} int num = 0; while (i.hasnext () ) {String name = ipxt ();Maka itu adalah fungsi addFilter lain, yang jelas merupakan fungsi beban berat.
Private Final Void AddFilter (ArrayMap <String, F [] Peta, String Name, Filter) {f [] array = Map.get (name); (name, array); if (i <n) {array [i] = filter;} else {f [] newa = newsray ((n*3)/2); n] = filter;Bahkan, kode masih sangat sederhana. Jika array F tidak ada, buat array dengan kapasitas 2 dan tetapkan elemen No. 0 ke filter.
Analisis kueri pencocokan niat
Klien melalui output fungsi QueryIntentActivities oleh ApplicationPackagemanager untuk memulai permintaan kueri ke Packagemanageerservice.
@Override Daftar publik <RevelIndInfo> queryIntentActivities (niat niat, bendera int) {return quryintititiesAser (intent, flags, mcontext.get userid ());} / ** @hide sama seperti di atas tetapi untuk pengguna tertentu* / @Override public public Daftar <ReperveInfo> queryIntentActivitiesAsuser (intent intent, int flags, inttimeid) ifneeded (mcontext.getContentResolver ()), flags, userid);} catch (remoteexception e) {throw runimeexception baru ("paket manajer telah mati", e); }Dapat dilihat bahwa implementasi nyata dari QueryIntentActivities ada di Packagemanagerservice.java.
Daftar Publik <ReperveInfo> QueryIntentActivities (Intent Intent, String ResolvedType, Int Flags, Inserid) {if (! Susermanager.exists)) collections.emptylist (); "); ComponentNetName comp = intent.getComponent (); if (comp == null) {if (intent.getSelector ()! = Null) {intent = intent.getSelect atau (); comp = intent.getComponent ();} } if (comp! = null) {// niat eksplisit, langsung dapatkan ActivityInfo Final List <VerveInfo> Daftar = ArrayInfo baru> (1); Null) {final resolveInfo ri = new resolveInfo (); null) {// Intent Intent Return Mactivities.QueryIntent (Intent, ResolvedType, Flags, UserID);} final Pa. nama mactivities return. QuryIntentForPackage (intent, resolvedType, flags, pkg.activities, userid);Dapat dilihat bahwa implementasi niat eksplisit relatif sederhana. Niat implisit yang disebut metode queryIntent.
Daftar Publik <ReperveInfo> QueryIntent (Intent Intent, String ResolvedType, Int Flags, Ins UserID) {if (! Susermanager.erid)) Return Null; )! = 0, userid);}Lanjutkan untuk melacak metode QueryIntent dari IntentResolver.java, kode sumbernya adalah sebagai berikut:
Daftar Publik <R> QueryIntent (Intent Intent, String ResolvedType, Boolean Defaultonly, Intimeric) {String Scheme = Intent.getscheme (); putaran operasi pencocokan f [] firstTypect = null; Slashpos = resolvedType.indexof ('/'); .length ()! = Slashpos+2 || diselesaikan Jenis kecocokan. ;} // jenis */ *selalu berlaku, tetapi kita hanya perlu melakukan ini // jika jenisnya tidak almedy */ *. ) !! ); ;} // Jika intert tidak menentukan data apa pun - baik tipe MIME atau // A URI - maka kita hanya akan mencari data yang cocok // if (resolute == null && intent.getAction ()! = Null) {firstTypecut = mactionToFilter.get (intent.get.get ()); SecondTypect! = NULL) {BuildResolvelist (Intent, Categories, Debug, DefaultOnly, Skema, Skema, S Econdtypecut, FinalSty , ThirdTypect, finalis, userid);} if (schemecut! = Null) {builtresolvelist (intent, cate gories, debug, defaultonly, resolvedType, skema, schemecut, finalis, userid);} sortresult (finalis);Proses pencocokan kueri spesifik diselesaikan oleh fungsi BuildResolvelist. Saya tidak memposting kode untuk implementasi kueri yang cocok.