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

android面试第五集

 
阅读更多

src/ java原代码存放目录
gen/ 自动生成目录
gen 目录中存放所有由Android开发工具自动生成的文件。目录中最重要的就是R.java文件。 这个文件由Android开发工具自动产生的。Android开发工具会自动根据你放入res目录的资源,同步更新修改R.java文件。正因为R.java文件是由开发工具自动生成的,所以我们应避免手工修改R.java。R.java在应用中起到了字典的作用,它包含了各种资源的id,通过R.java,应用可以很方便地找到对应资源。另外编绎器也会检查R.java列表中的资源是否被使用到,没有被使用到的资源不会编绎进软件中,这样可以减少应用在手机占用的空间。
res/ 资源(Resource)目录
在这个目录中我们可以存放应用使用到的各种资源,如xml界面文件,图片或数据。具体请看ppt下方备注栏。
assets资源目录
Android除了提供/res目录存放资源文件外,在/assets目录也可以存放资源文件,而且/assets目录下的资源文件不会在R.java自动生成ID,所以读取/assets目录下的文件必须指定文件的路径,如:file:///android_asset/xxx.3gp
AndroidManifest.xml 项目清单文件
这个文件列出了应用程序所提供的功能,以后你开发好的各种组件需要在该文件中进行配置,如果应用使用到了系统内置的应用(如电话服务、互联网服务、短信服务、GPS服务等等),你还需在该文件中声明使用权限。
default.properties 项目环境信息,一般是不需要修改此文件


在实际开发中,开发android软件的过程需要不断地进行测试。而使用Junit测试框架,侧是正规Android开发的必用技术,在Junit中可以得到组件,可以模拟发送事件和检测程序处理的正确性。
第一步:首先在AndroidManifest.xml中加入下面红色代码:

  1. <manifestxmlns:android="http://schemas.android.com/apk/res/android"
  2. package="cn.itcast.action“android:versionCode="1“android:versionName="1.0">
  3. <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
  4. <uses-libraryandroid:name="android.test.runner"/>
  5. ....
  6. </application>
  7. <uses-sdkandroid:minSdkVersion="6"/>
  8. <instrumentationandroid:name="android.test.InstrumentationTestRunner"
  9. android:targetPackage="cn.itcast.action"android:label="TestsforMyApp"/>
  10. </manifest>
上面targetPackage指定的包要和应用的package相同。
第二步:编写单元测试代码(选择要测试的方法,右键点击“Run As”--“Android Junit Test” ):
  1. importandroid.test.AndroidTestCase;
  2. importandroid.util.Log;
  3. publicclassXMLTestextendsAndroidTestCase{
  4. publicvoidtestSomething()throwsThrowable{
  5. Assert.assertTrue(1+1==3);
  6. }
  7. }
很多时候我们的软件需要对处理后的数据进行存储或再次访问。Android为数据存储提供了如下几种方式:
文件
SharedPreferences(参数)
SQLite数据库
内容提供者(Content provider)
网络


Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用Context.MODE_APPEND
Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件。
MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。
如果希望文件被其他应用读和写,可以传入:
openFileOutput("itcast.txt", Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);

android有一套自己的安全模型,当应用程序(.apk)在安装时系统就会分配给他一个userid,当该应用要去访问其他资源比如文件的时候,就需要userid匹配。默认情况下,任何应用创建的文件,sharedpreferences,数据库都应该是私有的(位于/data/data/<package name>/files),其他程序无法访问。除非在创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE ,只有这样其他程序才能正确访问。


如果要打开存放在/data/data/<package name>/files目录应用私有的文件,可以使用Activity提供openFileInput()方法。
FileInputStream inStream = this.getContext().openFileInput("itcast.txt");
Log.i("FileTest", readInStream(inStream));
readInStream()的方法请看本页下面备注。

或者直接使用文件的绝对路径:
File file = new File("/data/data/cn.itcast.action/files/itcast.txt");
FileInputStream inStream = new FileInputStream(file);
Log.i("FileTest", readInStream(inStream));
注意:上面文件路径中的“cn.itcast.action”为应用所在包,当你在编写代码时应替换为你自己应用使用的包。
对于私有文件只能被创建该文件的应用访问,如果希望文件能被其他应用读和写,可以在创建文件时,指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE权限。

Activity还提供了getCacheDir()和getFilesDir()方法:
getCacheDir()方法用于获取/data/data/<package name>/cache目录
getFilesDir()方法用于获取/data/data/<package name>/files目录

在程序中访问SDCard,你需要申请访问SDCard的权限。
在AndroidManifest.xml中加入访问SDCard的权限如下:
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备。 SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件。所谓事件,其实就是一些回调(callback)方法,这些方法(事件)定义在ContentHandler接口。下面是一些ContentHandler接口常用的方法:
startDocument()
当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。
endDocument()
和上面的方法相对应,当文档结束的时候,调用这个方法,可以在其中做一些善后的工作。
startElement(String namespaceURI, String localName, String qName, Attributes atts)
当读到一个开始标签的时候,会触发这个方法。namespaceURI就是命名空间,localName是不带命名空间前缀的标签名,qName是带命名空间前缀的标签名。通过atts可以得到所有的属性名和相应的值。要注意的是SAX中一个重要的特点就是它的流式处理,当遇到一个标签的时候,它并不会纪录下以前所碰到的标签,也就是说,在startElement()方法中,所有你所知道的信息,就是标签的名字和属性,至于标签的嵌套结构,上层标签的名字,是否有子元属等等其它与结构相关的信息,都是不得而知的,都需要你的程序来完成。这使得SAX在编程处理上没有DOM来得那么方便。
endElement(String uri, String localName, String name)
这个方法和上面的方法相对应,在遇到结束标签的时候,调用这个方法。
characters(char[] ch, int start, int length)
这个方法用来处理在XML文件中读到的内容,第一个参数为文件的字符串内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用new String(ch,start,length)就可以获取内容。


很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的QQ,用户可以设置是否允许陌生人添加自己为好友。对于软件配置参数的保存,如果是window软件通常我们会采用ini文件进行保存,如果是j2se应用,我们会采用properties属性文件或者xml进行保存。如果是Android应用,我们最适合采用什么方式保存软件配置参数呢?Android平台给我们提供了一个SharedPreferences类,它是一个轻量级的存储类,特别适合用于保存软件配置参数。使用SharedPreferences保存数据,其背后是用xml文件存放数据,文件存放在/data/data/<package name>/shared_prefs目录下:

  1. SharedPreferencessharedPreferences=getSharedPreferences("itcast",Context.MODE_PRIVATE);
  2. Editoreditor=sharedPreferences.edit();//获取编辑器
  3. editor.putString("name","传智播客");
  4. editor.putInt("age",4);
  5. editor.commit();//提交修改
生成的itcast.xml文件内容如下:
  1. <?xmlversion='1.0'encoding='utf-8'standalone='yes'?>
  2. <map>
  3. <stringname="name">传智播客</string>
  4. <intname="age"value="4"/>
  5. </map>
因为SharedPreferences背后是使用xml文件保存数据,getSharedPreferences(name,mode)方法的第一个参数用于指定该文件的名称,名称不用带后缀,后缀会由Android自动加上。方法的第二个参数指定文件的操作模式,共有四种操作模式,这四种模式前面介绍使用文件方式保存数据时已经讲解过。如果希望SharedPreferences背后使用的xml文件能被其他应用读和写,可以指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE权限。
另外Activity还提供了另一个getPreferences(mode)方法操作SharedPreferences,这个方法默认使用当前类不带包名的类名作为文件的名称。

ContentProvider 在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对你应用中的数据进行添删改查。关于数据共享,以前我们学习过文件操作模式,知道通过指定文件的操作模式为Context.MODE_WORLD_READABLE 或Context.MODE_WORLD_WRITEABLE同样也可以对外共享数据。那么,这里为何要使用ContentProvider 对外共享数据呢?是这样的,如果采用文件操作模式对外共享数据,数据的访问方式会因数据存储的方式而不同,导致数据的访问方式无法统一,如:采用xml文件对外共享数据,需要进行xml解析才能读取数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读取数据。
使用ContentProvider对外共享数据的好处是统一了数据的访问方式。
当应用需要通过ContentProvider对外共享数据时,第一步需要继承ContentProvider并重写下面方法:

  1. publicclassPersonContentProviderextendsContentProvider{
  2. publicbooleanonCreate()
  3. publicUriinsert(Uriuri,ContentValuesvalues)
  4. publicintdelete(Uriuri,Stringselection,String[]selectionArgs)
  5. publicintupdate(Uriuri,ContentValuesvalues,Stringselection,String[]selectionArgs)
  6. publicCursorquery(Uriuri,String[]projection,Stringselection,String[]selectionArgs,StringsortOrder)
  7. publicStringgetType(Uriuri)}
第二步需要在AndroidManifest.xml使用<provider>对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider , ContentProvider 采用了authorities(主机名/域名)对它进行唯一标识,你可以把 ContentProvider看作是一个网站(想想,网站也是提供数据者),authorities 就是他的域名:
  1. <manifest....>
  2. <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
  3. <providerandroid:name=".PersonContentProvider"android:authorities="cn.itcast.providers.personprovider"/>
  4. </application>
  5. </manifest>

使用多线程下载文件可以更快完成文件的下载,多线程下载文件之所以快,是因为其抢占的服务器资源多。如:假设服务器同时最多服务100个用户,在服务器中一条线程对应一个用户,100条线程在计算机中并非并发执行,而是由CPU划分时间片轮流执行,如果A应用使用了99条线程下载文件,那么相当于占用了99个用户的资源,假设一秒内CPU分配给每条线程的平均执行时间是10ms,A应用在服务器中一秒内就得到了990ms的执行时间,而其他应用在一秒内只有10ms的执行时间。就如同一个水龙头,每秒出水量相等的情况下,放990毫秒的水肯定比放10毫秒的水要多。
多线程下载的实现过程:
1>首先得到下载文件的长度,然后设置本地文件
的长度。

  1. HttpURLConnection.getContentLength();
  2. RandomAccessFilefile=newRandomAccessFile("QQWubiSetup.exe","rwd");
  3. file.setLength(filesize);//设置本地文件的长度
2>根据文件长度和线程数计算每条线程下载的数据长度和下载位置。如:文件的长度为6M,线程数为3,那么,每条线程下载的数据长度为2M,每条线程开始下载的位置如上图所示。
3>使用Http的Range头字段指定每条线程从文件的什么位置开始下载,下载到什么位置为止,如:指定从文件的2M位置开始下载,下载到位置(4M-1byte)为止,代码如下:
HttpURLConnection.setRequestProperty("Range", "bytes=2097152-4194303");
4>保存文件,使用RandomAccessFile类指定每条线程从本地文件的什么位置开始写入数据。
RandomAccessFile threadfile = new RandomAccessFile("QQWubiSetup.exe ","rwd");
threadfile.seek(2097152);//从文件的什么位置开始写入数据

Bundle类用作携带数据,它类似于Map,用于存放key-value名值对形式的值。相对于Map,它提供了各种常用类型的putXxx()/getXxx()方法,如:putString()/getString()和putInt()/getInt(),putXxx()用于往Bundle对象放入数据,getXxx()方法用于从Bundle对象里获取数据。Bundle的内部实际上是使用了HashMap<String, Object>类型的变量来存放putXxx()方法放入的值:

  1. publicfinalclassBundleimplementsParcelable,Cloneable{
  2. ......
  3. Map<String,Object>mMap;
  4. publicBundle(){
  5. mMap=newHashMap<String,Object>();
  6. ......
  7. }
  8. publicvoidputString(Stringkey,Stringvalue){
  9. mMap.put(key,value);
  10. }
  11. publicStringgetString(Stringkey){
  12. Objecto=mMap.get(key);
  13. return(String)o;
  14. ........//类型转换失败后会返回null,这里省略了类型转换失败后的处理代码
  15. }
  16. }
在调用Bundle对象的getXxx()方法时,方法内部会从该变量中获取数据,然后对数据进行类型转换,转换成什么类型由方法的Xxx决定,getXxx()方法会把转换后的值返回。

使用startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,我们需要为startActivityForResult()方法传入一个请求码(第二个参数)。请求码的值是根据业务需要由自已设定,用于标识请求来源。例如:一个Activity有两个按钮,点击这两个按钮都会打开同一个Activity,不管是那个按钮打开新Activity,当这个新Activity关闭后,系统都会调用前面Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法。在onActivityResult()方法如果需要知道新Activity是由那个按钮打开的,并且要做出相应的业务处理,这时可以这样做:

  1. @OverridepublicvoidonCreate(BundlesavedInstanceState){
  2. ....
  3. button1.setOnClickListener(newView.OnClickListener(){
  4. publicvoidonClick(Viewv){
  5. startActivityForResult(newIntent(MainActivity.this,NewActivity.class),1);
  6. }});
  7. button2.setOnClickListener(newView.OnClickListener(){
  8. publicvoidonClick(Viewv){
  9. startActivityForResult(newIntent(MainActivity.this,NewActivity.class),2);
  10. }});
  11. @OverrideprotectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
  12. switch(requestCode){
  13. case1:
  14. //来自按钮1的请求,作相应业务处理
  15. case2:
  16. //来自按钮2的请求,作相应业务处理
  17. }
  18. }

Android基本的设计理念是鼓励减少组件间的耦合,因此Android提供了Intent (意图) ,Intent提供了一种通用的消息系统,它允许在你的应用程序与其它的应用程序间传递Intent来执行动作和产生事件。使用Intent可以激活Android应用的三个核心组件:活动、服务和广播接收器。
Intent可以划分成显式意图和隐式意图。
显式意图:调用Intent.setComponent()或Intent.setClass()方法明确指定了组件名的Intent为显式意图,显式意图明确指定了Intent应该传递给哪个组件。
隐式意图:没有明确指定组件名的Intent为隐式意图。 Android系统会根据隐式意图中设置的动作(action)、类别(category)、数据(URI和数据类型)找到最合适的组件来处理这个意图。

  1. <intent-filter>
  2. <actionandroid:name="android.intent.action.CALL"/>
  3. <categoryandroid:name="android.intent.category.DEFAULT"/>
  4. <dataandroid:scheme="tel"/>
  5. </intent-filter>
  6. <intent-filter>
  7. <actionandroid:name="android.intent.action.CALL"/>
  8. <categoryandroid:name="android.intent.category.DEFAULT"/>
  9. <dataandroid:mimeType="vnd.android.cursor.item/phone"/>
  10. </intent-filter>

Activity有三个状态:
当它在屏幕前台时(位于当前任务堆栈的顶部),它是激活或运行状态。它就是响应用户操作的Activity。
当它上面有另外一个Activity,使它失去了焦点但仍然对用户可见时(如右图),它处于暂停状态。在它之上的Activity没有完全覆盖屏幕,或者是透明的,被暂停的Activity仍然对用户可见,并且是存活状态(它保留着所有的状态和成员信息并保持和窗口管理器的连接)。如果系统处于内存不足时会杀死这个Activity。
当它完全被另一个Activity覆盖时则处于停止状态。它仍然保留所有的状态和成员信息。然而对用户是不可见的,所以它的窗口将被隐藏,如果其它地方需要内存,则系统经常会杀死这个Activity。
当Activity从一种状态转变到另一种状态时,会调用以下保护方法来通知这种变化:
  1. voidonCreate(BundlesavedInstanceState)
  2. voidonStart()
  3. voidonRestart()
  4. voidonResume()
  5. voidonPause()
  6. voidonStop()
  7. voidonDestroy()

这七个方法定义了Activity的完整生命周期。实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环:

Activity的完整生命周期自第一次调用onCreate()开始,直至调用onDestroy()为止。Activity在onCreate()中设置所有“全局”状态以完成初始化,而在onDestroy()中释放所有系统资源。例如,如果Activity有一个线程在后台运行从网络下载数据,它会在onCreate()创建线程,而在 onDestroy()销毁线程。

Activity的可视生命周期自onStart()调用开始直到相应的onStop()调用结束。在此期间,用户可以在屏幕上看到Activity,尽管它也许并不是位于前台或者也不与用户进行交互。在这两个方法之间,我们可以保留用来向用户显示这个Activity所需的资源。例如,当用户不再看见我们显示的内容时,我们可以在onStart()中注册一个BroadcastReceiver来监控会影响UI的变化,而在onStop()中来注消。onStart() 和 onStop() 方法可以随着应用程序是否为用户可见而被多次调用。

Activity的前台生命周期自onResume()调用起,至相应的onPause()调用为止。在此期间,Activity位于前台最上面并与用户进行交互。Activity会经常在暂停和恢复之间进行状态转换——例如当设备转入休眠状态或者有新的Activity启动时,将调用onPause() 方法。当Activity获得结果或者接收到新的Intent时会调用onResume() 方法。关于前台生命周期循环的例子请见PPT下方备注栏。


广播接收者(BroadcastReceiver)用于接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast()、Context.sendOrderedBroadcast()来实现的。通常一个广播Intent可以被订阅了此Intent的多个广播接收者所接收,这个特性跟JMS中的Topic消息接收者类似。要实现一个广播接收者方法如下:
第一步:继承BroadcastReceiver,并重写onReceive()方法。

  1. publicclassIncomingSMSReceiverextendsBroadcastReceiver{
  2. @OverridepublicvoidonReceive(Contextcontext,Intentintent){
  3. }}
第二步:订阅感兴趣的广播Intent,订阅方法有两种:
第一种:使用代码进行订阅
  1. IntentFilterfilter=newIntentFilter("android.provider.Telephony.SMS_RECEIVED");
  2. IncomingSMSReceiverreceiver=newIncomingSMSReceiver();
  3. registerReceiver(receiver,filter);
第二种:在AndroidManifest.xml文件中的<application>节点里进行订阅:
  1. <receiverandroid:name=".IncomingSMSReceiver">
  2. <intent-filter>
  3. <actionandroid:name="android.provider.Telephony.SMS_RECEIVED"/>
  4. </intent-filter>
  5. </receiver>

在Android中,每次广播消息到来时都会创建BroadcastReceiver实例并执行onReceive() 方法, onReceive() 方法执行完后,BroadcastReceiver 的实例就会被销毁。当onReceive() 方法在10秒内没有执行完毕,Android会认为该程序无响应。所以在BroadcastReceiver里不能做一些比较耗时的操作,否侧会弹出ANR(Application No Response)的对话框。如果需要完成一项比较耗时的工作,应该通过发送Intent给Service,由Service来完成。这里不能使用子线程来解决,因为BroadcastReceiver的生命周期很短,子线程可能还没有结束BroadcastReceiver就先结束了。BroadcastReceiver一旦结束,此时BroadcastReceiver的所在进程很容易在系统需要内存时被优先杀死,因为它属于空进程(没有任何活动组件的进程)。如果它的宿主进程被杀死,那么正在工作的子线程也会被杀死。所以采用子线程来解决是不可靠的。


Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。服务的开发比较简单,如下:
第一步:继承Service类
public class SMSService extends Service { }

第二步:在AndroidManifest.xml文件中的<application>节点里对服务进行配置:
<service android:name=".SMSService" />

服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。使用startService()方法启用服务,访问者与服务之间没有关连,即使访问者退出了,服务仍然运行。使用bindService()方法启用服务,访问者与服务绑定在了一起,访问者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。

采用Context.startService()方法启动服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。


服务的生命周期跟启动服务的方法有关:
当采用Context.startService()方法启动服务,与之有关的生命周期方法 onCreate()? onStart() ? onDestroy()
onCreate()该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。
onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务,但onStart() 方法会被多次调用。
onDestroy()该方法在服务被终止时调用。
当采用Context.bindService()方法启动服务,与之有关的生命周期方法
onCreate()? onBind() ? onUnbind() ? onDestroy()
onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。
onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。
如果先采用startService()方法启动服务,然后调用bindService()方法绑定到服务,再调用unbindService()方法解除绑定,最后调用bindService()方法再次绑定到服务,触发的生命周期方法如下:
onCreate()?onStart()?onBind()?onUnbind()[重载后的方法需返回true]?onRebind()


Android提供了2种动画:
1> Tween动画,通过对 View 的内容进行一系列的图形变换 (包括平移、缩放、旋转、改变透明度)来实现动画效果。动画效果的定义可以采用XML来做也可以采用编码来做。Tween动画有4种类型:

2> Frame动画,即顺序播放事先做好的图像,跟放胶片电影类似。开发步骤:
(1)把准备好的图片放进项目res/ drawable下。
(2)在项目的res目录下创建文件夹anim,然后在anim文件夹下面定义动画XML文件,文件名称可以自定义。当然也可以采用编码方式定义动画效果(使用AnimationDrawable类)。
(3)为View控件绑定动画效果。调用代表动画的AnimationDrawable的start()方法开始动画。


除了使用 SAX可以解析XML文件,大家也可以使用熟悉的DOM来解析XML文件。 DOM解析XML文件时,会将XML文件的所有内容以文档树方式存放在内存中,然后允许您使用DOM API遍历XML树、检索所需的数据。使用DOM操作XML的代码看起来是比较直观的,并且在编码方面比基于SAX的实现更加简单。但是,因为DOM需要将XML文件的所有内容以文档树方式存放在内存中,所以内存的消耗比较大,特别对于运行Android的移动设备来说,因为设备的资源比较宝贵,所以建议还是采用SAX来解析XML文件,当然,如果XML文件的内容比较小采用DOM也是可行的。
除了可以使用 SAX或DOM解析XML文件之外,大家也可以使用Android内置的Pull解析器解析XML文件。 Pull解析器是一个开源的java项目,既可以用于android,也可以用于JavaEE。如果用在javaEE需要把其jar文件放入类路径中,因为Android已经集成进了Pull解析器,所以无需添加任何jar文件。android系统本身使用到的各种xml文件,其内部也是采用Pull解析器进行解析的。 Pull解析器的运行方式与 SAX 解析器相似。它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。跟SAX不同的是, Pull解析器产生的事件是一个数字,而非方法,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个Text类型节点的值。

分享到:
评论

相关推荐

    Android 面试题集

    Android 面试题集Android 面试题集Android 面试题集Android 面试题集Android 面试题集Android 面试题集Android 面试题集Android 面试题集Android 面试题集Android 面试题集Android 面试题集Android 面试题集Android ...

    android面试 android面试

    android面试 android面试 android面试 android面试 android面试 android面试 android面试 android面试 android面试 android面试

    Android精简面试总结

    在工作中,Android面试出现频率最高的知识点

    Android面试题汇总

    2.BAT Android面试20题详解 3.设计模式面试专题及答案 4.2019Android面试 常见58题 5.初级面试专题(中小厂) 7.设计模式面试专题 8.数据结构面试专题 9.多线程面试专题及答案 10.网络编程面试专题 11.腾讯Android...

    [Android实例] 面试题集

    android[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] ...

    BAT大咖助力 全面升级Android面试

    BAT大咖助力 全面升级Android面试 第1章 课程介绍 第2章 一线互联网公司初中高Android开发工程师的技能要求 第3章 Android基础相关面试问题 第4章 异步消息处理机制相关面试问题 第5章 View相关面试问题 第6章 ...

    71道经典Android面试题和答案

    ------71道经典Android面试题和答案助你轻松拿下offer------

    Android面试宝典6.0

    Android面试宝典,包括Java基础和高级面试,Android基础和高级面试,面试技巧,面试分享,BAT大咖助力,全面升级Android面试,Android高级面试,10大开源框架源码解析...等内容

    常见的java,android面试题整理

    ava,android面试题整理

    Android面试宝典2018

    最新的安卓面试宝典,介绍和解答了各类安卓面试会遇到的专业问题。

    android面试题 自己总结的

    android面试题 自己总结的 android面试题 自己总结的 android面试题 自己总结的 android面试题 自己总结的

    Android面试题整理

    Android面试题整理

    Android面试宝典4.0

    Android面试宝典,包括Java基础和高级面试,Android基础和高级面试,面试技巧,面试分享等内容

    联想android面试题

    联想android面试题

    2023最新Android 面试篇(2303版).pdf

    2023最新Android 面试篇(2303版).pdf

    最全Android面试题

    最全Android面试题 最全Android面 最全Android面试题 最全Android面试题试题

    Android面试题.doc

    Android面试题.doc, Android面试题.doc Android面试题.doc

    2022最新Android中高级面试题合集.pdf

    1.最新整理Android面试题 2.涵盖Java基础,jvm,Android常见面试问答,Kotlin面试题

    【黑马面试宝典】虐面试官神器之必备黑马程序员Android面试宝典.zip

    Android面试宝典包含两个宝典: 1【黑马项目宝典】虐面试官神器之必备黑马程序员项目宝典V1.1 内容包括:(1)电子商城(2)ListView系列(3)图像处理(4)动画效果(5)控件大全(6)新闻资讯(7)生活相关(8)...

    android面试四十题

    android面试题,总结大部分移动开发公司常考的android面试题,适用于android找工作的同学们

Global site tag (gtag.js) - Google Analytics