android中URI到底是什么?

前几天研究了下SDK中提供的NotePad例子,从这个例子中能够看到activity之间使用intent跳转的机制,而当时没看明白URI到底是怎么个东西。今天在看《ProAndroid》时,从作者那得到启发,终于明白URI是什么了。

以这个NotePad为例,

 

在NotePad.java中有如下两个定义:

public static final String AUTHORITY = "com.google.provider.NotePad";

public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/notes");

 

引用作者原话:

Actually, the URI, or the authority portion of the URI, is configured in the AndroidManifest.xml file as a content provider:
android:authorities="com.google.provider.NotePad"/>
When Android sees a URI that needs to be resolved, it pulls out the authority portion of it and looks up the ContentProvider class configured for the authority.In the Notepad application, the AndroidManifest.xml file contains a class called NotePadProvider configured for the com.google.provider.NotePad authority.

 

作者的意思是当android要处理和一个URI相关的操作时,android框架会根据URI中的authority内容,在AndroidManifest.xml (一个或多个)中查找拥有相同authority内容的provider,将二者对应起来。在NotePad这个例子中定义了 CONTENT_URI 和NotePadProvider这个类有对应关系。

我设置了几个断点,并实际调试了下来验证下面这段代码中managedQuery() 的URI参数在传递过程中,最终是交给NotePadProvider类中的query()方法处理的!! ^ ^

 

//NotesList.java

public class NotesList extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
Intent intent = getIntent();
if (intent.getData() == null) {
intent.setData(Notes.CONTENT_URI);//这里设置好了intent要处理的URI
}
getListView().setOnCreateContextMenuListener(this);

//managedQuery()第一个参数即为上面设置的URI,我想要在这里跟踪进去
Cursor cursor = managedQuery(getIntent().getData(),PROJECTION, null, null,Notes.DEFAULT_SORT_ORDER);
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.noteslist_item, cursor, new String[] { Notes.TITLE },
new int[] { android.R.id.text1 });
setListAdapter(adapter);
}
}

 

程序跑起来,跟踪进managedQuery(),会跳到

ContentResolver.class的

 public final Cursor query(Uri uri, String[] projection,
            String selection, String[] selectionArgs, String sortOrder) {
        IContentProvider provider = acquireProvider(uri);//这里是关键,ContentResolver的query,会根据URI获得provider!

        if (provider == null) {
            return null;
        }
        try {
            Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);//传说中的反向调用!
            if(qCursor == null) {
                releaseProvider(provider);
                return null;
            }
            //Wrap the cursor object into CursorWrapperInner object
            return new CursorWrapperInner(qCursor, provider);
        }

..

}

程序继续运行,如果在NotePadProvider.java中的query中设置断点,你会发现程序在断点处停住。

 

这就证明了 android框架根据URI中的authority找到对应的provider,由provider根据完整的URI内容再详细处理,比如去更新数据库某一条记录。

 

 

你可能感兴趣的:(android)