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

android面试题总结加强版(三)

 
阅读更多

自己总结的最强android应用面试题集

26.如果后台的Activity由于某原因被系统回收了,如何在被系统回收之前保存当前状态?

当你的程序中某一个ActivityA在运行时中,主动或被动地运行另一个新的ActivityB
这个时候A会执行

Java代码

publicvoidonSaveInstanceState(BundleoutState){super.onSaveInstanceState(outState);outState.putLong("id",1234567890);}

B完成以后又会来找A,这个时候就有两种情况,一种是A被回收,一种是没有被回收,被回
收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上参数savedInstanceState,没被收回的就还是onResume就好了。

savedInstanceState是一个Bundle对象,你基本上可以把他理解为系统帮你维护的一个Map对象。在onCreate()里你可能会用到它,如果正常启动onCreate就不会有它,所以用的时候要判断一下是否为空。

Java代码

if(savedInstanceState!=null){
longid=savedInstanceState.getLong("id");
}

就像官方的Notepad教程里的情况,你正在编辑某一个note,突然被中断,那么就把这个note的id记住,再起来的时候就可以根据这个id去把那个note取出来,程序就完整一些。这也是看你的应用需不需要保存什么,比如你的界面就是读取一个列表,那就不需要特殊记住什么,哦,没准你需要记住滚动条的位置...

27.如何退出Activity

对于单一Activity的应用来说,退出很简单,直接finish()即可。当然,也可以用killProcess()System.exit()这样的方法。现提供几个方法,供参考:
1、抛异常强制退出:该方法通过抛异常,使程序ForceClose。验证可以,但是,需要解决的问题是,如何使程序结束掉,而不弹出ForceClose的窗口。
2、记录打开的Activity:每打开一个Activity,就记录下来。在需要退出时,关闭每一个Activity即可。
3、发送特定广播:在需要结束应用时,发送一个特定的广播,每个Activity收到广播后,关闭即可。
4、递归退出在打开新的Activity时使用startActivityForResult,然后自己加标志,在onActivityResult中处理,递归关闭。除了第一个,都是想办法把每一个Activity都结束掉,间接达到目的。但是这样做同样不完美。你会发现,如果自己的应用程序对每一个Activity都设置了nosensor,在两个Activity结束的间隙,sensor可能有效了。但至少,我们的目的达到了,而且没有影响用户使用。为了编程方便,最好定义一个Activity基类,处理这些共通问题。

28.请解释下在单线程模型中MessageHandlerMessageQueueLooper之间的关系。

MessageQueue(消息队列):用来存放通过Handler发布的消息,通常附属于某一个创建它的线程,可以通过Looper.myQueue()得到当前线程的消息队列
  Handler:可以发布或者处理一个消息或者操作一个Runnable,通过Handler发布消息,消息将只会发送到与它关联的消息队列,然也只能处理该消息队列中的消息
  Looper:是Handler和消息队列之间通讯桥梁,程序组件首先通过Handler把消息传递给LooperLooper把消息放入队列。Looper也把消息队列里的消息广播给所有的
    HandlerHandler接受到消息后调用handleMessage进行处理
  Message:消息的类型,在Handler类中的handleMessage方法中得到单个的消息进行处理.

29.你如何评价Android系统?优缺点。

答:优点:1、学习的开源性
  2、软件兼容性比较好
  3、软件发展迅速
  4、界面布局好
  缺点:1、版本过多
  2、先有软件少3、商务性能差

30.谈谈android数据存储方式。

Android提供了5种方式存储数据:
1)使用SharedPreferences存储数据;它是Android提供的用来存储一些简单配置信息的一种机制,采用了XML格式将数据存储到设备中。只能在同一个包内使用,不能在不同的包之间使用。
2)文件存储数据;文件存储方式是一种较常用的方法,在Android中读取/写入文件的方法,与Java中实现I/O的程序是完全一样的,提供了openFileInput()openFileOutput()方法来读取设备上的文件。
3SQLite数据库存储数据;SQLiteAndroid所带的一个标准的数据库,它支持SQL语句,它是一个轻量级的嵌入式数据库。
4)使用ContentProvider存储数据;主要用于应用程序之间进行数据交换,从而能够让其他的应用保存或读取此ContentProvider的各种数据类型。
5)网络存储数据;通过网络上提供给我们的存储空间来上传(存储)和下载(获取)我们存储在网络空间中的数据信息。

  

31.AndroidActivity,Intent,ContentProvider,Service各有什么区别。

Activity:活动,是最基本的android应用程序组件。一个活动就是一个单独的屏幕,每一个活动都被实现为一个独立的类,并且从活动基类继承而来。
Intent:意图,描述应用想干什么。最重要的部分是动作和动作对应的数据。
ContentProvider:内容提供器,android应用程序能够将它们的数据保存到文件、SQLite数据库中,甚至是任何有效的设备中。当你想将你的应用数据和其他应用共享时,内容提供器就可以发挥作用了。
Service:服务,具有一段较长生命周期且没有用户界面的程序。

32.View,surfaceView,GLSurfaceView有什么区别。

view是最基础的,必须在UI主线程内更新画面,速度较慢。
SurfaceViewview的子类,类似使用双缓机制,在新的线程中更新画面所以刷新界面速度比view
GLSurfaceViewSurfaceView的子类,opengl专用的

33.Manifest.xml文件中主要包括哪些信息?

manifest:根节点,描述了package中所有的内容。
uses-permission:请求你的package正常运作所需赋予的安全许可。
permission:声明了安全许可来限制哪些程序能你package中的组件和功能。
instrumentation:声明了用来测试此package或其他package指令组件的代码。
application:包含packageapplication级别组件声明的根节点。
activityActivity是用来与用户交互的主要工具。
receiverIntentReceiver能使的application获得数据的改变或者发生的操作,即使它当前不在运行。
serviceService是能在后台运行任意时间的组件。
providerContentProvider是用来管理持久化数据并发布给其他应用程序使用的组件。

34.根据自己的理解描述下Android数字签名。

(1)所有的应用程序都必须有数字证书,Android系统不会安装一个没有数字证书的应用程序
(2)Android程序包使用的数字证书可以是自签名的,不需要一个权威的数字证书机构签名认证
(3)如果要正式发布一个Android,必须使用一个合适的私钥生成的数字证书来给程序签名,而不能使用adt插件或者ant工具生成的调试证书来发布。
(4)数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。如果程序已经安装在系统中,即使证书过期也不会影响程序的正常功能。

35.AIDL的全称是什么?如何工作?能处理哪些类型的数据?

AIDL全称AndroidInterfaceDefinitionLanguageAndRoid接口描述语言)是一种借口描述语言;编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程跨界对象访问的目的.AIDLIPC的机制和COMCORBA类似,是基于接口的,但它是轻量级的。它使用代理类在客户端和实现层间传递值.如果要使用AIDL,需要完成2件事情:1.引入AIDL的相关类.;2.调用aidl产生的class.理论上,参数可以传递基本数据类型和String,还有就是Bundle的派生类,不过在Eclipse,目前的ADT不支持Bundle做为参数,
具体实现步骤如下:

1、创建AIDL文件,在这个文件里面定义接口,该接口定义了可供客户端访问的方法和属性。

2、编译AIDL文件,Ant的话,可能需要手动,使用Eclipseplugin的话,可以根据adil文件自动生产java文件并编译,不需要人为介入.

3、在Java文件中,实现AIDL中定义的接口.编译器会根据AIDL接口,产生一个JAVA接口。这个接口有一个名为Stub的内部抽象类,它继承扩展了接口并实现了远程调用需要的几个方法。接下来就需要自己去实现自定义的几个接口了.
4、向客户端提供接口ITaskBinder,如果写的是service,扩展该Service并重载onBind()方法来返回一个实现上述接口的类的实例。
5、在服务器端回调客户端的函数.前提是当客户端获取的IBinder接口的时候,要去注册回调函数,只有这样,服务器端才知道该调用那些函数

AIDL语法很简单,可以用来声明一个带一个或多个方法的接口,也可以传递参数和返回值。由于远程调用的需要,这些参数和返回值并不是任何类型.下面是些AIDL支持的数据类型:

1.不需要import声明的简单Java编程语言类型(int,boolean)

2.String,CharSequence不需要特殊声明

3.List,MapParcelables类型,这些类型内所包含的数据成员也只能是简单数据类型,String等其他比支持的类型.

(另外:我没尝试Parcelables,Eclipse+ADT下编译不过,或许以后会有所支持).

实现接口时有几个原则:

.抛出的异常不要返回给调用者.跨进程抛异常处理是不可取的.

.IPC调用是同步的。如果你知道一个IPC服务需要超过几毫秒的时间才能完成地话,你应该避免在Activity的主线程中调用。也就是IPC调用会挂起应用程序导致界面失去响应.这种情况应该考虑单起一个线程来处理.

.不能在AIDL接口中声明静态属性。

IPC的调用步骤:

1.声明一个接口类型的变量,该接口类型在.aidl文件中定义。

2.实现ServiceConnection

3.调用ApplicationContext.bindService(),并在ServiceConnection实现中进行传递.

4.ServiceConnection.onServiceConnected()实现中,你会接收一个IBinder实例(被调用的Service).调用

YourInterfaceName.Stub.asInterface((IBinder)service)将参数转换为YourInterface类型。

5.调用接口中定义的方法。你总要检测到DeadObjectException异常,该异常在连接断开时被抛出。它只会被远程方法抛出。

6.断开连接,调用接口实例中的ApplicationContext.unbindService()
参考:http://buaadallas.blog.51cto.com/399160/372090

36.android:gravityandroid:layout_gravity的区别

LinearLayout有两个非常相似的属性:android:gravityandroid:layout_gravity。他们的区别在于:android:gravity用于设置View组件的对齐方式,而android:layout_gravity用于设置Container组件的对齐方式。

举个例子,我们可以通过设置android:gravity="center"来让EditText中的文字在EditText组件中居中显示;同时我们设置EditTextandroid:layout_gravity="right"来让EditText组件在LinearLayout中居中显示。来实践以下:

正如我们所看到的,在EditText中,其中的文字已经居中显示了,而EditText组件自己也对齐到了LinearLayout的右侧。

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <EditText 
        android:layout_width="wrap_content" 
        android:gravity="center" 
        android:layout_height="wrap_content" 
        android:text="one" 
        android:layout_gravity="right"/> 
</LinearLayout>



这两个属性也可以用于FramlayoutTextview等等,表示的意思大同小异

37.paddingmargin的区别

padding填充的意思,指的是view中的contentview边缘的距离,类似文本中的indent
margin表示的是view的左边缘与parentview的左边缘的距离
margin一般用来描述控件间位置关系,而padding一般描述控件内容和控件的位置关系。

简单,padding是站在父view的角度描述问题,它规定它里面的内容必须与这个父view边界的距离。margin则是站在自己的角度描述问题,规定自己和其他(上下左右)的view之间的距离,如果同一级只有一个view,那么它的效果基本上就和padding一样了。例如我的XMLlayout代码如下:

viewplaincopytoclipboardprint?

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:paddingLeft="10dip"  
    android:paddingRight="10dip"  
    android:paddingTop="10dip"  
    android:paddingBottom="10dip"  
    >  
<TextView    
    android:layout_width="wrap_content"   
    android:layout_height="wrap_content"   
    android:background="#FF0000"  
    android:text="@string/hello"  
    android:paddingLeft="50dip"  
    android:paddingRight="50dip"  
    android:paddingTop="50dip"  
    android:paddingBottom="50dip"  
    android:layout_marginBottom="10dip"  
    />  
    <TextView    
    android:layout_width="wrap_content"   
    android:layout_height="wrap_content"   
    android:background="#FF0000"  
    android:text="@string/hello"  
    android:paddingLeft="50dip"  
    android:paddingRight="50dip"  
    android:paddingTop="50dip"  
    android:paddingBottom="50dip"  
    android:layout_marginBottom="10dip"  
    />  
    <TextView    
    android:layout_width="wrap_content"   
    android:layout_height="wrap_content"   
    android:background="#FF0000"  
    android:text="@string/hello"  
    android:paddingLeft="50dip"  
    android:paddingRight="50dip"  
    android:paddingTop="50dip"  
    android:paddingBottom="50dip"  
    android:layout_marginBottom="10dip"  
    />  
    <TextView    
    android:layout_width="wrap_content"   
    android:layout_height="wrap_content"   
    android:background="#FF0000"  
    android:text="@string/hello"  
    android:paddingLeft="50dip"  
    android:paddingRight="50dip"  
    android:paddingTop="50dip"  
    android:paddingBottom="50dip"  
    android:layout_marginBottom="10dip"  
    />  
</LinearLayout>  

那么我会得到如下的效果,图上已经很明确的标出来区别咯。

38.注册广播接收者两种方式的区别

现在我们就来实现一个简单的广播程序。Android提供了两种注册广播接受者的形式,分别是在程序中动态注册和在xml中指定。他们之间的区别就是作用的范围不同,程序动态注册的接收者只在程序运行过程中有效,而在xml注册的接收者不管你的程序有没有启动有会起作用。

39.Dalvik基于JVM的改进

1.几个class变为一个dexconstantpool,省内存

2.Zygotecopy-on-writeshared,省内存,省cpu,省电

3.基于寄存器的bytecode,省指令,省cpu,省电

4.Trace-basedJIT,cpu,省电,省内存

40.android中有哪几种解析xml的类,官方推荐哪种?以及它们的原理和区别.

ØDOM解析

优点:

1.XML树在内存中完整存储,因此可以直接修改其数据和结构.

2.可以通过该解析器随时访问XML树中的任何一个节点.

3.DOM解析器的API在使用上也相对比较简单.

缺点:如果XML文档体积比较大时,将文档读入内存是非常消耗系统资源的.

使用场景:DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点的集合.这个层次结构允许开发人员在树中寻找特定信息.分析该结构通常需要加载整个文档和构造层次结构,然后才能进行任何工作.DOM是基于对象层次结构的.

ØSAX解析

优点:

SAX对内存的要求比较低,因为它让开发人员自己来决定所要处理的标签.特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体现.

缺点:

用SAX方式进行XML解析时,需要顺序执行,所以很难访问到同一文档中的不同数据.此外,在基于该方式的解析编码过程也相对复杂.

使用场景:

对于含有数据量十分巨大,而又不用对文档的所有数据进行遍历或者分析的时候,使用该方法十分有效.该方法不用将整个文档读入内存,而只需读取到程序所需的文档标签处即可.

ØXmlpull解析

androidSDK提供了xmlpullapi,xmlpull和sax类似,是基于流(stream)操作文件,然后根据节点事件回调开发者编写的处理程序.因为是基于流的处理,因此xmlpull和sax都比较节约内存资源,不会象dom那样要把所有节点以对橡树的形式展现在内存中.xmlpull比sax更简明,而且不需要扫描完整个流.

41.Android系统中GC什么情况下会出现内存泄露呢?

出现情况:
1.数据库的cursor没有关闭
2.构造adapter时,没有使用缓存contentview
衍生listview的优化问题-----减少创建view的对象,充分使用contentview,可以使用一静态类来优化处理getview的过程/
3.Bitmap对象不使用时采用recycle()释放内存
4.activity中的对象的生命周期大于activity
调试方法:DDMS==>HEAPSZIE==>dataobject==>[TotalSize]

42.谈谈对AndroidNDK的理解

NDK全称:NativeDevelopmentKit

2.误解
误解一:NDK发布之前,Android不支持进行C开发
在Google中搜索“NDK”,很多“Android终于可以使用C++开发”之类的标题,这是一种对Android平台编程方式的误解.其实,Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于AndroidSDK进行开发的第三方应用都必须使用Java语言.但这并不等同于“第三方应用只能使用Java”.在AndroidSDK首次发布时,Google就宣称其虚拟机Dalvik支持JNI编程方式,也就是第三方应用完全可以通过JNI调用自己的C动态库,即在Android平台上,“Java+C”的编程方式是一直都可以实现的.

当然这种误解的产生是有根源的:在AndroidSDK文档里,找不到任何JNI方面的帮助.即使第三方应用开发者使用JNI完成了自己的C动态链接库(so)开发,但是so如何和应用程序一起打包成apk并发布?这里面也存在技术障碍.我曾经花了不少时间,安装交叉编译器创建so,并通过asset(资源)方式,实现捆绑so发布.但这种方式只能属于取巧的方式,并非官方支持.所以,在NDK出来之前,我们将“Java+C”的开发模式称之为灰色模式,即官方既不声明“支持这种方式”,也不声明“不支持这种方式”.

误解二:有了NDK,我们可以使用纯C开发Android应用
AndroidSDK采用Java语言发布,把众多的C开发人员排除在第三方应用开发外(注意:我们所有讨论都是基于“第三方应用开发”,Android系统基于Linux,系统级别的开发肯定是支持C语言的.).NDK的发布,许多人会误以为,类似于Symbian.WM,在Android平台上终于可以使用纯C.C++开发第三方应用了!其实不然,NDK文档明确说明:itisnotagoodway.因为NDK并没有提供各种系统事件处理支持,也没有提供应用程序生命周期维护.此外,在本次发布的NDK中,应用程序UI方面的API也没有提供.至少目前来说,使用纯C.C++开发一个完整应用的条件还不完备.
1.NDK是一系列工具的集合.

NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk.这些工具对开发者的帮助是巨大的.
NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU.平台.ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”.“编译特性要求”等),就可以创建出NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作.
2.NDK提供了一份稳定.功能有限的API头文件声明.

Google明确声明该API是稳定的,在后续所有版本中都稳定支持当前发布的API.从该版本的NDK中看出,这些API支持的功能非常有限,包含有:C标准库(libc).标准数学库(libm).压缩库(libz).Log库(liblog).

3.NDK带来什么
1.NDK的发布,使“Java+C”的开发方式终于转正,成为官方支持的开发方式.

使用NDK,我们可以将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率.
使用NDK,我们可以将需要保密的应用逻辑使用C开发.毕竟,Java包都是可以反编译的.
NDK促使专业so组件商的出现.(乐观猜想,要视乎Android用户的数量)
2.NDK将是Android平台支持C开发的开端.NDK提供了的开发工具集合,使开发人员可以便捷地开发.发布C组件.同时,Google承诺在NDK后续版本中提高“可调式”能力,即提供远程的gdb工具,使我们可以便捷地调试C源码.在支持Android平台C开发,我们能感觉到Google花费了很大精力,我们有理由憧憬“C组件支持”只是GoogleAndroid平台上C开发的开端.毕竟,C程序员仍然是码农阵营中的绝对主力,将这部分人排除在Android应用开发之外,显然是不利于Android平台繁荣昌盛的.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics