مقدمة
تقدم هذه المقالة أساسًا Android Ntent ، وتحلل عملية مطابقة الاستعلام النية من منظور رمز مصدر Android.
مقدمة تين
تعني Intent الصينية "النية" ، والنية مفهوم مجردة للغاية. لذلك ، يحدد نظام Android بوضوح أنه يمكن قياس النية بواسطة جانبين.
السمات الرئيسية: بما في ذلك الإجراء والبيانات. من بينها ، يتم استخدام الإجراء لتمثيل نية الإجراء التي تعبر عنها النية ، ويتم استخدام البيانات لتمثيل البيانات التي تديرها الإجراء.
السمات الثانوية: بما في ذلك الفئة والنوع والمكون والإضافات. تمثل الفئة الفئة ، ويمثل النوع نوع البيانات للبيانات ، ويمكن استخدام المكونات لتحديد استجابة نية محددة (على سبيل المثال ، تحديد نية أن تكون فئة فئة تحت الحزمة) ، ويتم استخدام الإضافات لحمل الآخرين معلومة.
هناك نوعان رئيسيان من النية في نظام Android ، والذي يوضح النية (النية الصريحة) والنية المخفية (نية ضمنية).
نية صريحة: يشير هذا النوع من النوايا بوضوح إلى المكون الذي يجب العثور عليه. في الكود ، يمكنك قفل الكائن الهدف من خلال setClassName أو setComponent.
النية الضمنية: لا يشير هذا النوع من النوايا بوضوح إلى المكون الذي يجب بدء تشغيله ، ولكنه يعين الإجراء والبيانات والفئة لجعل شاشة النظام المكون المناسب.
بعد ذلك ، اكتب مثالين رمزين لتقديم نية expllicit وتضمين inent. الأول هو نية صريحة:
private void startExplicitIntEntWithComponent () {intent intent = new intent () ؛ intent) ؛} private void startExplicitIntWithClassName () {intent intent = new intent () ؛ومع ذلك ، من الكود المصدري ، وجدت أن setClassName استخدم أيضًا اسم المكون لتحقيق نية صريحة. رمز المصدر كما يلي:
النية العامة setClassName (سلسلة packagename ، string className) {mComponent = new componentName (packagename ، className) ؛ثم ، مثال رمز على نية ضمنا. أستخدم هنا نشاطًا لتمييز بعض مرشح النية كمثال ، ثم أكتب نية لبدءه.
<Activity Android: name = ". sendIntEnttype"> <Stent-Filter> <Action Android: Name = "JustTest"/> <category android: name = "justcategory" </intent-f ilter> </uvice>
في AndroidManifest.xml ، يتم إضافة المرشح القصد إلى فئة SendIntentType. الرمز الذي يبدأ النشاط كما يلي:
private void startImplictInt ()
في عملية مطابقة عملية نية ضمنا ، سيتم استخدام العناصر الثلاثة المدرجة في مرشح القصد كمعيار مرجعي.
إدارة معلومات النشاط
من التحليل أعلاه ، يمكن ملاحظة أنه في عملية مطابقة النظام ، تحتاج أولاً إلى إدارة جميع معلومات النشاط في النظام الحالي. تم جمع معلومات النشاط وإدارتها بواسطة Packagemanagerservice عند مسح APK. رمز المصدر ذي الصلة كما يلي:
// معالجة المعلومات الجماعية المرفقة n = pkg.activities.size () ؛ a .info.processName = FixProcessName (pkg.applicationInfo.ProcessName ، A.Info.ProcessName ، pkg.applicationInfo.uid) ؛
في الكود أعلاه ، هناك هيكلان مهمان للبيانات ، كما هو موضح في الشكل أدناه.
جنبا إلى جنب مع بنية البيانات للرمز والشكل أعلاه ، يمكن رؤيته:
Macitivity هو نوع ActivityIntresolver. يوجد أيضًا متغير Mactivies داخل بنية البيانات هذه.
يتم حفظ جميع المعلومات المتعلقة بالمعلومات التي تم الحصول عليها من APK (بما في ذلك علامة IntentFilter المعلنة في XML) بواسطة PackageParser.Activity.
يستدعي الكود السابق وظيفة AddActivity لإكمال دعاية المعلومات الخاصة. رمز دالة الإدمان على النحو التالي:
الإضافات النهائية النهائية (PackageParser.Activity A ، نوع السلسلة) int j = 0 ؛ / يجب أن تكون أولوية APK الخاصة بـ APK 0 intent.setPriority (0) ؛} addFilter (intent) ؛}}
دعنا نلقي نظرة على وظيفة AddFilter. رمز مصدر الوظيفة كما يلي:
public void addfilter (f f) {// mfilters لحفظ جميع معلومات intentFilter mfilters.Add (f) ؛ اكتب: ") ؛ if (nums == 0 && numt == 0) {register_intent_filter (f.ActionsIterTor () ، mactintofilter ،" الإجراء: ") ؛ () ، mtypedactintofilter ، "typedaction:") ؛}}}}هناك العديد من هياكل البيانات هنا.
بعد فهم بنية البيانات التقريبية ، دعونا نلقي نظرة على تنفيذ وظيفة 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 ؛ icher (i.hasNext () ) {string name = ipxt () ؛بعد ذلك ، فهي وظيفة addfilter أخرى ، والتي من الواضح أنها حمولة ثقيلة.
addfilter النهائي الخاص (arraymap <string ، f [] اسم السلسلة ، مرشح) {f [] Array = map.get (name) ؛ (الاسم ، صفيف) ؛ if (i <n) {array [i] = filter ؛} {f [] newa = newsray ((n*3)/2) ؛ n] = filter ؛في الواقع ، لا يزال الرمز بسيطًا للغاية. إذا لم يكن الصفيف F موجودًا ، فقم بإنشاء صفيف بسعة 2 وتعيين العنصر رقم 0 للمرشح.
نيتينت مطابقة تحليل الاستعلام
العميل من خلال إخراج QueryIntActivities بواسطة ApplicationPackageManager لبدء طلب استعلام إلى SPACKEMANAGEERSERVICE.
قائمة Override العامة <SolveInfo> QueryIntentActivities (نية النية ، أعلام int) {return QuryIntititiesAser (النية ، الأعلام ، mcontext.get userid ()) قائمة <SolveInfo> QueryIntActivitiesAsaSer (النية النية ، أعلام int ، intimeid) ifneeded (mcontext.getContentResolver ()) ، الأعلام ، المستخدم) ؛ }يمكن ملاحظة أن التنفيذ الحقيقي لـ QueryIntActivities موجود في Packagemanagerservice.java.
القائمة العامة <SolveInfo> QueryIntActivities (النية النية ، سلسلة ResolvedType ، int flags ، int user) {if (! susermanager.exists)) ") ؛ componentnetname comp = intent.getComponent () ؛ if (comp == null) {if (intent.getSelector ()! = null) {intent = intent.getselect أو () ؛ comp = intent.getComponent () ؛} } if (comp! = null) {// explicit ، الحصول على القائمة النهائية للنشاط المقابل <SolveInfo> null) {Final ResolveInfo Ri = New ResolveInfo () ؛ NULL) {// الضمنية النية المرجعية. اسم النية العائليةيمكن ملاحظة أن تنفيذ القصد الصريح بسيط نسبيًا. نية ضمنية تسمى طريقة QueryIntent.
القائمة العامة <SolveInfo> QueryIntent (NEUNTENT ، string resolvedtype ، int flags ، int user) {if (! susermanager.erid) )!استمر في تتبع طريقة QueryIntent لـ intentresolver.java ، رمز المصدر هو كما يلي:
القائمة العامة <r> QueryIntent (النية النية ، سلسلة ResolvedType ، Boolean Defaultonly ، {string scheme = intent.getscheme () ؛ جولات من عملية Ferytypecut = NULL ؛ slashpos = resolvedType.indexof ('/') ؛ .length ()! = slashpos+2 || اكتب المطابقات. ؛} // أي أنواع */ *تنطبق دائمًا ، لكننا بحاجة فقط إلى القيام بذلك // إذا لم يكن النوع almedy */ *. ) !! = NULL) ) ؛ ؛} // إذا كان intert لا يحدد أي بيانات - إما نوع mime أو // uri - فسنبحث فقط عن البيانات الفارغة المتطابقة. null) {firsttypecut = mactiontofilter.get (intent.get ()) ؛ SecondTypecut! = NULL) ، ThirdTypecut ، النهائي ، userId) ؛} if (schemecut! = null) {builtresolvelist (neintent ، cate gories ، debug ، defaultonly ، retervedtype ، schemيتم الانتهاء من عملية مطابقة الاستعلام المحددة من خلال وظيفة BuildResolvelist. أنا لا أقوم بنشر رمز التنفيذ المطابق للاستعلام.