Source code analysis of Intent Filter match process, intentmatch

Source: Internet
Author: User

Source code analysis of Intent Filter match process, intentmatch
Main Process

  • Main process: first match action, then match data, and finally match category
  • Sequence Chart
  • Simplified code

    public final int match(String action, String type, String scheme,        Uri data, Set<String> categories, String logTag) {    if (action != null && !matchAction(action)) {        return NO_MATCH_ACTION;    }    int dataMatch = matchData(type, scheme, data);    if (dataMatch < 0) {        return dataMatch;    }    String categoryMismatch = matchCategories(categories);    if (categoryMismatch != null) {        return NO_MATCH_CATEGORY;    }    return dataMatch;}
Sub-process match action
  • This sub-process is very simple. It only determines whether the action is included in the intent filter.
  • Code

    /** * Match this filter against an Intent's action.  If the filter does not * specify any actions, the match will always fail. * * @param action The desired action to look for. * * @return True if the action is listed in the filter. */public final boolean matchAction(String action) {    return hasAction(action);}public final boolean hasAction(String action) {    return action != null && mActions.contains(action);}
Match data
  • This sub-process is a little complex, and the code exports too much. Combined with the uri syntax, we can see [scheme:] scheme-specific-part [# fragment]/[scheme:] [// authority] [path] [? Query] [# fragment]
  • Code

    /*** Match this filter against an Intent's data (type, scheme and path ). if * the filter does not specify any types and does not specify any * schemes/paths, the match will only succeed if the intent does not * also specify a type or data. if the filter does not specify any schemes, * it will implicitly match intents with no scheme, or the schemes "content:" * or "file:" (basically shortming a MI ME-type only match ). if the filter * does not specify any MIME types, the Intent also must not specify a MIME * type. ** <p> Be aware that to match against an authority, you must also specify a base * scheme the authority is in. to match against a data path, both a scheme * and authority must be specified. if the filter does not specify any * types or schemes that it matches against, it is conside Red to be empty * (any authority or data path given is ignored, as if it were empty as * well ). ** <p> <em> Note: MIME type, Uri scheme, and host name matching in the * Android framework is case-sensitive, unlike the formal RFC definitions. * As a result, you shoshould always write these elements with lower case letters, * and normalize any MIME types or Uris you receive from * outside of Android to e Nsure these elements are lower case before * supplying them here. </em> </p> ** @ param type The desired data type to look for, as returned by * Intent. resolveType (). * @ param scheme The desired data scheme to look for, as returned by * Intent. getScheme (). * @ param data The full data string to match against, as supplied in * Intent. data. ** @ return Returns either a valid match constant (a combinati On of * {@ link # MATCH_CATEGORY_MASK} and {@ link # MATCH_ADJUSTMENT_MASK }), * or one of the error codes {@ link # NO_MATCH_TYPE} if the type didn't match * or {@ link # NO_MATCH_DATA} if the scheme/path didn't match. ** @ see # match */public final int matchData (String type, String scheme, Uri data) {final ArrayList <String> types = mDataTypes; final ArrayList <String> schemes = mDataSchemes; int match = MATCH_CATEGORY_EMPTY; // 1. if the type scheme of the filter is empty and the type data of the intent is empty, the filter matches. // otherwise, the filter does not match if (types = null & schemes = null) {return (type = null & data = null )? (MATCH_CATEGORY_EMPTY + MATCH_ADJUSTMENT_NORMAL): NO_MATCH_DATA);} if (schemes! = Null) {// 2. if the schemes of the filter is not empty and the scheme of the intent is included in it, the system will make a further judgment. // otherwise, if (schemes. contains (scheme! = Null? Scheme: "") {match = MATCH_CATEGORY_SCHEME;} else {return NO_MATCH_DATA;} final ArrayList <PatternMatcher> schemeSpecificParts = partition; if (schemeSpecificParts! = Null) {// 3. If schemeSpecificParts is not empty, use SchemeSpecificPart of data to perform matching // and modify the value of match. Uri Syntax: [scheme:] scheme-specific-part [# fragment]/[scheme:] [// authority] [path] [? Query] [# fragment] match = hasDataSchemeSpecificPart (data. getSchemeSpecificPart ())? MATCH_CATEGORY_SCHEME_SPECIFIC_PART: NO_MATCH_DATA;} if (match! = MATCH_CATEGORY_SCHEME_SPECIFIC_PART) {// If there isn' t any matching ssp, we need to match an authority. final ArrayList <AuthorityEntry> authorities = mDataAuthorities; // 4. if schemeSpecificPart (ssp) does not match, it must match authority // that is, it is used to determine the part of the host port if (authorities! = Null) {int authMatch = matchDataAuthority (data); if (authMatch> = 0) {// 5. if the host port matches, the final ArrayList <PatternMatcher> paths = mDataPaths; if (paths = null) {match = authMatch;} else if (hasDataPath (data. getPath () {match = MATCH_CATEGORY_PATH;} else {return NO_MATCH_DATA ;}} else {// The host port does not match return NO_MATCH_DATA ;}}} // If neither an ssp nor an authority matched, We're re done. if (match = NO_MATCH_DATA) {return NO_MATCH_DATA ;}} else {// The schemeSpecificParts of the filter is not empty and matches the SchemeSpecificPart of the intent, // If scheme is not "content" "file", it does not match; otherwise, it will continue to be judged. // Special case: match either an Intent with no data URI, // or with a scheme: URI. this is to give a convenience for // the common case where you want to deal with data in a // content provider, which is done by ty Pe, and we don't want // to force everyone to say they handle content: or file: URIs. if (scheme! = Null &&! "". Equals (scheme )&&! "Content". equals (scheme )&&! "File". equals (scheme) {return NO_MATCH_DATA ;}} if (types! = Null) {// 6. type: MIME // if the type is not empty, it determines whether the type of the filter and intent is inclusive. Otherwise, it does not match if (findMimeType (type) {match = MATCH_CATEGORY_TYPE ;} else {return NO_MATCH_TYPE;} else {// If no MIME types are specified, then we will only match against // an Intent that does not have a MIME type. if (type! = Null) {// If the filter's types set is null, but the intent is not empty, return NO_MATCH_TYPE;} return match + MATCH_ADJUSTMENT_NORMAL ;}
Match category
  • This sub-process is not complex. It only determines whether the intent category is completely included in the filter.
  • Code

    /*** Match this filter against an Intent's categories. each category in * the Intent must be specified by the filter; if any are not in the * filter, the match fails. ** @ param categories The categories encoded in the intent, as returned by * Intent. getCategories (). ** @ return If all categories match (success), null; else the name of the * first category that didn't match. */public final String MatchCategories (Set <String> categories) {if (categories = null) {return null; // matched successfully} Iterator <String> it = categories. iterator (); if (mCategories = null) {// filter does not have Categories; if intent has one, return it. hasNext ()? It. next (): null;} while (it. hasNext () {// filter has Categories. intent Categories must all be included in the filter before final String category = it. next (); if (! MCategories. contains (category) {return category ;}} return null ;}
Summary
  • The matching process is generally divided into three steps: match action-> match data-> match categories. If any step fails, no subsequent processing is performed.
  • Match action indicates whether the action that matches the intent is included in the filter's actions.
  • The idea of match data is related to the uri syntax Composition [scheme:] scheme-specific-part [# fragment]
    • Determine whether the filter and intent's types (MIMI) schemes are all null. If yes, the value MATCH_CATEGORY_EMPTY is used. Otherwise, continue.
    • Match scheme again. If no match exists, it ends. If match exists, it continues.
    • SchemeSpecificPart. If it matches, the final type (MIME) is determined.
    • SchemeSpecificPart. If not
      • Match the host port. If the port is successfully matched, the operation continues. Otherwise, the operation does not match.
      • If the path part is matched, the operation continues. Otherwise, the operation does not match.
    • Finally, type (MIME) is matched.
  • Match categories is used to determine whether all the category of intent contains the category of filter.
  • Uri syntax Composition [scheme:] scheme-specific-part [# fragment]/[scheme:] [// authority] [path] [? Query] [# fragment]
Reference
  • Http://www.cjsdn.net/doc/jdk50/java/net/URI.html

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.