android常见面试题

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

7、handler机制的原理

 

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

 

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

 

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

 

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

 

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

 

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

 

 MVC(Model_view_contraller)”模型_视图_控制器”。MVC应用程序总是由这三个部分组成。Event(事件)导致Controller改变Model或View,或者同时改变两者。只要Controller改变了Models的数据或者属性,所有依赖的View都会自动更新。类似的,只要Contro

 

9、Activity的生命周期

 

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

  简单地说一下为什么是这样:我们手机在运行 一个应用程序的时候,有可能打进来电话 发进来短信 ,或者没有电了,这时候程序都会被中断,优先去服务电话的基本功能 ,另 外系统也不允许你占用太多资源 ,至少要保证电话功能吧,所以资源不足的时候也就有可 能被干掉。

 

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

 

  Java代码

 

  public  class MyActivity extends Activity {

 

  protected   void onCreate(BundlesavedInstanceState);

 

  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,如果打断 这个应用程序的是一个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都有可能被系统干掉

 

 为了保证程序的正确性,你要在onPause()里写上持久层操作的代码,将用户编辑的内容都保存到存储介质上(一般都是数据库)。实际工作中因为生命周期的变化而带来的问题也很多,比如你的应用程序起了新的线程在跑,这时候中断了,你还要去维护那个线程,是暂停还是杀掉还是数据回滚,是吧?因为Activity可能被杀掉,所以线程中使用的变量和一些界面元素就千万要注意了,一般我都是采用Android的消息机制[Handler,Message]来处理多线程和界面交互的问题。这个我后面会讲一些,最近因为这些东西头已经很大了,等我理清思绪再跟大家分享。ller改变了View,View会 从潜在的Model中获取数据来刷新自己。

 

10、让Activity变成一个窗口:Activity属性设定

 

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

 

  Xml代码

 

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

 

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

 

  Xml代码

 

  1.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代码

 

  1. public

 

  2. void onSaveInstanceState(Bundle outState) {

 

  3. super.onSaveInstanceState(outState);

 

  4. outState.putLong("id", 1234567890);

 

  5. }

 

  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代码

 

  1. if(savedInstanceState != null){

 

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

 

  3. }

 

  if(savedInstanceState != null){

 

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

 

  }

 

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

 

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

 

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

 

  Java代码

 

  1. Intent intent = new Intent();

 

  2. intent.setAction(Intent.ACTION_CALL);

 

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

 

4.startActivity(intent);

 

  Intent intent = new Intent();

 

  intent.setAction(Intent.ACTION_CALL);

 

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

 

  startActivity(intent);

 

  扔出这样一个意图,系统看到了你的意图就唤醒了电话拨号程序,打出来电话。什么读联系人,发短信啊,邮件啊,统统只需要扔出intent就好了,这个部分设计 地确实很好啊。

 

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

 

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

 

  Java代码

 

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

 

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

 

  3. tartActivity(intent);

 

  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方法,就知道怎么调用咯,希望你喜欢:)

 

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

 

  答:ANR:Application Not Responding,五秒

 

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

 

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

 

  意向接受器(intentReceiver)超过10秒钟仍未执行完毕

 

  Android应用程序完全运行在一个独立的线程中(例如main)。这就意味着,任何在主线程中运行的,需要消耗大量时间的操作都会引发ANR。因为此时,你的应用程序已经没有机会去响应输入事件和意向广播(Intentbroadcast)。

 

  因此,任何运行在主线程中的方法,都要尽可能的只做少量的工作。特别是活动生命周期中的重要方法如onCreate()和onResume()等更应如此。潜在的比较耗时的操作,如访问网络和数据库;或者是开销很大的计算,比如改变位图的大小,需要在一个单独的子线程中完成(或者是使用异步请求,如数据库操作)。但这并不意味着你的主线程需要进入阻塞状态已等待子线程结束-- 也不需要调用Therad.wait()或者Thread.sleep()方法。取而代之的是,主线程为子线程提供一个句柄(Handler),让子线程在即将结束的时候调用它(xing:可以参看Snake的例子,这种方法与以前我们所接触的有所不同)。使用这种方法涉及你的应用程序,能够保证你的程序对输入保持良好的响应,从而避免因为输入事件超过5秒钟不被处理而产生的ANR。这种实践需要应用到所有显示用户界面的线程,因为他们都面临着同样的超时问题。

 

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

 

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

 

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

 

       答:会,如nullpointerException,textView没有初始化时,却调用了其方法。打开控制台,查看logcat找出异常并修改。

  16、简要解释一下activity、intent 、intentfilter、service、Broadcase、BroadcaseReceiver

 

  答:一个activity呈现了一个用户可以操作的可视化用户界面

 

  一个service不包含可见的用户界面,而是在后台无限地运行

 

  可以连接到一个正在运行的服务中,连接后,可以通过服务中暴露出来的借口与其进行通信

 

  一个broadcast receiver是一个接收广播消息并作出回应的component,broadcastreceiver没有界面

 

  intent:content provider在接收到ContentResolver的请求时被激活。

 

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

 

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

 

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

 

  它是通过将Intent对象和目标的intent filter相比较来完成这一工作的。一个component的intentfilter告诉android该component能处理的intent。intentfilter也是在manifest文件中声明的。

 

 17、IntentService有何优点?

 

  答:IntentService 的好处

 

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

 

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

 

  * 非常容易使用

 

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

 

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

 

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

 

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

 

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

 

  解答:可以将dictionary.db文件复制到Eclipse Android工程中的resaw目录中。所有在resaw目录中的文件不会被压缩,这样可以直接提取该目录中的文件。可以将dictionary.db文件复制到resaw目录中

 

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

 

  解答:在Android中不能直接打开res aw目录中的数据库文件,而需要在程序第一次启动时将该文件复制到手机内存或SD卡的某个目录中,然后再打开该数据库文件。复制的基本方法是使用getResources().openRawResource方法获得resaw目录中资源的InputStream对象,然后将该InputStream对象中的数据写入其他的目录中相应文件中。在Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法来打开任意目录中的SQLite数据库文件。

 

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

 

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

 

 其实回答这个问题的时候还可以这样问,android为什么要有那4大组件,现在的移动开发模型基本上也是照搬的web那一套MVC架构,只不过是改了点嫁妆而已。android的四大组件本质上就是为了实现移动或者说嵌入式设备上的MVC架构,它们之间有时候是一种相互依存的关系,有时候又是一种补充关系,引入广播机制可以方便几大组件的信息和数据交互。

 

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

 

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

 

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

 

22.   android 中我们常用的布局方式有这么几种:

1.LinearLayout ( 线性布局 ) (里面只可以有一个控件,并且不能设计这个控件的位置,控件会放到左上角)

                                          线性布局分为水平线性和垂直线性二者的属性分别为:android:orientation=" horizontal "  android:orientation= "vertical"

 2.RelativeLayout ( 相对布局 ) (里面可以放多个控件,但是一行只能放一个控件

    3.TableLayout ( 表格布局 ) (这个要和TableRow配合使用,很像html里面的table)

 这个表格布局不像HTML中的表格那样灵活,只能通过 TableRow 属性来控制它的行而列的话里面有几个控件就是几列(一般情况)

android:gravity="center" 书面解释是权重比。其时就是让它居中显示。它还可以动态添加里面的每行每列。

4.AbsoluteLayout ( 绝对布局 ) (里面可以放多个控件,并且可以自己定义控件的x,y的位置)

5.FrameLayout ( 帧布局 ) (里面可以放多个控件,不过控件的位置都是相对位置)

                               在它里面的控件都是按后面的一个控件叠加在前一个控件上来显示的,所有元素都被放置在最左上角

23.xml解析数据的方式:

Xml解析主要有SAX,Dom,PULL

在pc上使用DOM相对轻松写,在手机上采用SAX,因为SAX采用的是单向读取不占用内存空间,解析方便,但对嵌套多分之的数据处理不方便

PULL在J2ME上对节点处理较好

 

24. Android中5种数据存储方式 

 SharedPreferences存储数据。 

 ContentProvider存储 

 文件存储 

 SQLlite存储 

 网络存储 

 

25.androidview 的刷新机制

在Android的布局体系中,父View负责刷新、布局显示子View;而当子View需要刷新时,则是通知父View来完成。

 

步骤就是:

1、调用子View的invalidate()

2、跳转到上一层的invalidateChild函数中区

3、在一次调用invalidateChildInParent的函数一次层层刷新

 

26HashMap与HashTable的区别

1.hashMap去掉了HashTable contains方法,但是加上了containsValue()和containsKey()方法。
2.hashTable同步的,而HashMap是非同步的,效率上逼hashTable要高。
3.hashMap允许空键值,而hashTable不允许。

 

27.android中的四大组件

Android有四大组件:ActivityServiceBroadcast ReceiverContent Provider
 
在这些组件之间的通讯中,主要是由Intent协助完成的。
Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。
因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。

 

28.android中px,dp,sp的区别

Px:每个项目对应屏幕的像素点

Dp:基于屏幕密度的抽象单位

Sp:主要处理字体大小

 

29.list与map的区别

List:元素仿佛有顺序,且元素不可重复,内存分配是零散的,采用双向迭代,得到一个之的速度不快,但是插入,删除数据效率很高

Map:元素一键值对的像是存储,元素放入无顺序,底层采用树形结构

 

29ArrayList与HashMap

ArrayList是list的实现类,是用数组实现的list

lhaspMap是map的实现类,hashMap是用hasp实现map,是利用hashcode()进行快速数列查找

 

30.接口与抽象类

抽象类可以有普通成员变量,接口不行;
抽象类有非抽象的方法和构造方法,并且修饰符可以是私有的,
接口只能是抽象的方法,并且修饰符是public,接口继承一个抽象类,但能实现多个接口

 

31fianl与static的用法

final根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变:设计或效率。
        final类不能被继承,没有子类,final类中的方法默认是final的。
        final方法不能被子类的方法覆盖,但可以被继承。
        final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
        final不能用于修饰构造方法。
        注意:父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final类型的。
 

 static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。

        被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。

        用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类的对象市,不生成static变量的副本,而是类的所有实例共享同一个static变量。

 

32.封装,继承,多态

 封装:
  封装的意义在于保护或者防止代码(数据)被我们无意中破坏。在面向对象程序设计中数据被看作是一个中心的元素并且和使用它的函数结合的很密切,从而保护它不被其它的函数意外的修改。

继承:

  继承主要实现重用代码,节省开发时间。

多态

  1、多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。

  编译时的多态性:

  编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。 

  运行时的多态性:

  运行时的多态性就是指直到系统运行时,才根据实际情况决定实现何种操作。C#中,运行时的多态性通过虚成员实现。 

  编译时的多态性为我们提供了运行速度快的特点,而运行时的多态性则带来了高度灵活和抽象的特点。

   2、实现多态:

1.    接口多态性。

2.    继承多态性。

3.    通过抽象类实现的多态性。

  3、override关键字:

   重写父类中的virtual修饰的方法,实现多态。

33.重载与重写

重载是在同一个类中的两个或两个以上的方法,拥有相同的方法名,但是参数却不相同,方法体也不相同,最常见的重载的例子就是类的构造函数,

重写是子类的方法覆盖父类的方法,要求方法名和参数都相同

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值