1.说说Android系统的优缺点:
有点:开放性,丰富的硬件选择,无缝结合的Google应用支持
缺点:安全和隐私,开发商自定义,不够统一,同类机型用户减少
2. 简单描述Android的四大组件:
Activity是Android程序与用户交互的窗口,是Android构造块中最基本的一种,它需要为保持各界面的状态,做胡肯多持久化的事情,妥善管理生命周期以及一些跳转逻辑。
Service后台服务于Activity,封装有一个完整的功能逻辑实现,接受上层指令,完成相关的事务,定义好需要接受的Intent提供同步和异步的接口。
ContentProvider是Android提供的第三方应用数据的访问方案,可以派生ContentProvider类,对外提供数据,可以像数据库一样进行选择排序,屏蔽内部数据的存储细节,向外提供统一的接口模型,大大简化上层应用,对数据的整合提供了更方便的途径。
BroadCastReceiver接收一种或多种Intent作触发事件,接收相关信息,做一些简单处理,转换成一条Notification,统一了Android的事件广播模型。
的生命周期:
onCreate onStart onStop onPause onResume onDestroy
可见生命周期:从onStart直到系统调用onstop
前台生命周期:从onResume直到系统调用onPause
4.如何启用Service,如何停用Service:
第一步:继承Service类
public class ServiceDemo extends Service{}
第二步:在文件中的<application>节点里对服务进行配置:
<service android:name=".ServiceDemo"/>
服务不能自己运行,需要通过调用()或者()方法启动服务。这两种方法都可以启动Service,但是它们的使用场合有所不同。使用startService()方法启动服务,调用者与服务之间没有关联,即使调用者退出了,服务仍然运行。使用bindService()方法启动服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止。
如果采用()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onstart()方法,如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onstart()方法。采用startService()方法启动的服务,只能调用()方法结束服务,服务结束时会调用onDestroy()方法。
如果采用()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。
5.请介绍下Android中常用的五种布局:
LinearLayout:线性布局,每个LinearLayout里面又可以分为垂直布局和水平布局。如果是垂直布局,每一行就只有一个元素,多个元素依次垂直往下排布;如果是水平布局,只有一行,每一个元素依次向右排布。
RelativeLayout:相对布局,可以理解为某一个元素为参照物,来定位的布局方式。
FrameLayout:单帧布局,所有子元素依次放在左上角,会重叠,这个布局比较简单,也只能放一些比较简单的东西。
AbsoluteLayout:绝对布局,用X、Y坐标来指定元素的位置,这种布局比较简单,但是在屏幕旋转时,往往会出现问题,而且多个元素的时候,计算计较麻烦。
TableLayout:表格布局,每一个TableLayout里面有表格行TableRow,TableRow里面可以具体定义每一个元素。
的存储方式有哪些:
文件,SQLite,SharePreferences,ContentProvider,网络。
在屏幕旋转时的生命周期:
不设置Activity的android:configChanges时,切换会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次;设置Activity的android:configChanges="orientation"时,切换还是会重新调用各个生命周期,切横、竖屏时只会执行一次;设置Activity的android:configChanges="onrientationo|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法。
8.注册广播有几种方式,这些方式有何优缺点,请谈谈Android引入广播机制的用意:
首先写一个类要继承BroadCastReceiver
第一种:在清单文件中声明,添加
<receive android:name=".BroadCastReceiverDemo">
<intent-filter>
<action android:name=".SMS_RECEIVED">
</intent-filter>
</receiver>
第二种:使用代码进行注册如:
IntentFilter filter = new IntentFilter(".SMS_RECEIVED");
BroadCastReceiverDemo receiver = new BroadCastReceiver();
registerReceiver(receiver, filter);
两种注册类型的区别是:
a.第一种是常驻型广播,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。
b.第二种不是常驻广播,也就是说广播跟随程序的生命周期。
9.请解释下在单线程模型中Message、Handler、MessageQueue、Looper之间的关系:
Handler获取当前线程中的Looper对象,Looper对象用来从存放Message的MessageQueue中取出Message,再由Handler进行Message的分发和处理。
10.简要解释一下activity、intent、intentfilter、service、BroadCast、BroadCastReceiver
一个activity呈现了一个用户可以操作的可视化用户界面;一个service不包含可见的用户界面,而是在后台运行,可以与一个Activity绑定,通过绑定暴露出来的接口并与其进行通信;一个BroadCastReceiver是一个接收广播消息并做出回应的component,BroadCastReceiver没有界面;一个intent是一个Intent对象,它保存了消息的内容。对于activity和service来说,它指定了请求的操作名称和待操作数据的URI,Intent对象可以显式的指定一个目标component。如果这样的话,android会找到一个component并激活它,但如果一个目标不是显式指定的,android必须找到响应intent的最佳component。它是通过将Intent对象和目标的intentfilter相比较完成这一工作的;一个component的intentfilter也是在文件中声明的。
11.什么是ANR,如何避免它:
ANR:ApplicationNotResponding。在Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应,当用户操作在5s内应用程序没能做出反应,BroadCastReceiver在10s内没有执行完毕,就会出现应用程序无响应对话框,即ANR。
避免方法:Activity应该在它的关键生命周期方法(如onCreate和onResume)里面尽可能少的去做创建操作。潜在的耗时操作,例如网络或者数据库操作,或者高耗时的计算(如改变位图尺寸),应该在子线程或异步方式来完成。主线程应该为子线程提供一个Handler,以便完成时能够提交给主线程。
12.什么情况会导致Force Close,如何避免,能否捕获导致其的异常:
程序出现异常,比如nullpointer
避免:编写程序时,逻辑连贯,思维缜密。
能捕获异常,在logcat中能看到异常信息。
13.描述下Android的系统架构:
Android系统架构从上往下分为应用层、应用程序框架层、运行库、内核
有何优点:
Activity的进程,当处理Intent的时候,会产生一个对应的Service;Android的进程处理器现在会尽可能的不kill掉你,非常容易使用。
15.如果后台的Activity由于某原因被系统回收了,如何在被系统回收之前保存当前状态:
重写onSaveInstanceState()方法,在此方法中保存需要保存的数据,该方法将会在activity被回收之前调用。通过重写onRestoreInstanceState()方法可以从中提取保存好的数据。
本身的API并未声明会抛出异常,则其在运行时有无可能抛出runtime异常,你遇到过吗?若有的话,会导致什么问题?如何解决:
会,比如nullpointerException。遇到过,比如()时,textview没有初始化。会导致程序无法正常运行,出现forceclose。打开控制台查看logcat信息找出异常信息,并修改程序。
17.请介绍下ContentProvider是如何实现数据共享的:
一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据完全暴露出去,而且ContentProvider是以类似数据库中表的方式将数据暴露的。
ContentProvider存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方法。
要想使应用程序的数据公开化,可以通过创建一个属于自己的ContentProvider或者将数据添加到一个已经存在的ContentProvider中,前提是有相同数据类型并且有写入ContentProvider的权限。
Android提供了ContentResolver,外界的程序可以通过ContentResolver接口访问ContentProvider提供的数据。
18.如何退出Activity?如何安全退出已调用多个Activity的Application:
对于单一Activity的应用来说,直接finish()即可。当然也可以用killProcess()和()这样的方法。
对于多个activity,1、记录打开的Activity:每打开一个Activity,就记录下来,在需要退出时,关闭每一个Activity即可。2、发送特定广播:在需要结束应用时,发送一个特定的广播,每个Activity接收到广播后,关闭即可。3、递归退出:在打开新的Activity时使用startActivityForResult,然后自己添加标志,在onActivityResult中处理,递归关闭,为了编程方便,最好定义一个Activity基类,处理这些共通问题。
19.系统上安装了多种浏览器,能否指定某浏览器访问指定页面:
通过直接发送Uri把参数带过去,或者通过manifest里面的intentfilter里的data属性。
是什么:
NDK是一系列工具集合,NDK提供了一系列的工具,帮助开发者迅速的开发C/C++的动态库,并能自动将so和Java应用打成apk包。
NDK集成了交叉编译器,并提供了相应的mk文件和隔离cpu、平台等的差异,开发人员只需要简单的修改mk文件就可以创建出so文件。
21.嵌入式操作系统存储管理有哪几种:
页式、段式、段页,用到了MMU,虚拟空间等技术。
22.什么是嵌入式实时操作系统,Android操作系统属于实时操作系统吗:
嵌入式实时操作系统是指当外界事件或者数据产生时,能够接收并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统作出快速响应,并控制所有实时任务协调一致运行的嵌入式操作系统。主要用于工业控制、军事设备、航空航天等领域,对系统的响应时间有苛刻的要求。实时系统又分为软实时和硬实时两种,而Android是基于Linux内核的,属于软实时。
dvm的进程和Linux的进程,应用程序的进程是否同一个概念:
DVM指dalivk的虚拟机。每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟机实例。而每一个DVM都是在Linux中的一个进程,所以说可以认为是同一个概念。
24.说说mvc模式的原理,它在Android中的运用,Android的官方建议应用程序的开发采用mvc模式。何谓mvc:
mvc是model、view、controller的缩写,mvc包含三个部分:
模型(model )对象:是应用程序的主体部分,所有的业务逻辑都应该写在该层。
视图(view)对象:是应用程序中负责生成用户界面的部分。也是在整个mvc架构中用户唯一可以看到的一层,接收用户的输入,显示处理结果。
控制(controller)对象:是根据用户的输入,控制用户界面数据显示及更新model对象状态的部分,控制器更重要的一种导航功能,响应用户出发的相关事件,交给m层处理。
Android鼓励弱耦合和组件的重用,在android中mvc的具体体现如下:
a、视图层(view):一般采用xml文件进行界面的描述,使用的时候可以非常方便的引入,当然,如果对Android比较了解的话,就一定可以想到在Android中也可以使用javascript+thml等方式作为view层,当然这需要进行Java和javascript之间的通信,幸运的是,Android提供了它们之间非常方便的通信实现。
b、控制层(controller):Android的控制层的重任通常落在Activity的肩上,也就是不要在Activity中写代码,要通过Activity交给model业务逻辑层处理,这样做的另一个原因就是Android中的Activity的响应时间是5s,如果耗时的操作放在这里,程序就容易被回收掉。
c、模型层(model):对数据库、网络等的操作都应该放在model里面处理,当然对业务计算等操作也是必须放在该层的。
的启动模式有哪些,是什么含义:
启动模式分别为:standard、singleTop、singleTask、singleInstance
它们主要有如下不同:
a、如何决定所属task
standard和singleTop的activity的目标task,和收到的Intent的发送者在同一个task内,除非intent包含参数FLAG_ACTIVITY_NEW_TASK。如果提供了FLAG_ACTIVITY_NEW_TASK参数,会启动到别的task里。singleTask和singleInstance总是把activity作为一个task的根元素,他们不会被启动到一个其他task里。
b、是否允许多个实例
standard和singleTop可以被实例化多次,并且存在于不同的task中,且一个task可以包括一个activity的多个实例;singleTask和singleInstance则限制只生成一个实例,并且是task的根元素。singleTop要求如果创建intent的时候栈顶已经有要创建的Activity的实例,则将intent发送给该实例,而不发送给新的实例。
c、是够允许其他activity存在于本task内
singleInstance独占一个task,其他activit不能存在那个task里;如果它启动了一个新的activity,不管新的activity的launch mode如何,新的activity都将会到别的task里运行(如同加了FLAG_ACTIVITY_NEW_TASK)。而另外三种模式,则可以和其他activtiy共存。
d、是否每次都生成新实例
standard对于每一个启动Intent都会生成一个Activity的新实例;singleTop的Activity如果在task的栈顶的话,则不生成新的该Activity的实例,直接使用栈顶的实例,否则,生成该Activity的实例;singleInstance是其所在栈的唯一activity,他会每次都被重用;singleTask如果在栈顶,则接收intent,否则,该intent会被丢弃,但是该task仍会回到前台。
26.跟activity和Task有关的Intent启动方式有哪些:
核心的Intent Flag:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_SINGLE_TOP
的优化方案:
a、如果自定义适配器,那么在getView方法中要考虑方法传进来的参数contentView是否为null,如果为null就创建contentView并返回,如果不为null,则直接使用。在这个方法中尽可能少创建view。
b、给contentView设置tag,传入一个viewHolder对象用于缓存要显示的数据,可以达到图像数据异步加载的效果。
c、如果listView要显示的item很多,就要考虑分页加载,比如一共要显示100条或者更多的数据时,可以考虑先加载20条,等用户拉到列表底部时,再去加载接下来的20条。
中的动画有哪几类,它们的特点和区别是什么:
两种,一种是Tween动画,另一种是Frame动画。Tween动画,这种方式可以使视图组件移动、放大、缩小以及产生透明度的变化;另一种Frame动画,传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影。
中有哪几种解释xml的类,官方推荐哪种,以及它们的原理和区别:
xml解释主要有三种方式,SAX、DOM、PULL。常规的PC上开发使用DOM相对轻松些,但一些性能敏感的数据或手机上还是主要采用SAX方法,SAX读取是单向的,优点:不占内存空间,解释属性方便,但缺点就是对嵌套多个分支来处理不是很方便。而DOM方式会把整个xml文件加载到内存中,这里Android开发网提醒大家该方法在查找方面可以和XPath很好的结合,如果数据量不是很大推荐使用,而PULL常常用在J2ME对于节点处理比较好,类似SAX方式,同样很节省内存,在J2ME中经常使用的KXML库来解析。
和SurfaceView的区别:
SurfaceView是从View基类中派生出来的显示类,直接子类有GLSurfaceView和VedioView,可以看出GL和视频播放以及Camera摄像头一般均使用SurfaceView。对于Surface相关的,Android底层还提供了GPU加速功能,所以一般实时性很强的应用中主要使用SurfaceView而不是直接从View构建;SurfaceView和View最本质的区别在于,SurfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。
View的刷新:
Android中对View的更新有很多种方式,使用时要区分不同的应用场合,即多线程和双缓冲的使用情况。
a、不使用多线程和双缓冲
这种情况比较简单,一般只是希望在View发生改变时,对UI进行重绘,只需在Activity中显示的调用View对象中的invalidate()方法即可。系统会自动调用View的onDraw()方法。
b、使用多线程和不使用双缓冲
这种情况需要开启新的线程,新开的线程就不好访问View对象了,强制访问的话会报:$CalledFromWrongThreadException:Only the originalthread that created a view hierarchy can touch its views.这时候需要创建一个继承了的子类,并重写handleMessage(Message msg)方法。是能发送和处理消息的,需要在Activity中发出更新UI的消息,然后在Handler,也就是说,在新线程创建并发送一个Message,然后在主线程中捕获、处理该消息。
c、使用多线程和爽缓冲
Android中SurfaceView是View的子类,同时也现实了双缓冲。可以定义一个它的子类并实现接口。由于实现接口,新线程就不需要帮忙了。SurfaceHolder中lockCanvas()方法可以锁定画布,绘制完新的图像后再调用unlockCanvasAndPost(canvas)解锁(显示),还是比较方便的。
32.谈谈Android的IPC机制:
IPC是内部进程通信的简称,是共享“命名管道“的资源。Android中IPC机制是为了让Activity和Service之间可以随时的进行交互,故在Android中该机制,只适用于Activity和Service之间的通信,类似于远程方法调用,类似于C/S模式的访问。通过定义AIDL接口文件来定义IPC接口。Service端实现IPC接口,Client端调用IPC接口本地代理。
类的作用:
API里的第一句话是:
Base class for those who need to maintain global application state.
如果想在整个应用中使用全局变量,在java中一般是使用静态变量,public类型;而在Android中如果使用这样的全局变量就不符合Android的框架架构,但是可以使用一种更优雅的方式使用Application context。
首先需要重写Application,主要重写里面的onCreate方法,就是创建的时候,初始化变量的值。然后在整个应用中的各个文件中可以对该变量进行操作了。
启动Application时,系统会创建一个PID,即进程ID,所有的Activity就会在此进程上运行。那么在Application创建的时候初始化全局变量,同一个应用的所有Activity都可以去到这些全局变量的值,换句话说,在某一个Activity中改变了这些全局变量的值,那么在同一个应用的其他Activity中的值就会改变。
中如何计算一张Bitmap的大小:
在SDK >= 3.1 直接调用Bitmap的getByteCount()方法。
在SDK < 3.1 ()*();