`
dato0123
  • 浏览: 970282 次
文章分类
社区版块
存档分类
最新评论

Android实例剖析笔记(一)

 
阅读更多

开卷语

俗话说,熟读唐诗三百首,不会作诗也会吟。最近收集了很多Android的示例代码,从这些代码的阅读和实验中学习到很多知识,从而产生写这个系列的打算,目标就是一步步跟着实例进行动手实作,真正从中体会和学习Android开发。
本文是这个系列的第一篇,目标是
Android自带的一个范例程序:记事本,将分为四篇文章进行详细介绍。

预备知识

搭建开发环境,尝试编写”Hello World”,了解Android的基本概念,熟悉AndroidAPI(官方文档中都有,不赘述)

程序截图

先来简单了解下程序运行的效果








程序入口点

类似于win32程序里的WinMain函数,Android自然也有它的程序入口点。它通过在AndroidManifest.xml文件中配置来指明,可以看到名为NotesListactivity节点下有这样一个intent-filter,actionandroid.intent.action.MAIN,

Category指定为 android.intent.category.LAUNCHER,这就指明了这个activity是作为入口activity,系统查找到它后,就会创建这个activity实例来运行,若未发现就不启动(你可以把MAIN改名字试试)

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>

NotesList详解

就从入口点所在的activity(见图1)开始,可以看到这个activity最重要的功能就是显示日志列表。这个程序的日志都存放在Sqlite数据库中,因此需要读取出所有的日志记录并显示。

先来看两个重要的私有数据,第一个PROJECTION字段指明了日志列表所关注的数据库中的字段(即只需要IDTitle就可以了)。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->privatestaticfinalString[]PROJECTION=newString[]{
Notes._ID,
//0
Notes.TITLE,//1
};

第二个字段COLUMN_INDEX_TITLE指明title字段在数据表中的索引。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->privatestaticfinalintCOLUMN_INDEX_TITLE=1;

然后就进入第一个调用的函数onCreate

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->Intentintent=getIntent();
if(intent.getData()==null)
{
intent.setData(Notes.CONTENT_URI);
}

因为NotesList这个activity是系统调用的,此时的intent是不带数据和操作类型的,系统只是在其中指明了目标组件是Notelist,所以这里把”content:// com.google.provider.NotePad/notes”保存到intent里面,这个URI地址指明了数据库中的数据表名(参见以后的NotePadProvider类),也就是保存日志的数据表notes

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->Cursorcursor=managedQuery(getIntent().getData(),PROJECTION,null,null,Notes.DEFAULT_SORT_ORDER);

然后调用managedQuery函数查询出所有的日志信息,这里第一个参数就是上面设置的” content:// com.google.provider.NotePad/notes”这个URI,即notes数据表。PROJECTION 字段指明了结果中所需要的字段,Notes.DEFAULT_SORT_ORDER 指明了结果的排序规则。实际上managedQuery并没有直接去查询数据库,而是通过Content Provider来完成实际的数据库操作,这样就实现了逻辑层和数据库层的分离。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->SimpleCursorAdapteradapter=newSimpleCursorAdapter(this,R.layout.noteslist_item,cursor,
newString[]{Notes.TITLE},newint[]{android.R.id.text1});
setListAdapter(adapter);

查询出日志列表后,构造一个CursorAdapter,并将其作为List View的数据源,从而在界面上显示出日志列表。可以看到,第二个参数是R.layout.noteslist_item,打开对应的noteslist_item.xml文件,

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><TextViewxmlns:android="http://schemas.android.com/apk/res/android"
android:id
="@android:id/text1"
android:layout_width
="fill_parent"
android:layout_height
="?android:attr/listPreferredItemHeight"
android:textAppearance
="?android:attr/textAppearanceLarge"
android:gravity
="center_vertical"
android:paddingLeft
="5dip"
android:singleLine
="true"
/>

就是用来显示一条日志记录的TextView,最后两个字段指明了实际的字段映射关系,通过这个TextView来显示一条日志记录的title字段。

处理选择日志事件

既然有了日志列表,就自然要考虑如何处理某一条日志的单击事件,这通过重载onListItemClick方法来完成,

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->@Override
protectedvoidonListItemClick(ListViewl,Viewv,intposition,longid){
Uriuri
=ContentUris.withAppendedId(getIntent().getData(),id);

Stringaction
=getIntent().getAction();
if(Intent.ACTION_PICK.equals(action)||Intent.ACTION_GET_CONTENT.equals(action)){
//Thecalleriswaitingforustoreturnanoteselectedby
//theuser.Thehaveclickedonone,soreturnitnow.
setResult(RESULT_OK,newIntent().setData(uri));
}
else{
//Launchactivitytoview/editthecurrentlyselecteditem
startActivity(newIntent(Intent.ACTION_EDIT,uri));
}
}

首先通过”content:// com.google.provider.NotePad/notes”和日志的id 号拼接得到选中日志的真正URI,然后创建一个新的Intent,其操作类型为Intent.ACTION_EDIT,数据域指出待编辑的日志URI(这里只分析else块)。

Intent深度剖析

那么,上面这句startActivity(new Intent(Intent.ACTION_EDIT, uri))执行后会发生什么事情呢?这时候Android系统就跳出来接管了,它会根据intent中的信息找到对应的activity,在这里找到的是NoteEditor这个activity,然后创建这个activity的实例并运行。

那么,Android又是如何找到NoteEditor这个对应的activity的呢?这就是intent发挥作用的时刻了。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->newIntent(Intent.ACTION_EDIT,uri)

这里的Intent.ACTION_EDIT=” android.intent.action.EDIT”,另外通过设置断点,我们看下这里的uri值:


可以看到选中的日志条目的URI是:content://com.google.provider.NotePad/notes/1

然后我们再来看下Androidmanfest.xml,其中有这个provider

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><providerandroid:name="NotePadProvider"
android:authorities
="com.google.provider.NotePad"
/>

发现没有?它也有com.google.provider.NotePad,这个是content://com.google.provider.NotePad/notes/1的一部分,同时

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><activityandroid:name="NoteEditor"
android:theme
="@android:style/Theme.Light"
android:label
="@string/title_note"
android:screenOrientation
="sensor"
android:configChanges
="keyboardHidden|orientation"
>
<!--Thisfiltersaysthatwecanvieworeditthedataof
asinglenote
-->
<intent-filterandroid:label="@string/resolve_edit">
<actionandroid:name="android.intent.action.VIEW"/>
<actionandroid:name="android.intent.action.EDIT"/>
<actionandroid:name="com.android.notepad.action.EDIT_NOTE"/>
<categoryandroid:name="android.intent.category.DEFAULT"/>
<dataandroid:mimeType="vnd.android.cursor.item/vnd.google.note"/>
</intent-filter>
<!--Thisfiltersaysthatwecancreateanewnoteinside
ofadirectoryofnotes.
-->
<intent-filter>
<actionandroid:name="android.intent.action.INSERT"/>
<categoryandroid:name="android.intent.category.DEFAULT"/>
<dataandroid:mimeType="vnd.android.cursor.dir/vnd.google.note"/>
</intent-filter>
</activity>

上面第一个intent-filter中有一个action 名为android.intent.action.EDIT,而前面我们创建的Intent也正好是

Intent.ACTION_EDIT=” android.intent.action.EDIT”,想必大家已经明白是怎么回事了吧。

下面就进入activity选择机制了:

系统从intent中获取道uri,得到了content://com.google.provider.NotePad/notes/1,去掉开始的content:标识,得到com.google.provider.NotePad/notes/1,然后获取前面的com.google.provider.NotePad,然后就到Androidmanfest.xml中找到authoritiescom.google.provider.NotePadprovider,这个就是后面要讲的contentprovider,然后就加载这个content provider

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><providerandroid:name="NotePadProvider"
android:authorities
="com.google.provider.NotePad"
/>

在这里是NotePadProvider,然后调用NotePadProvidergettype函数,并把上述URI传给这个函数,函数返回URI所对应的类型(这里返回Notes.CONTENT_ITEM_TYPE,代表一条日志记录,而CONTENT_ITEM_TYPE = " vnd.android.cursor.item/vnd.google.note ")。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->@Override
publicStringgetType(Uriuri){
switch(sUriMatcher.match(uri)){
caseNOTES:
returnNotes.CONTENT_TYPE;
caseNOTE_ID:
returnNotes.CONTENT_ITEM_TYPE;
default:
thrownewIllegalArgumentException("UnknownURI"+uri);
}
}

上面的sUriMatcher.match是用来检测uri是否能够被处理,而sUriMatcher.match(uri)返回值其实是由

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->sUriMatcher=newUriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(NotePad.AUTHORITY,
"notes",NOTES);
sUriMatcher.addURI(NotePad.AUTHORITY,
"notes/#",NOTE_ID);

决定的。

然后系统使用获得的" vnd.android.cursor.item/vnd.google.note "”android.intent.action.EDIT”androidmanfest.xml中去找匹配的activity.

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><intent-filterandroid:label="@string/resolve_edit">
<actionandroid:name="android.intent.action.VIEW"/>
<actionandroid:name="android.intent.action.EDIT"/>
<actionandroid:name="com.android.notepad.action.EDIT_NOTE"/>
<categoryandroid:name="android.intent.category.DEFAULT"/>
<dataandroid:mimeType="vnd.android.cursor.item/vnd.google.note"/>
</intent-filter>

正好NoteEditor这个activityintent-filter满足上述条件,这样就找到了NoteEditor。于是系统加载这个类并实例化,运行,然后就到了NoteEditorOnCreate函数中(见后续文章)。

小技巧

1,在命令行中使用”adb shell”命令进入系统中,然后”cd app”进入应用程序所在目录,”rm XXX”就可以删除你指定的apk,从而去掉其在系统顶层界面占据的图标,若两次”cd data”则可以进入应用程序使用的数据目录,你的数据可以保存在这里,例如Notepad就是把其数据库放在它的databases目录下,名为note_pad.db.

2,第一次启动模拟器会比较慢,但以后就别关闭模拟器了,修改代码,调试都不需要再次启动的,直接修改后rundebug就是。

作者:phinecos(洞庭散人)
出处:http://phinecos.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但请保留此段声明,并在文章页面明显位置给出原文连接

分享到:
评论

相关推荐

    Android实例剖析笔记

    ### Android实例剖析笔记 #### 1. 活动(Activity)的生命周期与启动模式 - **活动的生命周期**:活动是Android应用程序中的基本组件之一,负责处理用户交互并展示UI界面。理解活动的生命周期对于合理管理资源和避免...

    Android-笔记一款以sqlitedatabase为数据库采用MVP架构的轻便易用的笔记app

    本项目名为"Android-笔记一款以sqlitedatabase为数据库采用MVP架构的轻便易用的笔记app",它是一个典型的Android应用示例,旨在展示如何结合SQLite数据库和Model-View-Presenter(MVP)架构模式来创建一个功能完善的...

    Android学习新手笔记

    整个笔记强调了在Android学习过程中,Java编程知识的重要性,并提供了大量代码实例来帮助新手理解Android开发的核心概念和常用组件的使用方法。这份笔记可以作为学习Android开发的入门教材,它覆盖了从基础到实战...

    android 非常全培训笔记

    这份"android 非常全培训笔记"无疑是为开发者提供了一个宝贵的参考资料。它包含了从小实例到实际应用的各种实践,帮助初学者逐步深入理解Android系统的工作原理和开发技巧。下面我们将详细探讨其中可能涵盖的关键...

    全网最全Android开发笔记.zip

    笔记包含了大量的实例代码、技术解析和实战经验,对于想要深入学习Android开发的程序员来说,是一份宝贵的资源。 一、Android系统架构 Android系统由五大部分组成:Linux内核、硬件抽象层(HAL)、库、应用程序框架...

    黑马Android基础笔记

    《黑马Android基础笔记》是一份全面且深入的Android开发学习资料,主要针对初学者和希望巩固基础知识的开发者。这份笔记涵盖了Android开发的核心概念和技术,旨在帮助读者构建坚实的Android开发基础。 1. **Android...

    Android+学习笔记

    本文档是一份详实的Android学习笔记,旨在帮助初学者快速入门Android开发。 #### 二、环境搭建与HelloWorld案例分析 **1. SDK下载与安装** - **下载**:访问Android官方网站或其他可信渠道下载Android SDK。 - **...

    《Android应用开发揭秘》读书笔记

    《Android应用开发揭秘》读书笔记不仅是一份个人学习历程的记录,更是一部深入浅出的Android开发指南。本书籍及笔记覆盖了从基础知识到高级应用的广泛内容,为初学者和有经验的开发者提供了宝贵的资源。 ### ...

    android课程笔记

    - **Dalvik虚拟机**(DVM):是Android平台上的虚拟机,它被设计为可以高效地在一个设备上运行多个实例。每个Android应用程序运行在自己的进程中,有自己的实例化的Dalvik虚拟机。这种设计使得每个应用都能得到足够...

    Android开发教程笔记完全版

    《Android开发教程笔记完全版》是一份全面深入的Android应用开发学习资料,旨在帮助开发者从零基础到精通,掌握Android平台的各项核心技术。这份教程涵盖了Android开发的各个方面,包括环境搭建、UI设计、数据存储、...

    android全程学习笔记

    Android全程学习笔记旨在提供一个详尽且全面的指南,涵盖了Android开发中的关键技术点和实践案例。以下是关于Android开发的一些核心知识点: 1. **第一个Android应用**:开发Android应用的起点通常是从创建并运行你...

    Android学习笔记1

    从学习笔记来看,笔记作者主要通过实例操作来逐步理解和掌握Android应用开发的各个方面,从基础的界面搭建到复杂的交互逻辑处理都有涉及。通过这些笔记,我们了解到一个初学者是如何逐步掌握Android开发技能的,并且...

    Android-一个仿照印象笔记的TimeBar.rar

    最后,它被推荐作为“参考学习”的材料,意味着这个项目可以作为一个学习Android编程,特别是TimeBar实现的实例。 【标签解析】 "一个仿照印象笔记的TimeBar.rar" 这个标签再次强调了项目的主要功能是实现类似印象...

    Android 上百实例源码分析以及开源分析 集合打包上

    本资源"Android上百实例源码分析以及开源分析集合打包上"提供了一个丰富的学习资料库,旨在帮助开发者通过实例学习和研究Android应用程序的实现细节。下面我们将针对这个主题进行深入探讨。 一、源码分析的重要性 ...

    Android 学习实例备份,添加收集的文档和笔记.

    "Android学习实例备份"这个压缩包文件包含了开发者在学习Android时收集的文档、笔记以及可能的代码示例,旨在帮助初学者或进阶者深入理解Android应用开发的核心概念。这里我们将详细探讨其中涉及的一些重要知识点。 ...

    基于Java语言的Android开发学习笔记设计源码

    本项目的学习笔记正是围绕这些知识点展开,通过实例代码、图表说明和文字解析,逐步引导学习者深入理解和掌握Android开发的核心技术。 本项目为Android开发初学者提供了一套完整的自学材料。它不仅包含了必要的理论...

Global site tag (gtag.js) - Google Analytics