Android开发简单实例(第二篇)


Notepad运行示例:

Android环境搭配好后,继续昨天的简单运用后,今天运行一个Notepad实例,在加之对Android的一些理解。
1。 在运行一个Android实例后,可以看到后台的日志:
    Android Launch!
   adb is running normally.
   Performing com.mydream.NotesList activity launch
   Launching a new emulator with Virtual Device 'androidStudy'
   New emulator found: emulator-5554
   Waiting for HOME ('android.process.acore') to be launched...
   HOME is up on device 'emulator-5554'
   Uploading AndroidNotepad.apk onto device 'emulator-5554'
   Installing AndroidNotepad.apk...
   Success!
   Starting activity com.mydream.NotesList on device
   ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.mydream/.NotesList }
开启了一个Android的一个活动NoteList。
2。 在AndroidManifest.xml文件中声明了很多Activity,其中有个就是NotesList,在这个节点下有个<intent-filter>的子节点:
       <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
其中Action的名字为MAIN,这代表程序的入口点,系统找到后就会创建一个Activity运行,否则不会运行。Notelist主要是显示日志列表,这些日志数据都存放在Sqlite数据库中,在NotesList的Java文件中有两个私有数据:
private static final String[] PROJECTION = new String[] {
            Notes._ID, // 0 "_id"
            Notes.TITLE, // 1 "title"
    }
0代表id字段,1代表title字段。
private static final int COLUMN_INDEX_TITLE = 1;
代表了title的索引。
之后进入的方法是onCreate,因为NotesList这个activity是系统调用的,此时的intent是不带数据和操作类型的,系统只是在其中指明了目标组件是Notelist,所以这里把”content:// com.google.provider.NotePad/notes”保存到intent里面,这个URI地址指明了数据库中的数据表名(参见以后的NotePadProvider类),也就是保存日志的数据表notes。
1 setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);设置按键处理快捷方式。
2 getListView().setOnCreateContextMenuListener(this);ListView注册 createContextMenu监听器。 
3 Cursor cursor = managedQuery(getIntent().getData(), PROJECTION, null, null,
                Notes.DEFAULT_SORT_ORDER);执行一个查询,返回一个光标结果。这里第一个参数就是上面设置的” content:// com.google.provider.NotePad/notes”这个URI,即notes数据表。PROJECTION 字段指明了结果中所需要的字段,Notes.DEFAULT_SORT_ORDER 指明了结果的排序规则。实际上managedQuery并没有直接去查询数据库,而是通过Content Provider来完成实际的数据库操作,这样就实现了逻辑层和数据库层的分离。
4 SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.noteslist_item, cursor,
                new String[] { Notes.TITLE }, new int[] { android.R.id.text1 });
        setListAdapter(adapter);
查询出日志列表后,构造一个CursorAdapter,并将其作为List View的数据源,从而在界面上显示出日志列表。可以看到,第二个参数是R.layout.noteslist_item,打开对应的noteslist_item.xml文件。
4。 活动列表查询之后,处理单个日志的单击事件是onListItemClick方法,首先通过”content:// com.google.provider.NotePad/notes”和日志的id 号拼接得到选中日志的真正URI,然后创建一个新的Intent,其操作类型为Intent.ACTION_EDIT,数据域指出待编辑的日志URI。startActivity(new Intent(Intent.ACTION_EDIT, uri))执行后会发生什么事情呢?这时候Android系统就跳出来接管了,它会根据intent中的信息找到对应的activity,在这里找到的是NoteEditor这个activity,然后创建这个activity的实例并运行。那么,Android又是如何找到NoteEditor这个对应的activity的呢?这就是intent发挥作用的时刻了。
             new Intent(Intent.ACTION_EDIT, uri)
5。 Androidmanfest.xml中的provider:
<provider android:name="NotePadProvider"
            android:authorities="com.google.provider.NotePad"
        />
进入activity选择机制了:
系统从intent中获取道uri,得到了content://com.google.provider.NotePad/notes/1,去掉开始的content:标识,得到com.google.provider.NotePad/notes/1,然后获取前面的com.google.provider.NotePad,然后就到Androidmanfest.xml中找到authorities为com.google.provider.NotePad的provider,这个就是后面要讲的contentprovider,然后就加载这个content provider。
在这里是NotePadProvider,然后调用NotePadProvider的gettype函数,并把上述URI传给这个函数,函数返回URI所对应的类型(这里返回Notes.CONTENT_ITEM_TYPE,代表一条日志记录,而CONTENT_ITEM_TYPE = " vnd.android.cursor.item/vnd.google.note ")。
然后系统使用获得的" vnd.android.cursor.item/vnd.google.note "和”android.intent.action.EDIT”到androidmanfest.xml中去找匹配的activity.
正好NoteEditor这个activity的intent-filter满足上述条件,这样就找到了NoteEditor。于是系统加载这个类并实例化,运行,然后就到了NoteEditor的OnCreate函数中。
注:1 第一次启动模拟器会比较慢,但以后就别关闭模拟器了,修改代码,调试都不需要再次启动的,直接修改后run或debug就是。
    2 出现INSTALL_FAILED_CONFLICTING_PROVIDER
      mobileFinder]Please check logcat
      mobileFinder]Launch canceled!
    原因就是有在用Provider造成的,你换个别的名字就可以了。




猜你喜欢

转载自handonghandong.iteye.com/blog/707608