11-12年个人收集的一些安卓Android面试题

1.android面试题:请描述下Activity的生命周期

onCreate:     在这里创建界面,做一些数据的初始化工作

onStart:      到这一步变成用户可见不可交互的

onResume:   变成和用户可交互的,(在activity 栈系统通过栈的方式管理这些个Activity的最上面,运行完弹出栈,则回到上一个Activity)

onPause:     到这一步是可见但不可交互的,系统会停止动画等消耗CPU 的事情从上文的描述已经知道,应该在这里保存你的一些数据,因为这个时候你的程序的优先级降低,有可能被系统收回。在这里保存的数据,应该在onResume里读出来,注意:这个方法里做的事情时间要短,因为下一个activity不会等到这个方法完成才启动

onstop:     变得不可见,被下一个activity覆盖了

onDestroy: 这是activity被干掉前最后一个被调用方法了,可能是外面类调用finish方法或者是系统为了节省空间将它暂时性的干掉,可以用isFinishing()来判断它,如果你有一个Progress Dialog在线程中转动,请在onDestroy里把他cancel掉,不然等线程结束的时候,调用Dialogcancel方法会抛异常的。


onPauseonstop onDestroy,三种状态 activity都有可能被系统干掉为了保证程序的正确性,你要在onPause()里写上持久层操作的代码,将用户编辑的内容都保存到存储介质上(一般都是数据库)。实际工作中因为生命周期的变化而带来的问题也很多,比如你的应用程序起了新的线程在跑,这时候中断了,你还要去维护那个线程,是暂停还是杀掉还是数据回滚,是吧?因为Activity可能被杀掉,所以线程中使用的变量和一些界面元素就千万要注意了,一般我都是采用Android的消息机制 [Handler,Message]来处理多线程和界面交互的问题。


2.android面试题:请介绍下Android的数据存储方式

Android 提供了5种方式存储数据:

--使用SharedPreferences存储数据;

--文件存储数据;

--SQLite数据库存储数据;

--使用ContentProvider存储数据;

--网络存储数据;

先说下,PreferenceFile DataBase这三种方式分别对应的目录是/data/data/Package Name/Shared_Pref, /data/data/PackageName/files, /data/data/Package Name/database


Android中通常使用File存储方式是用 Context.openFileOutput(String fileName, int mode)Context.openFileInput(StringfileName)

Context.openFileOutput(StringfileName, int mode)生成的文件自动存储在/data/data/Package Name/files目录下,其全路径是/data/data/Package Name/files/fileName 。注意下,这里的参数fileName不可以包含路径分割符(如"/")。

通常来说,这种方式生成的文件只能在这个apk内访问。但这个结论是指使用Context.openFileInput(String fileName)的方式。使用这种方式,每个apk只可以访问自己的/data/data/PackageName/files目录下的文件,原因很简单,参数fileName中不可以包含路径分割符,Android会自动在/data/data /Package Name/files目录下寻找文件名为fileName的文件。


一:使用SharedPreferences存储数据


首先说明SharedPreferences存储方式,它是 Android提供的用来存储一些简单配置信息的一种机制,例如:登录用户的用户名与密码。其采用了Map数据结构来存储数据,以键值的方式存储,可以简单的读取与写入,具体实例如下:

voidReadSharedPreferences(){

StringstrName,strPassword;

SharedPreferences  user = getSharedPreferences(“user_info”,0);

strName =user.getString(“NAME”,””);

strPassword = usergetString(“PASSWORD”,””);

}

voidWriteSharedPreferences(String strName,String strPassword){

SharedPreferences  user = getSharedPreferences(“user_info”,0);

uer.edit();

user.putString(“NAME”,strName);

user.putString(“PASSWORD”,strPassword);

user.commit();

}

数据读取与写入的方法都非常简单,只是在写入的时候有些区别:先调用edit()使其处于编辑状态,然后才能修改数据,最后使用commit()提交修改的数据。实际上SharedPreferences是采用了XML格式将数据存储到设备中,在DDMS中的File Explorer中的/data/data/<packagename>/shares_prefs下。以上面的数据存储结果为例,打开后可以看到一个user_info.xml的文件,打开后可以看到:

<?xml version=”1.0″encoding=”UTF-8″?>

<map>

<stringname=”NAME”>moandroid</string>

<string name=”PASSWORD”>SharedPreferences</string>

</map>

使用SharedPreferences是有些限制的:只能在同一个包内使用,不能在不同的包之间使用。


二:文件存储数据

文件存储方式是一种较常用的方法,在Android中读取/写入文件的方法,与 Java中实现I/O的程序是完全一样的,提供了openFileInput()openFileOutput()方法来读取设备上的文件。 FilterInputStream FilterOutputStream等可以到Java io package说明中去详细学习,不再此详细说明,具体实例如下:

String fn =“moandroid.log”;

FileInputStream fis =openFileInput(fn);

FileOutputStream fos =openFileOutput(fn,Context.MODE_PRIVATE);

除此之外,Android还提供了其他函数来操作文件,详细说明请阅读Android SDK


三:网络存储数据

网络存储方式,需要与Android 网络数据包打交道,关于Android 网络数据包的详细说明,请阅读Android SDK引用了Java SDK的哪些package?。


四:ContentProvider


1ContentProvider简介

当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferencesAPI读写数据。而使用ContentProvider共享数据的好处是统一了数据访问方式。?


2Uri类简介

Uri代表了要操作的数据,Uri主要包含了两部分信息:1.需要操作的ContentProvider 2.ContentProvider中的什么数据进行操作,一个Uri由以下几部分组成:

1.schemeContentProvider(内容提供者)的scheme已经由Android所规定为:content://

2.主机名(或Authority):用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。

3.路径(path):可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:

要操作contact表中id10的记录,可以构建这样的路径:/contact/10

要操作contact表中id10的记录的name字段, contact/10/name

要操作contact表中的所有记录,可以构建这样的路径:/contact?

要操作的数据不一定来自数据库,也可以是文件等他存储方式,如下:

要操作xml文件中contact节点下的name节点,可以构建这样的路径:/contact/name

如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:

Uri uri =Uri.parse("content://com.changcheng.provider.contactprovider/contact")

3UriMatcherContentUristContentResolver简介

因为Uri代表了要操作的数据,所以我们很经常需要解析Uri,并从 Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher ContentUris 。掌握它们的使用,会便于我们的开发工作。

UriMatcher:用于匹配Uri,它的用法如下:

1.首先把你需要匹配Uri路径全部给注册上,如下:

//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码(-1)

UriMatcher uriMatcher =new UriMatcher(UriMatcher.NO_MATCH);

//如果match()方法匹配content://com.changcheng.sqlite.provider.contactprovider/contact路径,返回匹配码为1

uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”,“contact”, 1);//添加需要匹配uri,如果匹配就会返回匹配码

//如果match()方法匹配content://com.changcheng.sqlite.provider.contactprovider/contact/230路径,返回匹配码为2

uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”,“contact/#”, 2);//#号为通配符


2.注册完需要匹配的Uri后,就可以使用uriMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用 addURI()方法传入的第三个参数,假设匹配 content://com.changcheng.sqlite.provider.contactprovider/contact路径,返回的匹配码为1

ContentUris:用于获取Uri路径后面的ID部分,它有两个比较实用的方法:

withAppendedId(uri,id)用于为路径加上ID部分

parseId(uri)方法用于从路径中获取ID部分

ContentResolver:当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用 ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver使用insertdeleteupdatequery方法,来操作数据。


:总结说明

以上5中存储方式,在以后的开发过程中,根据设计目标、性能需求、空间需求等找到合适的数据存储方式。Android 中的数据存储都是私有的,其他应用程序都是无法访问的,除非通过ContentResolver获取其他程序共享的数据。采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferencesAPI读写数据。而使用ContentProvider共享数据的好处是统一了数据访问方式。



3.android面试题:请介绍下Android中常用的五种布局

Android布局是应用界面开发的重要一环,在Android中,共有五种布局方式,分别是:FrameLayout(框架布局),LinearLayout (线性布局),AbsoluteLayout(绝对布局),RelativeLayout(相对布局),TableLayout(表格布局)。

一、FrameLayout

这个布局可以看成是墙脚堆东西,有一个四方的矩形的左上角墙脚,我们放了第一个东西,要再放一个,那就在放在原来放的位置的上面,这样依次的放,会盖住原来的东西。这个布局比较简单,也只能放一点比较简单的东西。

二、LinearLayout

线性布局,这个东西,从外框上可以理解为一个div,他首先是一个一个从上往下罗列在屏幕上。每一个LinearLayout里面又可分为垂直布局

android:orientation="vertical")和水平布局(android:orientation="horizontal"

)。当垂直布局时,每一行就只有一个元素,多个元素依次垂直往下;水平布局时,只有一行,每一个元素依次向右排列。

linearLayout中有一个重要的属性android:layout_weight="1",这个weight在垂直布局时,代表行距;水平的时候代表列宽;weight值越大就越大。


三、AbsoluteLayout

绝对布局犹如div指定了absolute属性,用X,Y坐标来指定元素的位置android:layout_x="20px"

android:layout_y="12px" 这种布局方式也比较简单,但是在垂直随便切换时,往往会出问题,而且多个元素的时候,计算比较麻烦。

四、RelativeLayout

相对布局可以理解为某一个元素为参照物,来定位的布局方式。主要属性有:

相对于某一个元素

android:layout_below="@id/aaa"该元素在 idaaa的下面

android:layout_toLeftOf="@id/bbb" 该元素的左边是bbb
相对于父元素的地方

android:layout_alignParentLeft="true" 在父元素左对齐

android:layout_alignParentRight="true"在父元素右对齐,还可以指定边距等,具体详见API


五、TableLayout

表格布局类似Html里面的Table。每一个TableLayout里面有表格行TableRowTableRow里面可以具体定义每一个元素,设定他的对齐方式 android:gravity=""

每一个布局都有自己适合的方式,另外,这五个布局元素可以相互嵌套应用,做出美观的界面。

4.描述一下android的系统架构

android系统架构分从下往上为linux 内核层运行库应用程序框架层和应用程序层

linuxkernel:负责硬件的驱动程序、网络、电源、系统安全以及内存管理等功能。

libraries android runtimelibraries:即c/c++函数库部分,大多数都是开放源代码的函数库,例如webkit(引擎),该函数库负责 android网页浏览器的运行,例如标准的c函数库libcopensslsqlite等,当然也包括支持游戏开发2dsgl 3dopengles,在多媒体方面有mediaframework框架来支持各种影音和图形文件的播放与显示,例如mpeg4h.264mp3 aacamrjpgpng等众多的多媒体文件格式。androidruntime负责解释和执行生成的dalvik格式的字节码。

applicationframework(应用软件架构),java应用程序开发人员主要是使用该层封装好的api进行快速开发。

applications:该层是java的应用程序层,android内置的googlemapse-mail、即时通信工具、浏览器、mp3播放器等处于该层,java开发人员开发的程序也处于该层,而且和内置的应用程序具有平等的位置,可以调用内置的应用程序,也可以替换内置的应用程序。

上面的四个层次,下层为上层服务,上层需要下层的支持,调用下层的服务,这种严格分层的方式带来的极大的稳定性、灵活性和可扩展性,使得不同层的开发人员可以按照规范专心特定层的开发。

android应用程序使用框架的api并在框架下运行,这就带来了程序开发的高度一致性,另一方面也告诉我们,要想写出优质高效的程序就必须对整个 applicationframework进行非常深入的理解。精通applicationframework,你就可以真正的理解android的设计和运行机制,也就更能够驾驭整个应用层的开发。


5.Android的四大组件是哪些,它们的作用?

ActivityActivityAndroid程序与用户交互的窗口,是Android构造块中最基本的一种,它需要为保持各界面的状态,做很多持久化的事情,妥善管理生命周期以及一些跳转逻辑。

service:后台服务于Activity,封装有一个完整的功能逻辑实现,接受上层指令,完成相关的事务,定义好需要接受的Intent提供同步和异步的接口。

Content Provider:是Android提供的第三方应用数据的访问方案,可以派生Content Provider类,对外提供数据,可以像数据库一样进行选择排序,屏蔽内部数据的存储细节,向外提供统一的接口模型,大大简化上层应用,对数据的整合提供了更方便的途径。

BroadCast Receiver:接受一种或者多种Intent作触发事件,接受相关消息,做一些简单处理,转换成一条Notification,统一了Android的事件广播模型。

6.横竖屏切换时的Activity的生命周期


横竖屏切换时候Activity的生命周期

曾经遇到过一个面试题,让你写出横屏切换竖屏Activity的生命周期。现
在给大家分析一下他切换时具体的生命周期是怎么样的:

1、新建一个Activity,并把各个生命周期打印出来

2、运行Activity,得到如下信息

onCreate-->
onStart-->
onResume-->

3、按crtl+f12切换成横屏时

onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->

4、再按crtl+f12切换成竖屏时,发现打印了两次相同的log

onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->

5、修改AndroidManifest.xml,把该Activity添加
android:configChanges="orientation",执行步骤3

onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->

6、再执行步骤4,发现不会再打印相同信息,但多打印了一行onConfigChanged

onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
onConfigurationChanged-->

7、把步骤5的android:configChanges="orientation"改成
android:configChanges="orientation|keyboardHidden",执行步骤3,就只打印
onConfigChanged

onConfigurationChanged-->

8、执行步骤4

onConfigurationChanged-->
onConfigurationChanged-->

总结:

1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,
切横屏时会执行一次,切竖屏时会执行两次

2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调
用各个生命周期,切横、竖屏时只会执行一次

3、设置Activity的android:configChanges="orientation|keyboardHidden"时,
切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法

总结一下整个Activity的生命周期

补充一点,当前Activity产生事件弹出Toast和AlertDialog的时候Activity的生命
周期不会有改变

Activity运行时按下HOME键(跟被完全覆盖是一样的):onSaveInstanceState -->
onPause --> onStop       onRestart-->onStart--->onResume

Activity未被完全覆盖只是失去焦点:onPause--->onResume


7.Android的动画有哪几种?他们的特点和区别是什么?


答:两种,一种是tween动画,一种是frame动画。tween动画,这种实现方式可以使视图组件移动,放大或缩小以及产生透明度的变化。frame动画,传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影。


8.Handler机制的原理

答:android提供了handlerlooper来满足线程间的通信。Handler先进先出原则。looper用来管理特定线程内对象之间的消息交换(message Exchange.

  1)looper:一个线程可以产生一个looper对象,由它来管理此线程里的message queue(消息队列)

  2)handler:你可以构造一个handler对象来与looper沟通,以便push新消息到messagequeue里;或者接收looper(从messagequeue里取出)所送来的消息。

  3)messagequeue:用来存放线程放入的消息。

  4)线程:UI thread 通常就是main thread,android启动程序时会为它建立一个message queue.



9.说说MVC模式的原理,它在Android中的运用


答:android的官方建议应用程序的开发采用mvc模式。何谓mvc

mvcmodel,view,controller的缩写,mvc包含三个部分:

l模型(model)对象:是应用程序的主体部分,所有的业务逻辑都应该写在该层。

2视图(view)对象:是应用程序中负责生成用户界面的部分。也是在整个mvc架构中用户唯一可以看到的一层,接收用户的输入,显示处理结果。

3控制器(control)对象:是根据用户的输入,控制用户界面数据显示及更新model对象状态的部分,控制器更重要的一种导航功能,想用用户出发的相关事件,交给m哦得了处理。

android鼓励弱耦合和组件的重用,在androidmvc的具体体现如下:

   1)视图层(view):一般采用xml文件进行界面的描述,使用的时候可以非常方便的引入,当然,如何你对android了解的比较的多了话,就一定可以想到在android中也可以使用javascript+html等的方式作为view层,当然这里需要进行javajavascript之间的通信,幸运的是,android提供了它们之间非常方便的通信实现。

2)控制层(controller):android的控制层的重任通常落在了众多的acitvity的肩上,这句话也就暗含了不要在acitivity中写代码,要通过activity交割model业务逻辑层处理,这样做的另外一个原因是android中的acitivity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。

3)模型层(model):对数据库的操作、对网络等的操作都应该在model里面处理,当然对业务计算等操作也是必须放在的该层的。


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

答:AIDL(AndroidInterface DefinitionLanguage)android接口描述语言

11.SQLite支持事务码?添加删除如何提高性能?

答:SQLite作为轻量级的数据库,比MySQL还小,但支持SQL语句查询,提高性能可以考虑通过原始经过优化的SQL查询语句方式处理。

12.Android Service和Binder、AIDL你都熟练吗?

作为Android重要的后台服务,这些每个Android开发者都应该掌握,这也算是和Java SE最大的不同了,具体的实例大家可以查看Android音乐播放器的源代码Music.git中的,这里不再赘述


13.塞班,安卓,WP,IOS这几种系统各有什么优缺点

塞班:入手快速,但智能程度低
安卓:优点不少,但是吸费门也同样屡屡爆出
WP7
:操作界面的风格会有人不喜欢,也是微软对手机系统的一次改革(以前微软往往舍速度追求功能,现在重心开始向速度方面转变)
iOS
:安装这个系统的设备价格要高出不少,相对而言入手慢些,优势很明显,不多说


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

onSaveInstanceState() 当你的程序中某一个Activity A在运行时,主动或被动地运行另一个新的Activity B,这个时候A会执行onSaveInstanceState()B完成以后又会来找A

这个时候就有两种情况:一是A被回收,二是A没有被回收,被回收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上了参数savedInstanceState;而没被收回的就直接执行onResume(),跳过onCreate()了。

另外,刚才查看了一下Activity的源码,发现Activity还有个onRestoreInstanceState(BundleoutState)方法.这个方法的描述中也写到在Activity回复先前保存的状态时会被调用.

你可能感兴趣的:(android)