android笔试题.docx
- 文档编号:30077519
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:33
- 大小:38.31KB
android笔试题.docx
《android笔试题.docx》由会员分享,可在线阅读,更多相关《android笔试题.docx(33页珍藏版)》请在冰豆网上搜索。
android笔试题
Android笔试题
1.请描述下Activity的声明周期。
正常启动的过程中,他们被调用的顺序是onCreate->onStart->onResume,在Activity被干掉的时候顺序是onPause->onStop->onDestroy,这样就是一个完整的生命周期,但是有人问了,程序正运行着呢来电话了,这个程序咋办?
中止了呗,如果中止的时候新出的一个Activity是全屏的那么:
onPause->onStop,恢复的时候onStart->onResume,如果打断这个应用程序的是一个Theme为Translucent或者Dialog的Activity那么只是onPause,恢复的时候onResume。
详细介绍一下这几个方法中系统在做什么以及我们应该做什么:
onCreate:
在这里创建界面,做一些数据的初始化工作
onStart:
到这一步变成用户可见不可交互的
onResume:
变成和用户可交互的,(在activity栈系统通过栈的方式管理这些个
Activity的最上面,运行完弹出栈,则回到上一个Activity)
onPause:
到这一步是可见但不可交互的,系统会停止动画等消耗CPU的事情从上文的描述已经知道,应该在这里保存你的一些数据,因为这个时候 你的程序的优先级降低,有可能被系统收回。
在这里保存的数据,应该在 onResume里读出来,注意:
这个方法里做的事情时间要短,因为下一个activity不会等到这个方法完成才启动
onstop:
变得不可见,被下一个activity覆盖了
onDestroy:
这是activity被干掉前最后一个被调用方法了,可能是外面类调用finish方法或者是系统为了节省空间将它暂时性的干掉,可以用isFinishing()来判断它,如果你有一个ProgressDialog在线程中转动,请在onDestroy里把他cancel掉,不然等线程结束的时候,调用Dialog的cancel方法会抛异常的。
onPause,onstop,onDestroy,三种状态下activity都有可能被系统干掉。
2.如果后台的Activity由于某种原因被系统回收,如何在回收之前保存当前状态。
onSaveInstanceState().
程序中的某一个ActivityA在运行时,主动或被动的运行另一个新的ActivityB,这个时候A会执行onSaveInstanceState()。
B完成以后又回来找A,这个时候有两种情况:
一是A被回收,二是A没有被回收,被回收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上了参数savedInstanceState;而没被回收的就直接执行onResume(),跳过onCreate()。
3.如何将一个Activity设置成窗口样式。
在AndroidManifext.xml中Activity定义处添加
android:
theme="@android:
style/Theme.Dialog"或
android:
theme="@android:
style/Theme.Translucent"。
4.如何退出Activity?
如何安全退出已调用多个Activity的Application?
对于单一Activity的应用来说,退出很简单,直接finish()即可。
当然,也可以用killProcess()和System.exit()这样的方法。
至于退去application则
在2.1之前,可以使用ActivityManager的restartPackage方法。
2.1之后的方法有
1、抛异常强制退出:
该方法通过抛异常,使程序ForceClose。
验证可以,但是,需要解决的问题是,如何使程序结束掉,而不弹出ForceClose的窗口。
2、记录打开的Activity:
每打开一个Activity,就记录下来。
在需要退出时,关闭每一个Activity即可。
3、发送特定广播:
在需要结束应用时,发送一个特定的广播,每个Activity收到广播后,关闭即可。
4、递归退出:
在打开新的Activity时使用startActivityForResult,然后自己加标志,在onActivityResult中处理,递归关闭。
5.请介绍下android大众常用的五种布局。
FrameLayout(框架布局)LinearLayout(线性布局)AbsoluteLayout(绝对布局)
RelativeLayout(相对布局)TableLayout(表格布局)
(1)——FrameLayout框架布局,放入其中的所有元素都被放置在最左上的区域,而且无法为这些元素指定一个确切的位置,下一个子元素会重叠覆盖上一个子元素,适合浏览单张图片。
(2)LinearLayout线性布局,是应用程序中最常用的布局方式,主要提供控件水平或者垂直排列的模型,每个子组件都是以垂直或水平的方式来定位.(默认是垂直)
(3)AbsoluteLayout绝对定位布局,采用坐标轴的方式定位组件,左上角是(0,0)点,往右x轴递增,往下Y轴递增,组件定位属性为android:
layout_x和android:
layout_y来确定坐标。
(4)RelativeLayout相对布局,根据另外一个组件或是顶层父组件来确定下一个组件的位置。
和CSS里面的类似。
(5)TableLayout表格布局,类似Html里的Table.使用TableRow来布局,其中TableRow代表一行,TableRow的每一个视图组件代表一个单元格。
6.请介绍下android的数据存储方式。
Android提供了5种方式存储数据:
(1)使用SharedPreferences存储数据;它是Android提供的用来存储一些简单配置信息的一种机制,采用了XML格式将数据存储到设备中。
只能在同一个包内使用,不能在不同的包之间使用。
(2)文件存储数据;文件存储方式是一种较常用的方法,在Android中读取/写入文件的方法,与Java中实现I/O的程序是完全一样的,提供了openFileInput()和openFileOutput()方法来读取设备上的文件。
(3)SQLite数据库存储数据;SQLite是Android所带的一个标准的数据库,它支持SQL语句,它是一个轻量级的嵌入式数据库。
(4)使用ContentProvider存储数据;主要用于应用程序之间进行数据交换,从而能够让其他的应用保存或读取此ContentProvider的各种数据类型。
(5)网络存储数据;通过网络上提供给我们的存储空间来上传(存储)和下载(获取)我们存储在网络空间中的数据信息。
7。
请介绍下ContentProvider是如何实现数据共享的。
一个程序可以通过实现一个Contentprovider的抽象接口将自己的数据完全暴露出去,而且Contentproviders是以类似数据库中表的方式将数据暴露。
Contentproviders存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方法。
要想使应用程序的数据公开化,可通过2种方法:
创建一个属于你自己的Contentprovider或者将你的数据添加到一个已经存在的Contentprovider中,前提是有相同数据类型并且有写入Contentprovider的权限。
8。
如何启用Service,如何停用Service。
1.第一种是通过调用Context.startService()启动,调用Context.stopService()结束,startService()可以传递参数给Service
2.第二种方式是通过调用Context.bindService()启动,调用Context.unbindservice()结束,还可以通过ServiceConnection访问Service。
在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。
9.Receiver的生命周期?
广播注册的两种方法和区别?
Android引入广播机制的用意。
生命周期:
在onReceive()执行的时候期间。
引入广播机制用意:
可以方便几大组件的信息和数据交互。
b:
程序间互通消息(例如在自己的应用程序内监听系统来电)
c:
效率上(参考UDP的广播协议在局域网的方便性)
d:
设计模式上(反转控制的一种应用,类似监听者模式)。
第一种方式:
在Manifest.xml中注册广播,是一种比较推荐的方法,因为它不需要手动注销广播(如果广播未注销,程序退出时可能会出错)。
具体实现在Manifest的application中添加:
上面两个android:
name分别是广播名和广播的动作(这里的动作是表示系统启动完成),如果要自己发送一个广播,在代码中为:
Intenti=newIntent(“android.intent.action.BOOT_COMPLETED”);
sendBroadcast(i);
这样,广播就发出去了,然后是接收。
接收可以新建一个类,继承至BroadcastReceiver,也可以建一个BroadcastReceiver的实例,然后得写onReceive方法,实现如下:
protectedBroadcastReceivermEvtReceiver=newBroadcastReceiver(){
@Override
publicvoidonReceive(Contextcontext,Intentintent){
Stringaction=intent.getAction();
if(action.equals(“android.intent.action.BOOT_COMPLETED”)){
//Dosomething
}
}
};
第二种方式,直接在代码中实现,但需要手动注册注销,实现如下:
IntentFilterfilter=newIntentFilter();
filter.addAction(“android.intent.action.BOOT_COMPLETED”);
registerReceiver(mEvtReceiver,filter);//这时注册了一个recevier,名为mEvtReceiver,然后同样用上面的方法以重写onReceiver,
最后在程序的onDestroy中要注销广播,实现如下:
@Override
publicvoidonDestroy(){
super.onDestroy();
unregisterReceiver(mPlayerEvtReceiver);
}
在Android中如果要发送一个广播必须使用sendBroadCast向系统发送对其感兴趣的广播接收器中。
使用广播必须要有一个intent对象必设置其action动作对象
使用广播必须在配置文件中显式的指明该广播对象
每次接收广播都会重新生成一个接收广播的对象
在BroadCast中尽量不要处理太多逻辑问题,建议复杂的逻辑交给Activity或者Service去处理
10.请解释下在单线程模型中Message,Handler,MessageQueue,Looper之间的关系。
MessageQueue
消息队列MessageQueue是一个以执行时间为序的优先级队列:
普通消息的执行为当前时间,先发送的前面,后发送在后面,这是典型的FIFO。
最高优先级的消息执行时间为0,所以直接插在队列的最前面,通常会立即执行。
而在将来执行的Message相当于timer,执行时间为当前时间+delay的时间。
MessageQueue的函数booleanenqueueMessage(Messagemsg,longwhen)用来向队列中插入消息。
Message和GTK+idle不同之处在于,Message只是一段数据,里面说明了要做什么,但不并知道如何做。
而idle带有自己的数据和处理函数,它知道如何做。
Message放入队列中后,在处理这些消息时到底要做些什么呢?
这就引入了Handler:
Handler对消息队列的enqueueMessage做了包装,这其实并不重要,因为完全可以直接调用enqueueMessage来实现。
重要的Handler把在包装enqueueMessage的同时,把Message的target设成了自己,即为Message指定执行的行为:
if(queue!
=null){
msg.target=this;
sent=queue.enqueueMessage(msg,uptimeMillis);
}
这样一来,当前Message被处理的时候就会调用Handler的dispatchMessage,而这个函数就会调用你要实现的虚函数handleMessage了。
经过消息队列转了一圈,还是调用了你自己的实现函数,但是同步操作变成了异步操作。
publicvoiddispatchMessage(Messagemsg){
if(msg.callback!
=null){
handleCallback(msg);
}else{
if(mCallback!
=null){
if(mCallback.handleMessage(msg)){
return;
}
}
handleMessage(msg);
}
}
Looper
Message放在消息队列里了,谁来一个一个的取出来处理呢?
这时轮到Looper上场了,它的函数loop会一直循环处理队列中的消息,直到遇上一个没有target的Message:
publicstaticfinalvoidloop(){
Looperme=myLooper();
MessageQueuequeue=me.mQueue;
while(true){
Messagemsg=queue.next();//mightblock
//if(!
me.mRun){
// break;
//}
if(msg!
=null){
if(msg.target==null){
//Notargetisamagicidentifierforthequitmessage.
return;
}
if(me.mLogging!
=null)me.mLogging.println(
">>>>>Dispatchingto"+msg.target+""
+msg.callback+":
"+msg.what
);
msg.target.dispatchMessage(msg);
if(me.mLogging!
=null)me.mLogging.println(
"<<<< +msg.callback); msg.recycle(); } } } 由此可见: 一个Looper总是和一个MessageQueue关联起来的。 Thread loop只是一个函数,它也需要别人来执行它。 由于它一执行就会阻塞在那里,所以一定需要一个线程来调用: * classLooperThreadextendsThread{ * publicHandlermHandler; * * publicvoidrun(){ * Looper.prepare(); * * mHandler=newHandler(){ * publicvoidhandleMessage(Messagemsg){ * //processincomingmessageshere * } * }; * * Looper.loop(); * } * } 一个Looper也总是和一个Thread关联起来的,不过不一定要创建新线程,可以是主线程的。 Handler和Thread不是一一对应的,理论上,在一个LooperThread中,可以有任何多个Handler,每个消息都可以指定不同的Handler,因为每个消息都可以有不同的行为。 在创建Handler时并不会创建Thread,它只是取当前线程的Looper的MessageQueue: publicHandler(){ if(FIND_POTENTIAL_LEAKS){ finalClass extendsHandler>klass=getClass(); if((klass.isAnonymousClass()||klass.isMemberClass()||klass.isLocalClass())&& (klass.getModifiers()&Modifier.STATIC)==0){ Log.w(TAG,"ThefollowingHandlerclassshouldbestaticorleaksmightoccur: "+ klass.getCanonicalName()); } } mLooper=Looper.myLooper(); if(mLooper==null){ thrownewRuntimeException( "Can'tcreatehandlerinsidethreadthathasnotcalledLooper.prepare()"); } mQueue=mLooper.mQueue; mCallback=null; } 通过myLooper取出当前线程的Looper: publicstaticfinalLoopermyLooper(){ return(Looper)sThreadLocal.get(); } 这个Looper是在Looper.prepare里创建的: publicstaticfinalvoidprepare(){ if(sThreadLocal.get()! =null){ thrownewRuntimeException("OnlyoneLoopermaybecreatedperthread"); } sThreadLocal.set(newLooper()); } 11.AIDL的全程是什么? 如何工作? 能处理哪些类型的数据? AIDL全称AndroidInterfaceDefinitionLanguage(AndRoid接口描述语言)是一种借口描述语言;编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程跨界对象访问的目的.AIDL的IPC的机制和COM或CORBA类似,是基于接口的,但它是轻量级的。 它使用代理类在客户端和实现层间传递值.如果要使用AIDL,需要完成2件事情: 1.引入AIDL的相关类.;2.调用aidl产生的class.理论上,参数可以传递基本数据类型和String,还有就是Bundle的派生类,不过在Eclipse中,目前的ADT不支持Bundle做为参数, 12.请解释下Android程序运行时权限与文件系统权限的区别。 apk程序是运行在虚拟机上的,对应的是Android独特的权限机制,只有体现到文件系统上时才使用linux的权限设置。 android系统有的权限是基于签名的。 13.系统上安装了多种浏览器,能否指定某浏览器访问指定页面? 通过直接发送Uri把参数带过去,或者通过manifest里的intentfilter里的data属性 14.有一个一维整型数组int[]data保存的是一张宽为width,高为height的图片像素值信息。 请写一个算法,将该图片所有的白色不透明(0xffffffff)像素点的透明度调整为50%。 15.你如何评价Android系统? 优缺点。 一、开放性 二、挣脱运营商的束缚 三、丰富的硬件选择 四、不受任何限制的开发商 五、无缝结合的Google应用 再说Android的5大不足: 一、安全和隐私 二过分依赖开发商缺少标准配置 16.android中的动画有哪几类,他们的特点和区别是什么? 两种,一种是Tween动画,一种是Frame动画。 Tween动画: 使试图组件移动,放大,缩小以及产生透明度的变化。 Frame动画: 传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影。 17.横竖屏切换时activity的生命周期 不设置Activity的android: configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次。 设置Activity的android: configChanges="orientation"时,切横,竖屏时生命周期只会执行一次。 设置Activity的android: configChanges="orientation|keyboardHidden"时,切屏不会重新调用声明周期,只会执行onConfigurationChanged方法。 18.Android进程的5个等级 1.ForegroundProcess前台进程 ActivityResume()状态 Activity绑定Service,正在交互 Service生命周期正在被执行 BroadcastReceiver正在执行onReceive() 2.VisibleProcess 可见进程 Activity不在前端显示,但没有完全隐藏 3.ServiceProcess 服务进程 正在运行,不在上述两种状态的Service 4.BackgroundProcess后台进程 不可见状态 5.EmptyProcess 空进程 19、何为ANR,何时会产生ANR 1.界面操作(按钮的点击)相应时间超过5秒 2.BroadcastReceiver执行超过10秒 20、如何防止ANR 将耗时操作在子线程中执行 21、Manifest文件的是什么时候加载的? 系统启动的时候PackageManageService(系统级服务)读取Manifest信息,在系统级的共享内存中建立一信息库,可看作一张可供查询的数据库表 启动应用程序的时候,Launcher进行系统级判断,从信息库中查询Activity并进行实例化.并判断sdk版本 22、Manifest中定义的Activity,Ser
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- android 笔试