与Android的UriMatcher问题 [英] Problems with Android's UriMatcher

查看:133
本文介绍了与Android的UriMatcher问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在回答我的previous问题,有人指出,有一些片状(由于缺乏一个更好的词)固有的Andr​​oid类UriMatcher。任何人都可以找出已知问题UriMatcher?我设计的内容提供商依靠UriMatcher正确地配合我尤里斯(而不是错误的,我想)。是否有解决方法的已知问题?或者是有匹配尤里斯一个更好的策略?

In an answer to a previous question of mine someone indicated that there is some flakiness (for lack of a better word) inherent in the Android class UriMatcher. Can anyone pinpoint the known issues with UriMatcher? I'm designing a Content Provider that relies on UriMatcher to match my Uris correctly (as opposed to incorrectly I suppose). Are there workarounds to the known issues? Or is there a better strategy for matching Uris?

例如:

下面是code设置我UriMatcher

Here is the code setting my UriMatcher

private static final int MEMBER_COLLECTION_URI = 1;
private static final int MEMBER_SINGLE_URI = 2;
private static final int SUBMATERIAL_COLLECTION_URI = 3;
private static final int SUBMATERIAL_SINGLE_URI = 4;
private static final int JOBNAME_COLLECTION_URI = 5;
private static final int JOBNAME_SINGLE_URI = 6;
private static final int ALL_MEMBERS_URI = 7;
private static final int ALL_SUBMATERIAL_URI = 8;

static
{
        //return the job and fab for anything matching the provided jobName
        // JobNames/jobName
        uriMatcher.addURI(JobMetaData.AUTHORITY, "JobNames/*/",
                          JOBNAME_SINGLE_URI);
        //return a collection of members
        // jobName/member/attribute/value
        uriMatcher.addURI(JobMetaData.AUTHORITY, "*/member/*/*/",
                          MEMBER_COLLECTION_URI);
        //return a single member
        // jobName/member/memberNumber
        uriMatcher.addURI(JobMetaData.AUTHORITY, "*/member/*/",
                          MEMBER_SINGLE_URI);
        //return a collection of submaterial
        // jobName/submaterial/attribute/value
        uriMatcher.addURI(JobMetaData.AUTHORITY, "*/submaterial/*/*",
                          SUBMATERIAL_COLLECTION_URI);
        //return a single piece of submaterial
        // jobName/submaterial/GUID
        //GUID is the only way to uniquely identify a piece of submaterial    
        uriMatcher.addURI(JobMetaData.AUTHORITY, "*/submaterial/*",
                          SUBMATERIAL_SINGLE_URI);
        //Return everything in the member and submaterial tables
        //that has the provided attribute that matches the provided value
        // jobName/attribute/value
        //not currently used
        uriMatcher.addURI(JobMetaData.AUTHORITY, "JobNames/",
                          JOBNAME_COLLECTION_URI);
        //return all members in a job
        uriMatcher.addURI(JobMetaData.AUTHORITY, "*/members/",
                          ALL_MEMBERS_URI);

}

添加其他网址:

private static final int MEMBER_COLLECTION_URI = 1;
private static final int MEMBER_SINGLE_URI = 2;
private static final int SUBMATERIAL_COLLECTION_URI = 3;
private static final int SUBMATERIAL_SINGLE_URI = 4;
private static final int JOBNAME_COLLECTION_URI = 5;
private static final int JOBNAME_SINGLE_URI = 6;
private static final int ALL_MEMBERS_URI = 7;
private static final int ALL_SUBMATERIAL_URI = 8;
//ADDITIONAL URI
private static final int REVERSE_URI = 9;

static
{
        //return the job and fab for anything matching the provided jobName
        // JobNames/jobName
        uriMatcher.addURI(JobMetaData.AUTHORITY, "JobNames/*/",
                          JOBNAME_SINGLE_URI);
        //return a collection of members
        // jobName/member/attribute/value
        uriMatcher.addURI(JobMetaData.AUTHORITY, "*/member/*/*/",
                          MEMBER_COLLECTION_URI);
        //return a single member
        // jobName/member/memberNumber
        uriMatcher.addURI(JobMetaData.AUTHORITY, "*/member/*/",
                          MEMBER_SINGLE_URI);
        //return a collection of submaterial
        // jobName/submaterial/attribute/value
        uriMatcher.addURI(JobMetaData.AUTHORITY, "*/submaterial/*/*",
                          SUBMATERIAL_COLLECTION_URI);
        //return a single piece of submaterial
        // jobName/submaterial/GUID
        //GUID is the only way to uniquely identify a piece of submaterial    
        uriMatcher.addURI(JobMetaData.AUTHORITY, "*/submaterial/*",
                          SUBMATERIAL_SINGLE_URI);
        //Return everything in the member and submaterial tables
        //that has the provided attribute that matches the provided value
        // jobName/attribute/value
        //not currently used
        uriMatcher.addURI(JobMetaData.AUTHORITY, "JobNames/",
                          JOBNAME_COLLECTION_URI);
        //return all members in a job
        uriMatcher.addURI(JobMetaData.AUTHORITY, "*/members/",
                          ALL_MEMBERS_URI);
        //ADDITIONAL URI
        uriMatcher.addURI(JobMetaData.AUTHORITY, "*/reverse/*",
                          REVERSE_URI);

}

和最后一个开放的我们正在使用无法识别:     uriMatcher.match(URI)

And the last Uri is not recognized using: uriMatcher.match(uri)

在previous问题(前面提到的),有人建议我将违规URI来调用到UriMatcher.put(字符串,INT)的顶部。这解决了previous问题(给我留下了不好的味道在我嘴里)。试图在当前第一个URI(JOBNAME_SINGLE_URI)将无法识别该code结果相同的解决方案。我相当肯定,这个问题是不是在我的code(我已经成功地创建之前使用URI和调试所有的问题,他们对这一问题工作的ContentProvider),倒像是一个问题,乌里匹配的Andr​​oid。

On the previous question (mentioned earlier) it was recommended that I move the offending Uri to the top of the calls to UriMatcher.put(String, int). That solved the previous problem (and left me with a bad taste in my mouth). Trying the same solution with this code results in the current first Uri (JOBNAME_SINGLE_URI) going unrecognized. I'm fairly sure that the issue isn't in my code (I've managed to create a working ContentProvider utilizing Uris and debug all of the problems with them prior to this issue), but rather is an issue with Uri matching in Android.

更新:

public final static String AUTHORITY = "dsndata.sds2mobile.jobprovider";

示例URI:
    内容://dsndata.sds2mobile.jobprovider/SDS2MobileDemo/reverse/C_1

Sample Uri:
content://dsndata.sds2mobile.jobprovider/SDS2MobileDemo/reverse/C_1

推荐答案

有说是至关重要的理解UriMatcher的匹配机制三个规则未据可查,但是:

There are three rules that aren't well documented but that are crucial to understanding the matching mechanism of UriMatcher:

  1. UriMatcher尝试匹配整个乌里对抗的格局。就像火柴()java.util.regex.Matcher中的方法,只有当整个区域序列匹配的匹配器模式(与find()方法,对部分匹配返回true)返回true。
  2. 通配符被应用到只有一个路径段,这意味着*或SDS2MobileDemo / *永远比不上SDS2MobileDemo /后退/ C_1但是* / * / *或* / * / C_1会。
  3. 一旦它找到一个匹配的路径段就不会找到任何替代匹配特定的路径段。

下面是使用以下URL一些例子:内容://dsndata.sds2mobile.jobprovider/SDS2MobileDemo/reverse/C_1

Here are some examples using the following url: content://dsndata.sds2mobile.jobprovider/SDS2MobileDemo/reverse/C_1

前两个规则是容易理解的:

The first two rules are easy to understand:

  • SDS2MobileDemo / * / *将匹配
  • * /后退/ *将匹配
  • * / *不会匹配,因为它匹配的只有两个路径段
  • 在SDS2MobileDemo不会匹配,因为它仅匹配一个路径段

第三条规则是有点难以理解。 如果在此准确顺序添加以下尤里斯:

The third rule is a little harder to understand. If you add the following Uris in this exact order:

  • * /错/ C_1
  • SDS2MobileDemo /后退/ C_1

那么就不会找到一个匹配,因为这意味着以下(伪)code:

then it won't find a match because that translates into the following (pseudo) code:

if ("*".matches("SDS2MobileDemo")) {    
    // tries to match the other parts but fails    
}
else if ("SDS2MobileDemo".matches("SDS2MobileDemo")) {
    // will never be executed
}

如果您反转(伪)code为顺序:

If you reverse the order the (pseudo) code becomes:

if ("SDS2MobileDemo".matches("SDS2MobileDemo")) {    
    // tries to match the other parts and succeeds    
}    
else if ("*".matches("SDS2MobileDemo")) {    
    // will never be executed    
}

现在,只要原来的问题去。 SDS2MobileDemo /后退/ C_1将获得相匹配的* /后退/ *而不是如JobNames /后退/ C_1,因为其中一个将下井JobNames / *路径... 也很明显,移动* /后退/ *顶端是解决不了问题,因为所有其他模式不是以*不匹配了。 这确实没有说的是正确的解决方案是什么,只要它是未知的应该匹配该模式,这尤里斯。

Now as far as the original question goes. SDS2MobileDemo/reverse/C_1 will get matched by */reverse/* but not e.g. JobNames/reverse/C_1 because that one will go down the JobNames/* path... Also it's clear that moving */reverse/* to the top isn't the solution because all other patterns not starting with * won't match any more. There's really no telling what the correct solution is as long as it's unknown which patterns should match which Uris.

这篇关于与Android的UriMatcher问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆