移动应用开发面试题

来源:互联网 发布:此情唯有落花知txt 编辑:程序博客网 时间:2024/04/28 12:09

 1 Android dvm的进程和Linux的进程,应用程序的进程是否为同一个概念?

  DVMdalivk的虚拟机。每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟机实例。而每一个DVM都是在Linux中的一个进程,所以说可以认为是同一个概念。

 

  2sim卡的EF文件有何作用?

  sim卡的文件系统有自己规范,主要是为了和手机通讯,sim本身可以有自己的操作系统,EF就是作存储并和手机通讯用的

 

  3、嵌入式操作系统内存管理有哪几种,各有何特性?

  页式,段式,段页,用到了MMU,虚拟空间等技术

 

  4、什么是嵌入式实时操作系统, Android操作系统属于实时操作系统吗?

  嵌入式实时操作系统是指当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统作出快速响应,并控制所有实时任务协调一致运行的嵌入式操作系统。主要用于工业控制、军事设备、航空航天等领域对系统的响应时间有苛刻的要求,这就需要使用实时系统。又可分为软实时和硬实时两种,而android是基于linux内核的,因此属于软实时。

 

  5、一条最长的短信息约占多少byte?

  中文70(包括标点),英文160160个字节。

 

  6 android中的动画有哪几类,它们的特点和区别是什么?

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

 

  7handler机制的原理

  andriod提供了 Handler Looper 来满足线程间的通信。Handler先进先出原则。Looper类用来管理特定线程内对象之间的消息交换(Message Exchange)

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

  2)Handler:你可以构造Handler对象来与Looper沟通,以便push新消息到Message Queue;或者接收LooperMessage Queue取出)所送来的消息。

  3) Message Queue(消息队列):用来存放线程放入的消息。

  4)线程:UI thread通常就是main thread,而Android启动程序时会替它建立一个Message Queue

 

8、说说mvc模式的原理,它在android中的运用?

    MVC(Model_view_contraller)”模型_视图_控制器”。 MVC应用程序总是由这三个部分组成。Event(事件)导致Controller改变ModelView,或者同时改变两者。

    只要 Controller改变了Models的数据或者属性,所有依赖的View都会自动更新。类似的,只要Control

 

  9Activity的生命周期是怎样的?

  和其他手机平台的应用程序一样,Android的应用程序的生命周期是被统一掌控的,也就是说我们写的应用程序命运掌握在别人(系统)的手里,我们不能改变它,只能学习并

适应它。简单地说一下为什么是这样:我们手机在运行一个应用程序的时候,有可能打进来电话发进来短信,或者没有电了,这时候程序都会被中断,优先去服务电话的基本功能,另

外系统也不允许你占用太多资源,至少要保证电话功能吧,所以资源不足的时候也就有可能被干掉。

  言归正传,Activity的基本生命周期如下代码所示:

  Java代码

  public class MyActivity extends Activity {

    protected void onCreate(Bundle savedInstanceState);

   protected void onStart();

   protected void onResume();

   protected void onPause();

   protected void onStop();

   protected void onDestroy();

  }

 

  你自己写的Activity会按需要重载这些方法,onCreate是免不了的,在一个Activity正常启动的过程中,

   他们被调用的顺序是 onCreate -> onStart -> onResume,Activity被干掉的时候顺序是onPause -> onStop -> onDestroy

   这样就是一个完整的生命周期,但是有人问了,程序正运行着呢来电话了,这个程序咋办?

   中止了呗,如果中止的时候新出的一个Activity是全屏的那么:onPause->onStop,恢复的时候onStart->onResume

   如果打断这个应用程序的是一个ThemeTranslucent或者Dialog Activity那么只是onPause ,恢复的时候onResume

 

  详细介绍一下这几个方法中系统在做什么以及我们应该做什么:

  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]来处理多线程和界面交互的问题。这个我后面会讲一些,最近因为这些东西头已经很大了,等我理清思绪再跟大家分享。 ller改变了ViewView会从潜在的Model中获取数据来刷新自己。

 

10、如何让Activity变成一个窗口?Activity属性设定

讲点轻松的吧,可能有人希望做出来的应用程序是一个漂浮在手机主界面的东西,那么很简单你只需要设置一下Activity的主题就可以了在AndroidManifest.xml中定义 Activity的地方一句话:

  Xml代码:

android :theme="@android:style/Theme.Dialog"

 

  这就使你的应用程序变成对话框的形式弹出来了,或者

  Xml代码:

  android:theme="@android:style/Theme.Translucent"

 

  就变成半透明的,[友情提示-.-]类似的这种activity的属性可以在android.R.styleable类的AndroidManifestActivity 方法中看到,AndroidManifest.xml中所有元素的属性的介绍都可以参考这个类android.R.styleable

 

  上面说的是属性名称,具体有什么值是在android.R.style中可以看到,比如这个"@android:style/Theme.Dialog"就对应于android.R.style.Theme_Dialog ,('_'换成'.' < --注意:这个是文章内容不是笑脸)就可以用在描述文件中了,找找类定义和描述文件中的对应关系就都明白了。

 

  11、你后台的Activity被系统回收怎么办? OnSaveInstanceState

当你的程序中某一个Activity A在运行时中,主动或被动地运行另一个新的Activity B

  这个时候A会执行

  Java代码

  public void onSaveInstanceState(Bundle outState) {

  super.onSaveInstanceState(outState);

  outState.putLong("id", 1234567890);

  }

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

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

  Java代码

  if(savedInstanceState != null){

   long id = savedInstanceState.getLong("id");

  }

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

 

  12、调用与被调用:我们的通信使者Intent

  要说Intent了,Intent就是这个这个意图,应用程序间Intent进行交流,打个电话啦,来个电话啦都会发Intent,这个是Android架构的松耦合的精髓部分,大大提高了组件的复用性,比如你要在你的应用程序中点击按钮,给某人打电话,很简单啊,看下代码先:

  Java代码

  Intent intent = new Intent();

  intent.setAction(Intent.ACTION_CALL);

  intent.setData(Uri.parse("tel:" + number));

  startActivity(intent);

 

  扔出这样一个意图,系统看到了你的意图就唤醒了电话拨号程序,打出来电话。

    什么读联系人,发短信啊,邮件啊,统统只需要扔出intent就好了,这个部分设计地确实很好啊。

  那Intent通过什么来告诉系统需要谁来接受他呢?

  通常使用Intent有两种方法,第一种是直接说明需要哪一个类来接收代码如下:

 

  Java代码

  Intent intent = new Intent(this, MyActivity.class);

  intent.getExtras().putString("id", "1");

  tartActivity(intent);

 

  第一种方式很明显,直接指定了MyActivity为接受者,并且传了一些数据给MyActivity,在MyActivity里可以用getIntent()来的到这个intent和数据。

 

  第二种就需要先看一下AndroidMenifest中的intentfilter的配置了

  Xml代码

  < intent-filter>

  < action

  android:name="android.intent.action.VIEW"

  />

  < action

  android:value="android.intent.action.EDIT"

  />

  < action

  android:value="android.intent.action.PICK"

  />

  < category

  android:name="android.intent.category.DEFAULT"

  />

  < data

  android:mimeType="vnd.android.cursor.dir/vnd.google.note"

  />

  < /intent-filter>

 

  这里面配置用到了action, data, category这些东西,那么聪明的你一定想到intent里也会有这些东西,然后一匹配不就找到接收者了吗?action其实就是一个意图的字符串名称。上面这段intent-filter的配置文件说明了这个Activity可以接受不同的Action,当然相应的程序逻辑也不一样咯,提一下那个 mimeType,他是在ContentProvider里定义的,你要是自己实现一个ContentProvider就知道了,必须指定mimeType才能让数据被别人使用。

  不知道原理说明白没,总结一句,就是你调用别的界面不是直接new那个界面,而是通过扔出一个intent,让系统帮你去调用那个界面,这样就多么松藕合啊,而且符合了生命周期被系统管理的原则。

  想知道category都有啥,Android为你预先定制好的action都有啥等等,请亲自访问官方链接Intent

  ps:想知道怎么调用系统应用程序的同学,可以仔细看一下你的logcat,每次运行一个程序的时候是不是有一些信息比如:

Starting activity: Intent { action=android.intent.action.MAINcategories={android.intent.category.LAUNCHER} flags=0x10200000comp={com.android.camera/com.android.camera.GalleryPicker} }

 

  再对照一下Intent的一些set方法,就知道怎么调用咯,希望你喜欢:)

 

 

  Android面试题

 

  1. 请描述下Activity的生命周期。

 

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

 

  3. 如何将一个Activity设置成窗口的样式。(Edited by Sodino)

 

  4. 如何退出Activity?如何安全退出已调用多个ActivityApplication?

 

  5. 请介绍下Android中常用的五种布局。

 

  6. 请介绍下Android的数据存储方式。(Edited by Sodino)

 

  7. 请介绍下ContentProvider是如何实现数据共享的。(Edited by Sodino)

 

  8. 如何启用Service,如何停用Service(Edited by Sodino)

 

  9. 注册广播有几种方式,这些方式有何优缺点?请谈谈Android引入广播机制的用意。

 

  10. 请解释下在单线程模型中MessageHandlerMessage QueueLooper之间的关系。

 

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

 

  12. 请解释下Android程序运行时权限与文件系统权限的区别。(Edited by Sodino)

 

  13. 系统上安装了多种浏览器,能否指定某浏览器访问指定页面?请说明原由。

 

  14. 有一个一维整型数组int[]data保存的是一张宽为width,高为height的图片像素值信息。请写一个算法,将该图片所有的白色不透明(0xffffffff)像素点的透明度调整为50%

 

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

 

  1、什么是ANR如何避免它?

 

  答:ANRApplication Not Responding,五秒

    Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应。当出现下列情况时,Android就会显示ANR对话框了:

  对输入事件(如按键、触摸屏事件)的响应超过5

  意向接受器(intentReceiver)超过10秒钟仍未执行完毕Android应用程序完全运行在一个独立的线程中(例如main)

    这就意味着,任何在主线程中运行的,需要消耗大量时间的操作都会引发ANR

    因为此时,你的应用程序已经没有机会去响应输入事件和意向广播(Intent broadcast)

  因此,任何运行在主线程中的方法,都要尽可能的只做少量的工作。

    特别是活动生命周期中的重要方法如onCreate() onResume()等更应如此。

    潜在的比较耗时的操作,如访问网络和数据库;或者是开销很大的计算,比如改变位图的大小,需要在一个单独的子线程中完成 (或者是使用异步请求,如数据库操作)

    但这并不意味着你的主线程需要进入阻塞状态已等待子线程结束 --也不需要调用Therad.wait()或者Thread.sleep()方法。

    取而代之的是,主线程为子线程提供一个句柄(Handler),让子线程在即将结束的时候调用它(xing:可以参看Snake的例子,这种方法与以前我们所接触的有所不同)

    使用这种方法涉及你的应用程序,能够保证你的程序对输入保持良好的响应,从而避免因为输入事件超过5秒钟不被处理而产生的ANR

    这种实践需要应用到所有显示用户界面的线程,因为他们都面临着同样的超时问题。

 

  2、什么情况会导致Force Close ?如何避免?能否捕获导致其的异常?

  答:一般像空指针啊,可以看起logcat,然后对应到程序中来解决错误

 

  3Android本身的api并未声明会抛出异常,则其在运行时有无可能抛出runtime异常,你遇到过吗?诺有的话会导致什么问题?如何解决?

 

  4、简要解释一下activity intentintent filterserviceBroadcaseBroadcaseReceiver

  答:一个activity呈现了一个用户可以操作的可视化用户界面一个service不包含可见的用户界面,而是在后台无限地运行可以连接到一个正在运行的服务中,连接后,可以通过服务中暴露出来的借口与其进行通信一个broadcast receiver是一个接收广播消息并作出回应的componentbroadcast receiver没有界面intent:content provider在接收到ContentResolver的请求时被激活。

  activity, servicebroadcast receiver是被称为intents的异步消息激活的。

    一个intent是一个Intent对象,它保存了消息的内容。对于activityservice来说,它指定了请求的操作名称和待操作数据的URI

  Intent对象可以显式的指定一个目标component。如果这样的话,android会找到这个component(基于 manifest文件中的声明)并激活它。

    但如果一个目标不是显式指定的,android必须找到响应intent的最佳component

  它是通过将Intent对象和目标的intent filter相比较来完成这一工作的。

    一个componentintent filter告诉androidcomponent能处理的intentintent filter也是在manifest文件中声明的。

 

  5IntentService有何优点?

  答:IntentService的优点:

  * Acitivity的进程,当处理Intent的时候,会产生一个对应的Service

  * Android的进程处理器现在会尽可能的不kill掉你

  * 非常容易使用

 

  6、横竖屏切换时候activity的生命周期?

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

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

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

 

 

 

 

  1. 如何将SQLite数据库(dictionary.db文件)apk文件一起发布?

 

  解答:可以将dictionary.db文件复制到Eclipse Android工程中的res aw目录中。

    所有在res aw目录中的文件不会被压缩,这样可以直接提取该目录中的文件。可以将dictionary.db文件复制到res aw目录中

 

  2. 如何将打开res aw目录中的数据库文件?

 

  解答:在Android中不能直接打开res aw目录中的数据库文件,而需要在程序第一次启动时将该文件复制到手机内存或SD卡的某个目录中,

    然后再打开该数据库文件。复制的基本方法是使用getResources().openRawResource方法获得res aw目录中资源的 InputStream对象,

    然后将该InputStream对象中的数据写入其他的目录中相应文件中。

    Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法来打开任意目录中的SQLite数据库文件。

 

  3. Android引入广播机制的用意?

 

  答:a:MVC的角度考虑(应用程序内)

    其实回答这个问题的时候还可以这样问,

    android为什么要有那4大组件?

    现在的移动开发模型基本上也是照搬的web那一套MVC架构,只不过是改了点嫁妆而已。

    android的四大组件本质上就是为了实现移动或者说嵌入式设备上的MVC架构,它们之间有时候是一种相互依存的关系,

    有时候又是一种补充关系,引入广播机制可以方便几大组件的信息和数据交互。

 

  b:程序间互通消息(例如在自己的应用程序内监听系统来电)

  c:效率上(参考UDP的广播协议在局域网的方便性)

  d:设计模式上(反转控制的一种应用,类似监听者模式)

原创粉丝点击