`
tnje_2007
  • 浏览: 4240 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

【转】Android面试题大集合

阅读更多
转载自:http://my.oschina.net/xubohui/blog/78998
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个字节

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

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

7、handler机制的原理

andriod提供了 Handler 和 Looper 来满足线程间的通信。Handler 先进先出原则。Looper类用来管理特定线程内对象之间的消息交换(Message Exchange)。 1)Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的Message Queue(消息队列)。 2)Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息到Message Queue里;或者接收Looper从Message Queue取出)所送来的消息。 3) Message Queue(消息队列):用来存放线程放入的消息。 4)线程:UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。

8、说说mvc模式的原理,

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

(View重绘和内存泄露面试经常问的问题 )

9. View的刷新:

在需要刷新的地方,使用handle.sendmessage发送信息,然后在handle的getmessage里面执行invaliate或者postinvaliate。

可以调用invalidate()和postInvalidate()这两个方法刷新

10. GC内存泄露 出现情况:

1).数据库的cursor没有关闭

2).构造adapter时,没有使用缓存contentview 衍生listview的优化问题-----减少创建view的对象,充分使用contentview,可以使用一静态类来优化处理getview的过程/

3).Bitmap对象不使用时采用recycle()释放内存

4).activity中的对象的生命周期大于activity 调试方法: DDMS==> HEAPSZIE==>dataobject==>[Total Size]

11、 Activity的生命周期

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 ,如果打断 这个应用程序的是一个Theme为Translucent 或者Dialog 的Activity那么只是onPause ,恢复 的时候onResume

12、生命周期中的各个方法中都可以做什么?

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

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

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

onRestart:重新启动activity时调用。该活动仍在栈中,而不是启动新的活动

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

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

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

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

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

你只需要设置一下Activity的主题就可以了在AndroidManifest.xml 中定义 Activity的地方一句话: Xml代码 android :theme="@android :style/Theme.Dialog" android:theme="@android :style/Theme.Dialog" 这就使你的应用程序变成对话框的形式弹出来了,或者 Xml代码 android:theme="@android :style/Theme.Translucent" android:theme="@android :style/Theme.Translucent

14、后台的Activity被系统回收怎么办:(onSaveInstanceState )

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

Java代码

public void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState);

outState.putLong("id", 1234567890);

}

public void onSaveInstanceState(Bundle outState) {

B 完成以后又会来找A, 这个时候就有两种情况,一种是A被回收,一种是没有被回收,被回 收的A就要重新调用onCreate()方法,不同于直接启动的是这回 onCreate()里是带上参数 savedInstanceState,没被收回的就还是onResume就好了。 savedInstanceState是一个Bundle对象,你基本上可以把他理解为系统帮你维护的一个Map对象。在onCreate()里你可能会用到它,如果正常启动onCreate就不会有它,所以用的时候要判断一下是否为空

Java代码

if(savedInstanceState !=null){

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

}

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

15、四 调用与被调用:我们的通信使者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");

startActivity(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>

<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里也会有这些东西,然后一匹配不就找到接收者了吗?

16.listview你是怎么优化的

17,IPC及原理

IPC是内部进程通信的简称, 是共享"命名管道"的资源。Android中的IPC机制是为了让Activity和Service之间可以随时的进行交互,故在Android中该机制,只适用于Activity和Service之间的通信,类似于远程方法调用,类似于C/S模式的访问。通过定义AIDL接口文件来定义IPC接口。Servier端实现IPC接口,Client端调用IPC接口本地代理
18.Android多线程

19.Android为什么要设计4大组件,他们之间的联系

主要是为了实现MVC模式

20、DDMS与TraceView的区别?

DDMS是一个程序执行查看器,在里面你可以看见线程和堆栈等信息,TraceView是程序性能分析器

21、.在Java中如何引入C语言

可以用JNI接口来实现

22、Android国际化与本地化

internationalization (国际化)简称 i18n,因为在i和n之间还有18个字符,localization(本地化 ),简称L10n。 一般说明一个地区的语言时,用 语言_地区的形式,如  zh_CN, zh_TW. 各国语言缩写  http://www.loc.gov/standards/iso639-2/php/code_list.php 国家和地区简写 http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html android 对i18n和L10n提供了非常好的支持。android没有专门的API来提供国际化,而是通过对不同resource的命名来达到国际化,同时这种命名方法还可用于对硬件的区分,如不同的新视屏用不同的图片

我们以不同的local和region来做一次国际化,首先values表示默认的字符串,也即当Resource找不到匹配的资源时,默认使用values文件夹下的资源,其余 drawable等资源也是同样的。    当命名这些文件夹的名字时,不同的选项用-分开,而且次序必须和 andorid 文档中table http://developer.android.com/guide/topics/resources/resources-i18n.html#AlternateResources 文件夹的命名必须都是小写字符,否则在一些大小敏感的文件系统中可能会出错,如果你用大写,eclipse的adt都会自动报错。小写字母r表示region的意思。 上图命名了中文简体和繁体以及默认选项,在strings.xml中除了字符串本身不一样,xml中定义该字符串的名字,id都是一样的。所以在代码或者xml中引用该资源时,只要引用名字即可或者id即可,程序启动时候Resource类回到相应的目录下去寻找正确的字符串(资源)   通过在Settings中设置locale& Text 我们可以让Resource类来选择相应文件夹下的内容, 选择英语时候结果如下,也即选择了 values下的strings.xml 选择 chinese(china)时,也即选了 values-zh-rcn目录下的strings.xml 选择 chinese(taiwan)时,也即选了 values-zh-rtw目录下的strings.xml  其余手机的选项,像屏幕的像素等都可以建立相应得目录

23、在eclipse的工程中,res目录有默认几项resource,如 drawable, layout,menu,values 其余还有哪些?

res/anim/   用来放置动画

res/xml/     用来放置style theme等xml定义。

res/raw/    用来放置data数据

24、Android常用的控件

单选框(RadioButton与RadioGroup):

RadioGroup用于对单选框进行分组,相同组内的单选框只有一个单选框被选中。   事件:setOnCheckedChangeListener(),处理单选框被选择事件。把RadioGroup.OnCheckedChangeListener实例作为参数传入。

多选框(CheckBox):  每个多选框都是独立的,可以通过迭代所有的多选框,然后根据其状态是否被选中在获取其值。  事件:setOnCheckChangeListener()处理多选框被选择事件。把CompoundButton.OnCheckedChangeListener实例作为参数传入

下拉列表框(Spring):  Spinner.getItemAtPosition(Spinner.getSelectedItemPosition());获取下拉列表框的值。  事件:setOnItemSelectedListener(),处理下拉列表框被选择事件把AdapterView.OnItemSelectedListener实例作为参数传入;

拖动条(SeekBar):  SeekBar.getProgress()获取拖动条当前值  事件:setOnSeekBarChangeListener(),处理拖动条值变化事件,把SeekBar.OnSeekBarChangeListener实例作为参数传入。

菜单(Menu):  重写Activity的onCreatOptionMenu(Menu menu)方法,该方法用于创建选项菜单,当用户按下手机的"Menu"按钮时就会显示创建好的菜单,在onCreatOptionMenu(Menu Menu)方法内部可以调用Menu.add()方法实现菜单的添加。  重写Activity的onMenuItemSelected()方法,该方法用于处理菜单被选择事件。

进度对话框(ProgressDialog):  创建并显示一个进度对话框:ProgressDialog.show(ProgressDialogActivity.this,"请稍等","数据正在加载中....",true);  设置对话框的风格:setProgressStyle()   ProgressDialog.STYLE_SPINNER  旋转进度条风格(为默认风格)   ProgressDialog.STYLE_HORIZONTAL 横向进度条风格

25、Android系统架构

1、应用程序.   Android会同一系列核心应用程序包一起发布,该应用程序包包括email客户端,SMS短消息程序,日历,地图,浏览器,联系人管理程序等。所有的应用程序都是使用JAVA语言编写的。

  2.应用框架:   开发人员也可以完全访问核心应用程序所使用的API框架。该应用程序的架构设计简化了组件的重用;任何一个应用程序都可以发布它的功能块并且任何其它的应用程序都可以使用其所发布的功能块(不过得遵循框架的安全性限制)。同样,该应用程序重用机制也使用户可以方便的替换程序组件。   隐藏在每个应用后面的是一系列的服务和系统, 其中包括;  

* 丰富而又可扩展的视图(Views),可以用来构建应用程序, 它包括列表(lists),网格(grids),文本框(text boxes),按钮(buttons), 甚至可嵌入的web浏览器。 

* 内容提供器(Content Providers)使得应用程序可以访问另一个应用程序的数据(如联系人数据库), 或者共享它们自己的数据 

* 资源管理器(Resource Manager)提供 非代码资源的访问,如本地字符串,图形,和布局文件( layout files )。   * 通知管理器 (Notification Manager) 使得应用程序可以在状态栏中显示自定义的提示信息。 

* 活动管理器( Activity Manager) 用来管理应用程序生命周期并提供常用的导航回退功能。

3、系统运行库

1)程序库   Android 包含一些C/C++库,这些库能被Android系统中不同的组件使用。它们通过 Android 应用程序框架为开发者提供服务。以下是一些核心库:

  * 系统 C 库 - 一个从 BSD 继承来的标准 C 系统函数库( libc ), 它是专门为基于 embedded linux 的设备定制的。

   * 媒体库 - 基于 PacketVideo OpenCORE;该库支持多种常用的音频、视频格式回放和录制,同时支持静态图像文件。编码格式包括MPEG4, H.264, MP3, AAC, AMR, JPG, PNG 。 

* Surface Manager - 对显示子系统的管理,并且为多个应用程序提 供了2D和3D图层的无缝融合。  

* LibWebCore - 一个最新的web浏览器引擎用,支持Android浏览器和一个可嵌入的web视图。 

* SGL - 底层的2D图形引擎 

* 3D libraries - 基于OpenGL ES 1.0 APIs实现;该库可以使用硬件 3D加速(如果可用)或者使用高度优化的3D软加速。 

* FreeType -位图(bitmap)和矢量(vector)字体显示。  

* SQLite - 一个对于所有应用程序可用,功能强劲的轻型关系型数据库引擎。   2)Android 运行库   Android 包括了一个核心库,该核心库提供了JAVA编程语言核心库的大多数功能。   每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟机实例。Dalvik被设计成一个设备可以同时高效地运行多个虚拟系统。 Dalvik虚拟机执行(.dex)的Dalvik可执行文件,该格式文件针对小内存使用做了优化。同时虚拟机是基于寄存器的,所有的类都经由JAVA编译器编译,然后通过SDK中 的 “dx” 工具转化成.dex格式由虚拟机执行。   Dalvik虚拟机依赖于linux内核的一些功能,比如线程机制和底层内存管理机制

4)Linux内核

Android 的核心系统服务依赖于 Linux 2.6 内核,如安全性,内存管理,进程管理, 网络协议栈和驱动模型。 Linux 内核也同时作为硬件和软件栈之间的抽象层

26、开机自启动程序

27、什么是Activity?

通俗一点说Activity就是一个界面,这个界面里面可以放置各种控件。Activity的界面也是用xml文件表示的,放置在res->layout下面。每生成一个新的Activity后,我们需要在AndroidManifest.xml中注册一下这个activity

28、 两个Activity之间跳转时必然会执行的是哪几个方法。

onCreate() //在Activity生命周期开始时调用 onRestoreInstanceState()//用来恢复UI状态 onReStart()//当Activity重新启动时调用 onStart()//Activity对用户即将可见时调用 onResume()//当Activity与用户交互时,绘制界面 onSaveInstanceState()//activity即将移出栈顶保留UI状态时调用 onPause()//暂停当前活动activity,提交持久数据的改变,停止动画和其他占用CPU资源的东西,由于下一个activity在这个方法返回之前不会resume,所以这个方法的代码执行要快。 onStop()//activity不再可见时调用 onDestroy()//在Activity销毁钱被调用的最后一个方法。

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

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

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

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

30、 如何退出Activity?如何安全退出已调用多个Activity的Application?

用finish()方法退出activity.

在2.1之前,可以使用ActivityManager的restartPackage方法。 它可以直接结束整个应用。在使用时需要权限android.permission.RESTART_PACKAGES。

在2.2,这个方法失效了,可使用以下几个人工的方法

1、记录打开的Activity: 每打开一个Activity,就记录下来。在需要退出时,关闭每一个Activity即可。

2、发送特定广播: 在需要结束应用时,发送一个特定的广播,每个Activity收到广播后,关闭即可

3、递归退出:在打开新的Activity时使用startActivityForResult,然后自己加标志,在onActivityResult中处理,递归关闭

为了编程方便,最好定义一个Activity基类,处理这些共通问题

在2.1之前,可以使用ActivityManager的restartPackage方法。 它可以直接结束整个应用。在使用时需要权限android.permission.RESTART_PACKAGES。 注意不要被它的名字迷惑。 可是,在2.2,这个方法失效了。在2.2添加了一个新的方法,killBackground Processes(),需要权限 android.permission.KILL_BACKGROUND_PROCESSES。可惜的是,它和2.2的restartPackage一样,根本起不到应有的效果。 另外还有一个方法,就是系统自带的应用程序管理里,强制结束程序的方法,forceStopPackage()。它需要权限android.permission.FORCE_STOP_PACKAGES。并且需要添加android:sharedUserId="android.uid.system"属性。同样可惜的是,该方法是非公开的,他只能运行在系统进程,第三方程序无法调用。 因为需要在Android.mk中添加LOCAL_CERTIFICATE := platform。 而Android.mk是用于在Android源码下编译程序用的。 从以上可以看出,在2.2,没有办法直接结束一个应用,而只能用自己的办法间接办到。 现提供几个方法,供参考: 1、抛异常强制退出: 该方法通过抛异常,使程序Force Close。 验证可以,但是,需要解决的问题是,如何使程序结束掉,而不弹出Force Close的窗口。 2、记录打开的Activity: 每打开一个Activity,就记录下来。在需要退出时,关闭每一个Activity即可。 3、发送特定广播: 在需要结束应用时,发送一个特定的广播,每个Activity收到广播后,关闭即可。 4、递归退出 在打开新的Activity时使用startActivityForResult,然后自己加标志,在onActivityResult中处理,递归关闭。 除了第一个,都是想办法把每一个Activity都结束掉,间接达到目的。但是这样做同样不完美。你会发现,如果自己的应用程序对每一个Activity都设置了nosensor,在两个Activity结束的间隙,sensor可能有效了。但至少,我们的目的达到了,而且没有影响用户使用。为了编程方便,最好定义一个Activity基类,处理这些共通问题

31、  两个Activity之间怎么传递数据?

在Intent的对象中增加要传递的参数既可。  在Intent的对象的请求中加入键值对,对象名字.putExtra("键值对的名字","键值对的值");  在另一个Activity中将Intent请求中的数据取出来:   Intent intent=getIntent();//   String value = intent.getStringExtra("testIntent");//将testIntent对应的值赋值给value 

32、  怎么在启动一个Activity时就启动一个service?

将启动Service的语句放在onCreate()方法中。

33、同一个程序,但不同的Activity是否可以放在不同的Task任务栈中?

可以放在不同的Task中。需要为不同的activity设置不同的taskaffinity属性,启动activity的Intent需要包含FLAG_ACTIVITY_NEW_TASK标记

34、   Activity怎么和service绑定,怎么在activity中启动自己对应的service?

1、Activity能进行绑定得益于Service的接口。为了支持Service的绑定,实现onBind方法。

2、Service和Activity的连接可以用ServiceConnection来实现。你需要实现一个新的ServiceConnection,重写onServiceConnected和onServiceDisconnected方法,一旦连接建立,你就能得到Service实例的引用。

3、执行绑定,调用bindService方法,传入一个选择了要绑定的Service的Intent(显式或隐式)和一个你实现了的ServiceConnection实例

35 、 什么是Service以及描述下它的生命周期。

Android Service是运行在后台的代码,不能与用户交互,可以运行在自己的进程,也可以运行在其他应用程序进程的上下文里。需要通过某一个Activity或者其他Context对象来调用, Context.startService() 和 Context.bindService()。  如果在Service执行耗时的操作需要启动一个新线程来执行。 Android Service只继承了onCreate(),onStart(),onDestroy()三个方法,当我们第一次启动Service时,先后调用了onCreate(),onStart()这两个方法,当停止Service时,则执行onDestroy()方法,这里需要注意的是,如果Service已经启动了,当我们再次启Service时,不会在执行onCreate()方法,而是直接执行onStart()方法

36、 Service有哪些启动方法,有什么区别,怎样停用Service?

两种启动Service的方式Context.startService() 和 Context.bindService()。 区别为 Context.startService():Service会经历onCreate -> onStart(如果Service还没有运行,则android先调用onCreate()然后调用onStart();如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次 );stopService的时候直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。该Service的调用者再启动起来后可以通过stopService关闭Service   Context.bindService():Service会经历onCreate() -> onBind(),onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind -> onDestroyed相应退出,所谓绑定在一起就共存亡了 。 停用service使用 context.stopService()

37、  不用service,B页面为音乐播放,从A跳转到B,再返回,如何使音乐继续播放?

a 使用startActivityForResult() 方法开启b,b类结束时调用finish();

a类的intent有一个子activity结束事件onActivityResult(),在事件里继续播放音乐

38、 什么是IntentService?有何优点?

IntentService也是一个Service,是Service的子类, IntentService和Service有所不同,通过Looper和Thread来解决标准Service中处理逻辑的阻塞问题。  优点:Acitivity的进程,当处理Intent的时候,会产生一个对应的Service Android的进程处理器现在会尽可能的不kill掉你 非常容易使用 (看自己写的日历中IntentService的应用)

39、  什么时候使用Service?

比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记 录你地理信息位置的改变等等,总之服务嘛,总是藏在后头的。

40、 请描述一下Intent 和 Intent Filter

ntent在Android中被翻译为"意图",熟语来讲就是目的,他们是三种应用程序基本组件—activity,service和broadcast receiver之间互相激活的手段。 在调用Intent名称时使用ComponentName也就是类的全名时为显示调用。这种方式一般用于应用程序的内部调用,因为你不一定会知道别人写的类的全名。我们来看看隐式Intent怎么用? 首先我们先配置我们的Activity的Intent Filter <intent-filter>     <action android:name="com.example.project.SHOW_CURRENT" /> </intent-filter> 这样在调用的时候指定Intent的action,系统就是自动的去对比是哪个intent-filter符合我们的Activity,找到后就会启动Activity。 一个intent filter是IntentFilter类的实例, 但是它一般不出现在代码中,而是出现在android Manifest文件中, 以<intent-filter>的形式. (有一个例外是broadcast receiver的intent filter是使用Context.registerReceiver()来动态设定的, 其intent filter也是在代码中创建的.) 一个filter有action, data, category等字段. 一个隐式intent为了能被某个intent filter接受, 必须通过3个测试. 一个intent为了被某个组件接受, 则必须通过它所有的intent filter中的一个
41、Intent传递数据时,可以传递哪些类型数据?

Intent间传送数据一般有两种常用的办法:
1.extra  2.data.  extra可以用Intent.putExtra放入数据。新启动的Activity可用Intent.getExtras取出来Bundle, 然后用Bundles.getLong, getInt, getBoolean, getString等函数来取放进入的值。  而data则是传输url。url可以是指我们熟悉的http, ftp 等网络地址, 也可以指content来指向ContentProvider提供的资源。Intent.setData可以放入数据,Intent.getData可以取出数据
42、 说说Activity,Intent,Service是什么关系 。

一个Activity通常是一个单独的屏幕,每一个Activity都被实现为一个单独的类,这些类都是从Activity基类中继承来的,Activity类会显示由视图控件组成的用户接口,并对视图控件的事件做出响应。 Intent的调用是用来进行架构屏幕之间的切换的。Intent是描述应用想要做什么。Intent数据结构中两个最重要的部分是动作和动作对应的数据,一个动作对应一个动作数据。 Android Service是运行在后台的代码,不能与用户交互,可以运行在自己的进程,也可以运行在其他应用程序进程的上下文里。需要通过某一个Activity或者其他Context对象来调用。 Activity跳转到Activity,Activity启动Service,Service打开Activity都需要Intent表明跳转的意图,以及传递参数,Intent是这些组件间信号传递的承载者。
43、   请描述一下Broadcast Receiver。

Broadcast Receiver用于接收并处理广播通知(broadcast announcements)。多数的广播是系统发起的,如地域变换、电量不足、来电来信等。程序也可以播放一个广播。程序可以有任意数量的 broadcast receivers来响应它觉得重要的通知。broadcast receiver可以通过多种方式通知用户:启动activity、使用NotificationManager、开启背景灯、振动设备、播放声音等,最典型的是在状态栏显示一个图标,这样用户就可以点它打开看通知内容。通常我们的某个应用或系统本身在某些事件(电池电量不足、来电来短信)来临时会广播一个Intent出去,我们可以利用注册一个Broadcast Receiver来监听到这些Intent并获取Intent中的数据。
44、在manifest和代码中如何注册和使 用 broadcast receiver 。

1)在AndroidManifest.xml中注册
<receiver android:name="Receiver1"> 
<intent-filter>               
<!-- 和Intent中的action对应 -->  
<action android:name="com.forrest.action.mybroadcast"/>
</intent-filter>
</receiver> 
2)在代码中注册
1. IntentFilter filter = new IntentFilter("com.forrest.action.mybroadcast"); // 和广播中Intent的action对应
    2. MyBroadcastReceiver br = new MyBroadcastReceiver();  
3. registerReceiver(new MyBroadcastReceiver(), filter);
45、 请介绍下ContentProvider是如何实现数据共享的。

ContentProvider是通过提供Uri来实现数据共享
46、   请介绍下Android的数据存储方式。

Android提供了5种方式存储数据:
使用SharedPreferences存储数据;
文件存储数据;
  SQLite数据库存储数据; 
使用ContentProvider存储数据; 
网络存储数据
一:使用SharedPreferences存储数据
首先说明SharedPreferences存储方式,它是 Android提供的用来存储一些简单配置信息的一种机制,例如:登录用户的用户名与密码。其采用了Map数据结构来存储数据,以键值的方式存储,可以简单的读取与写入,
具体实例如下:
void ReadSharedPreferences(){
String strName,strPassword;
SharedPreferences   user = getSharedPreferences(“user_info”,0);
strName = user.getString(“NAME”,””);
strPassword = user getString(“PASSWORD”,””); }
void WriteSharedPreferences(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/<package name>/shares_prefs下。使用SharedPreferences是有些限制的:只能在同一个包内使用,不能在不同的包之间使用

二:文件存储数据 文件存储方式是一种较常用的方法,在Android中读取/写入文件的方法,与 Java中实现I/O的程序是完全一样的,提供了openFileInput()和openFileOutput()方法来读取设备上的文件。具体实例如下:
String fn = “moandroid.log”;
FileInputStream fis = openFileInput(fn);
FileOutputStream fos = openFileOutput(fn,Context.MODE_PRIVATE);
三:网络存储数据 网络存储方式,需要与Android 网络数据包打交道,关于Android 网络数据包的详细说明,请阅读Android SDK引用了Java SDK的哪些package?。
四:ContentProvider
1、ContentProvider简介 当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据。而使用ContentProvider共享数据的好处是统一了数据访问方式。
2、Uri类简介 Uri代表了要操作的数据,Uri主要包含了两部分信息:1.需要操作的ContentProvider ,2.对ContentProvider中的什么数据进行操作,一个Uri由以下几部分组成: 1.scheme:ContentProvider(内容提供者)的scheme已经由Android所规定为:content://… 2.主机名(或Authority):用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。 3.路径(path):可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
要操作contact表中id为10的记录,可以构建这样的路径:/contact/10 要操作contact表中id为10的记录的name字段, contact/10/name 要操作contact表中的所有记录,可以构建这样的路径:/contact? 要操作的数据不一定来自数据库,也可以是文件等他存储方式,如下: 要操作xml文件中contact节点下的name节点,可以构建这样的路径:/contact/name 如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
Uri uri = Uri.parse("content://com.changcheng.provider.contactprovider/contact")
3、UriMatcher、ContentUrist和ContentResolver简介 因为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使用insert、delete、update、query方法,来操作数据

47、   为什么要用ContentProvider?它和sql的实现上有什么差别?

使用ContentProvider可以将数据共享给其他应用,让除本应用之外的应用也可以访问本应用的数据。它的底层是用SQLite数据库实现的,所以其对数据做的各种操作都是以Sql实现,只是在上层提供的是Uri

48、  请介绍下Android中常用的五种布局

49、   谈谈UI中, Padding和Margin有什么区别?

Padding是文字相对于边框,而Margin是边框相对于父窗体
50、   请解释下在单线程模型中Message、Handler、Message Queue、Looper之间的关系

答:简单的说,Handler获取当前线程中的looper对象,looper用来从存放Message的MessageQueue中取出Message,再有Handler进行Message的分发和处理. Message Queue(消息队列):用来存放通过Handler发布的消息,通常附属于某一个创建它的线程,可以通过Looper.myQueue()得到当前线程的消息队列 Handler:可以发布或者处理一个消息或者操作一个Runnable,通过Handler发布消息,消息将只会发送到与它关联的消息队列,然也只能处理该消息队列中的消息 Looper:是Handler和消息队列之间通讯桥梁,程序组件首先通过Handler把消息传递给Looper,Looper把消息放入队列。Looper也把消息队列里的消息广播给所有的 Handler:Handler接受到消息后调用handleMessage进行处理 Message:消息的类型,在Handler类中的handleMessage方法中得到单个的消息进行处理 在单线程模型下,为了线程通信问题,Android设计了一个Message Queue(消息队列), 线程间可以通过该Message Queue并结合Handler和Looper组件进行信息交换。下面将对它们进行分别介绍:
1. Message 
   Message消息,理解为线程间交流的信息,处理数据后台线程需要更新UI,则发送Message内含一些数据给UI线程。
2. Handler      Handler处理者,是Message的主要处理者,负责Message的发送,Message内容的执行处理。后台线程就是通过传进来的 Handler对象引用来sendMessage(Message)。而使用Handler,需要implement 该类的 handleMessage(Message)方法,它是处理这些Message的操作内容,例如Update UI。通常需要子类化Handler来实现handleMessage方法。
3. Message Queue      Message Queue消息队列,用来存放通过Handler发布的消息,按照先进先出执行。     每个message queue都会有一个对应的Handler。Handler会向message queue通过两种方法发送消息:sendMessage或post。这两种消息都会插在message queue队尾并按先进先出执行。但通过这两种方法发送的消息执行的方式略有不同:通过sendMessage发送的是一个message对象,会被 Handler的handleMessage()函数处理;而通过post方法发送的是一个runnable对象,则会自己执行。
4. Looper      Looper是每条线程里的Message Queue的管家。Android没有Global的Message Queue,而Android会自动替主线程(UI线程)建立Message Queue,但在子线程里并没有建立Message Queue。所以调用Looper.getMainLooper()得到的主线程的Looper不为NULL,但调用Looper.myLooper() 得到当前线程的Looper就有可能为NULL。对于子线程使用Looper,API Doc提供了正确的使用方法:这个Message机制的大概流程:
  1. 在Looper.loop()方法运行开始后,循环地按照接收顺序取出Message Queue里面的非NULL的Message。 
  2. 一开始Message Queue里面的Message都是NULL的。当Handler.sendMessage(Message)到Message Queue,该函数里面设置了那个Message对象的target属性是当前的Handler对象。随后Looper取出了那个Message,则调用 该Message的target指向的Hander的dispatchMessage函数对Message进行处理。在dispatchMessage方法里,如何处理Message则由用户指定,三个判断,优先级从高到低:     1) Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工作;     2) Handler里面的mCallback指向的一个实现了Callback接口的对象,由其handleMessage进行处理;     3) 处理消息Handler对象对应的类继承并实现了其中handleMessage函数,通过这个实现的handleMessage函数处理消息。     由此可见,我们实现的handleMessage方法是优先级最低的!  
  3. Handler处理完该Message (update UI) 后,Looper则设置该Message为NULL,以便回收!     在网上有很多文章讲述主线程和其他子线程如何交互,传送信息,最终谁来执行处理信息之类的,个人理解是最简单的方法——判断Handler对象里面的Looper对象是属于哪条线程的,则由该线程来执行
1. 当Handler对象的构造函数的参数为空,则为当前所在线程的Looper;
2. Looper.getMainLooper()得到的是主线程的Looper对象,Looper.myLooper()得到的是当前线程的Looper对象

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

AIDL是一种接口定义语言,用于约束两个进程间的通信规则,供编译器生成代码,实现Android设备上的进程间通信。 进程之间的通信信息首先会被转换成AIDL协议消息,然后发送给对方,对方受到AIDL协议消息后再转换成相应的对象。 AIDL支持的类型包括Java基础类型和String,List,Map,CharSequence,如果使用自定义类型,必须实现Parcelable接口
52、  请解释下Android程序运行时权限与文件系统权限的区别。

运行时 Dalvik( android授权)  文件系统 linux 内核授权
53、系统上安装了多种浏览器,能否指定某浏览器访问指定页面?

通过直接发送Uri把参数带过去,或者通过manifest里的intentfilter里的data属性
在action 赋值为”android.intent.action.VIEW“ 时可接收如下scheme 为"http" 等等类型的data 。所以突发奇想,启动该程序后,指定action 及Uri ,即访问指定网页
54、对多线程的运用和理解,及多线程之间handle的传值

55、 对android虚拟机的理解,包括内存管理机制垃圾回收机制。 
56、  Framework工作方式及原理,Activity是如何生成一个view的,机制是什么。
57、 android本身的一些限制,比如apk包大小限制,读取大文件时的时间

58、 如何加载的音乐信息,如何改善其效率。

Android系统提供了MediaScanner,MediaProvider,MediaStore等接口,并且提供了一套数据库表格,通过Content Provider的方式提供给用户。当手机开机或者有SD卡插拔等事件发生时,系统将会自动扫描SD卡和手机内存上的媒体文件,如audio,video,图片等,将相应的信息放到定义好的数据库表格中。 改善效率可以从界面需要查询必备数据,不需要的不进行查询
59、  ListView如何提高其效率?

答:1、如果自定义适配器,那么在getView方法中要考虑方法传进来的参数contentView是否为null,如果为null就创建contentView并返回,如果不为null则直接使用。在这个方法中尽可能少创建view。 2、给contentView设置tag(setTag()),传入一个viewHolder对象,用于缓存要显示的数据,可以达到图像数据异步加载的效果。 3、如果listview需要显示的item很多,就要考虑分页加载。比如一共要显示100条或者更多的时候,我们可以考虑先加载20条,等用户拉到列表底部的时候再去加载接下来的20条
60、 启动应用后,改变系统语言,应用的语言会改变么?

不会
61、启动一个程序,可以主界面点击图标进入,也可以从一个程序中跳转过去,二者有什么区别?

从主界面启动一个应用程序是通过快捷方式直接调用mainActivity启动的,从其他应用程序调用需要隐式的通过Action或者在Intent中需要使用setClass(),且要写明包路径
62  Android程序与Java程序的区别?

android程序是Java编写的,但程序使用的android开发的API,就是andriod的库。
63、Android中Task任务栈的分配。

64、   在Android中,怎么节省内存的使用,怎么主动回收内存?
65、不同工程中的方法是否可以相互调用?
66、 在Android中是如何实现判断区分通话记录中的电话状态,去电,来电、未接来电?
67、  dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念

DVM指dalivk的虚拟机.每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的 Dalvik虚拟机实例.而每一个DVM都是在Linux中的一个进程,所以说可以认为是同一个概念.
68、如何判断是否有SD卡?

在程序中访问SDCard,你需要申请访问SDCard的权限
在AndroidManifest.xml中加入访问SDCard的权限如下: <!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) Environment.getExternalStorageState()方法用于获取SDCard的状态,如果手机装有SDCard,并且可以进行读写,那么方法返回的状态等于Environment.MEDIA_MOUNTED

69、im卡的EF 文件有何作用

SIM卡的文件系统有自己规范,主要是为了和手机通讯,SIM卡本身可以有自己的操作系统,EF就是作存储并和手机通讯用的
70、  Linux中跨进程通信的几种方式

71、谈对Android NDK的理解。

Android NDK是一套工具,允许Android应用开发者嵌入从C、C++源代码文件编译来的本地机器代码到各自的应用软件包中。
72、 谈谈Android的优点和不足之处

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

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

一般只是希望在View发生改变时对UI进行重绘。你只需在Activity中显式地调用View对象中的invalidate()方法即可。系统会自动调用 View的onDraw()方法
75、  简单描述下Android 数字签名。
76、  什么是ANR 如何避免它

答:ANR:Application Not Responding。在Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应,当用户操作的在5s内应用程序没能做出反应,BroadcastReceiver在10秒内没有执行完毕,就会出现应用程序无响应对话框,这既是ANR。 避免方法:Activity应该在它的关键生命周期方法(如onCreate()和onResume())里尽可能少的去做创建操作。潜在的耗时操作,例如网络或数据库操作,或者高耗时的计算如改变位图尺寸,应该在子线程里(或者异步方式)来完成。主线程应该为子线程提供一个Handler,以便完成时能够提交给主线程
在Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应。当出现下列情况时,Android就会显示ANR对话框了:     对输入事件(如按键、触摸屏事件)的响应超过5秒     意向接受器(intentReceiver)超过10秒钟仍未执行完毕     Android应用程序完全运行在一个独立的线程中(例如main)。这就意味着,任何在主线程中运行的,需要消耗大量时间的操作都会引发ANR。因为此时,你的应用程序已经没有机会去响应输入事件和意向广播(Intent broadcast)。     因此,任何运行在主线程中的方法,都要尽可能的只做少量的工作。特别是活动生命周期中的重要方法如onCreate()和 onResume()等更应如此。潜在的比较耗时的操作,如访问网络和数据库;或者是开销很大的计算,比如改变位图的大小,需要在一个单独的子线程中完成(或者是使用异步请求,如数据库操作)。但这并不意味着你的主线程需要进入阻塞状态已等待子线程结束 -- 也不需要调用Therad.wait()或者Thread.sleep()方法。取而代之的是,主线程为子线程提供一个句柄(Handler),让子线程在即将结束的时候调用它(xing:可以参看Snake的例子,这种方法与以前我们所接触的有所不同)。使用这种方法涉及你的应用程序,能够保证你的程序对输入保持良好的响应,从而避免因为输入事件超过5秒钟不被处理而产生的ANR。这种实践需要应用到所有显示用户界面的线程,因为他们都面临着同样的超时问题
77、handler机制的原理

Andriod提供了Handler和Looper来满足线程间的通信.Handler先进先出原则.Looper类用来管理特定线程内对象之间的消息交换(Message Exchange).  
1)Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的Message Queue(消息队列).  
2)Handler:你可以构造Handler对象来与Looper沟通,以便push新消息到Message Queue里;或者接收Looper从Message Queue取出)所送来的消息.   
android中线程与线程,进程与进程之间如何通信。 线程通信使用Handler,
78、 android中有哪几种解析xml的类,官方推荐哪种?以及它们的原理和区别

DOM优点:
1. XML树在内存中完整存储,因此可以直接修改其数据和结构。
2.可以通过该解析器随时访问XML树中的任何一个节点。
3.DOM解析器的API在使用上也相对比较简单。 缺点: 如果XML文档体积比较大时,将文档读入内存是非常消耗系统资源的。 使用场景: DOM 是用与平台和语言无关的方式表示 XML 文档的官方 W3C 标准。DOM 是以层次结构组织的节点的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能进行任何工作。DOM是基于对象层次结构的。
SAX解析 优点:
SAX 对内存的要求比较低,因为它让开发人员自己来决定所要处理的标签。特别是当开发人员只需要处理文档中所包含的部分数据时,SAX 这种扩展能力得到了更好的体现。 缺点: 用SAX方式进行XML解析时,需要顺序执行,所以很难访问到同一文档中的不同数据。此外,在基于该方式的解析编码过程也相对复杂。 使用场景: 对于含有数据量十分巨大,而又不用对文档的所有数据进行遍历或者分析的时候,使用该方法十分有效。该方法不用将整个文档读入内存,而只需读取到程序所需的文档标签处即可
79、NotifactionManager使用原理

1. 通过getSystemService方法获得一个NotificationManager对象。   2. 创建一个Notification对象。每一个Notification对应一个Notification对象。在这一步需要设置显示在屏幕上方状态栏的通知消息、通知消息前方的图像资源ID和发出通知的时间。一般为当前时间。   3. 由于Notification可以与应用程序脱离。也就是说,即使应用程序被关闭,Notification仍然会显示在状态栏 中。当应用程序再次启动后,又可以重新控制这些Notification。如清除或替换它们。因此,需要创建一个PendingIntent对象。该对象由Android系统负责维护,因此,在应用程序关闭后,该对象仍然不会被释放。   4. 使用Notification类的setLatestEventInfo方法设置Notification的详细信息。   5. 使用NotificationManager类的notify方法显示Notification消息。在这一步需要指定标识Notification的唯一ID。这个ID必须相对于同一个NotificationManager对象是唯一的,否则就会覆盖相同ID的Notificaiton
80、 activityy的启动模式有哪些?是什么含义?

   答:在android里,有4种activity的启动模式,分别为:
  “standard” (默认) 
“singleTop” 
“singleTask” 
“singleInstance”
它们主要有如下不同:
1. 如何决定所属task  “standard”和”singleTop”的activity的目标task,和收到的Intent的发送者在同一个task内,除非intent包括参数FLAG_ACTIVITY_NEW_TASK。  如果提供了FLAG_ACTIVITY_NEW_TASK参数,会启动到别的task里。  “singleTask”和”singleInstance”总是把activity作为一个task的根元素,他们不会被启动到一个其他task里。
2. 是否允许多个实例  “standard”和”singleTop”可以被实例化多次,并且存在于不同的task中,且一个task可以包括一个activity的多个实例;  “singleTask”和”singleInstance”则限制只生成一个实例,并且是task的根元素。 singleTop要求如果创建intent的时候栈顶已经有要创建 的Activity的实例,则将intent发送给该实例,而不发送给新的实例。
3. 是否允许其它activity存在于本task内  “singleInstance”独占一个task,其它activity不能存在那个task里;如果它启动了一个新的activity,不管新的activity的launch mode 如何,新的activity都将会到别的task里运行(如同加了FLAG_ACTIVITY_NEW_TASK参数)。  而另外三种模式,则可以和其它activity共存。
4. 是否每次都生成新实例  “standard”对于没一个启动Intent都会生成一个activity的新实例;  “singleTop”的activity如果在task的栈顶的话,则不生成新的该activity的实例,直接使用栈顶的实例,否则,生成该activity的实例。  比如现在task栈元素为A-B-C-D(D在栈顶),这时候给D发一个启动intent,如果D是 “standard”的,则生成D的一个新实例,栈变为A-B-C-D-D。  如果D是singleTop的话,则不会生产D的新实例,栈状态仍为A-B-C-D  如果这时候给B发Intent的话,不管B的launchmode是”standard” 还是 “singleTop” ,都会生成B的新实例,栈状态变为A-B-C-D-B。 “singleInstance”是其所在栈的唯一activity,它会每次都被重用。 “singleTask”如果在栈顶,则接受intent,否则,该intent会被丢弃,但是该task仍会回到前台。 当已经存在的activity实例处理新的intent时候,会调用onNewIntent()方法 如果收到intent生成一个activity实例,那么用户可以通过back键回到上一个状态;如果是已经存在的一个activity来处理这个intent的话,用户不能通过按back键返回到这之前的状态
81、 什么情况会导致Force Close ?如何避免如何避免如何避免如何避免?能否捕获导致其的异常

    答:程序出现异常,比如nullpointer。 避免:编写程序时逻辑连贯,思维缜密。能捕获异常,在logcat中能看到异常信息
82、请介绍下ContentProvider是如何实现数据共享的?

    一个程序可以通过实现一个Content provider的抽象接口将自己的数据完全暴露出去,而且Content providers是以类似数据库中表的方式将数据暴露。Content providers存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方法。 要想使应用程序的数据公开化,可通过2种方法:创建一个属于你自己的Content provider或者将你的数据添加到一个已经存在的Content provider中,前提是有相同数据类型并且有写入Content provider的权限。 如何通过一套标准及统一的接口获取其他应用程序暴露的数据?  Android提供了ContentResolver,外界的程序可以通过ContentResolver接口访问ContentProvider提供的数据
83、Thread 和service的区别

答:servie是系统的组件,它由系统进程托管(servicemanager);它们之间的通信类似于client和server,是一种轻量级的ipc通信,这种通信的载体是binder,它是在linux层交换信息的一种ipc。而thread是由本应用程序托管。 1). Thread:Thread 是程序执行的最小单元,它是分配CPU的基本单位。可以用 Thread 来执行一些异步的操作。 2). Service:Service 是android的一种机制,当它运行的时候如果是Local Service,那么对应的 Service 是运行在主进程的 main 线程上的。如:onCreate,onStart 这些函数在被系统调用的时候都是在主进程的 main 线程上运行的。如果是Remote Service,那么对应的 Service 则是运行在独立进程的 main 线程上。 既然这样,那么我们为什么要用 Service 呢?其实这跟 android 的系统机制有关,我们先拿 Thread 来说。Thread 的运行是独立于 Activity 的,也就是说当一个 Activity 被 finish 之后,如果你没有主动停止 Thread 或者 Thread 里的 run 方法没有执行完毕的话,Thread 也会一直执行。因此这里会出现一个问题:当 Activity 被 finish 之后,你不再持有该 Thread 的引用。另一方面,你没有办法在不同的 Activity 中对同一 Thread 进行控制。   举个例子:如果你的 Thread 需要不停地隔一段时间就要连接服务器做某种同步的话,该 Thread 需要在 Activity 没有start的时候也在运行。这个时候当你 start 一个 Activity 就没有办法在该 Activity 里面控制之前创建的 Thread。因此你便需要创建并启动一个 Service ,在 Service 里面创建、运行并控制该 Thread,这样便解决了该问题(因为任何 Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例)。   因此你可以把 Service 想象成一种消息服务,而你可以在任何有 Context 的地方调用 Context.startService、Context.stopService、Context.bindService,Context.unbindService,来控制它,你也可以在 Service 里注册 BroadcastReceiver,在其他地方通过发送 broadcast 来控制它,当然这些都是 Thread 做不到的
84、Android本身api并未声明会抛出异常,那么它在运行时有无可能会抛出runtime 异常

比如nullpointerException。我遇到过,比如textview.setText()时,textview没有初始化。会导致程序无法正常运行出现forceclose。打开控制台查看logcat信息找出异常信息并修改程序
85、IntentService有何优点?

答:Acitivity的进程,当处理Intent的时候,会产生一个对应的Service; Android的进程处理器现在会尽可能的不kill掉你;非常容易使用

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

  答:全称是:Android Interface Define Language 在Android中, 每个应用程序都可以有自己的进程. 在写UI应用的时候, 经常要用到Service. 在不同的进程中, 怎样传递对象呢?显然, Java中不允许跨进程内存共享. 因此传递对象, 只能把对象拆分成操作系统能理解的简单形式, 以达到跨界对象访问的目的. 在J2EE中,采用RMI的方式, 可以通过序列化传递对象. 在Android中, 则采用AIDL的方式. 理论上AIDL可以传递Bundle,实际上做起来却比较麻烦。 AIDL(AndRoid接口描述语言)是一种借口描述语言; 编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要在一个Activity中, 访问另一个Service中的某个对象, 需要先将对象转化成AIDL可识别的参数(可能是多个参数), 然后使用AIDL来传递这些参数, 在消息的接收端, 使用这些参数组装成自己需要的对象. AIDL的IPC的机制和COM或CORBA类似, 是基于接口的,但它是轻量级的。它使用代理类在客户端和实现层间传递值. 如果要使用AIDL, 需要完成2件事情: 1. 引入AIDL的相关类.; 2. 调用aidl产生的class. AIDL的创建方法: AIDL语法很简单,可以用来声明一个带一个或多个方法的接口,也可以传递参数和返回值。 由于远程调用的需要, 这些参数和返回值并不是任何类型.下面是些AIDL支持的数据类型: 1. 不需要import声明的简单Java编程语言类型(int,boolean等) 2. String, CharSequence不需要特殊声明 3. List, Map和Parcelables类型, 这些类型内所包含的数据成员也只能是简单数据类型, String等其他比支持的类型.


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

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

88、Android引入广播机制的用意?

答:a:从MVC的角度考虑(应用程序内)    其实回答这个问题的时候还可以这样问,android为什么要有那4大组件,现在的移动开发模型基本上也是照搬的web那一套MVC架构,只不过是改了点嫁妆而已。android的四大组件本质上就是为了实现移动或者说嵌入式设备上的MVC架构,它们之间有时候是一种相互依存的关系,有时候又是一种补充关系,引入广播机制可以方便几大组件的信息和数据交互。     b:程序间互通消息(例如在自己的应用程序内监听系统来电)     c:效率上(参考UDP的广播协议在局域网的方便性)     d:设计模式上(反转控制的一种应用,类似监听者模式)
89、1. Intent的几种有关的启动的方式有哪些

Intent的一些标记有FLAG_ACTIVITY_BROUGHT_TO_FRONT 、FLAG_ACTIVITY_CLEAR_TOP、FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET、FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS、FLAG_ACTIVITY_MULTIPLE_TASK和FLAG_ACTIVITY_NEW_TASK 等。每种含义大家看SDK文档和具体跑下这样你的记忆会更深刻些
90、通过Intent传递一些二进制数据的方法有哪些

1). 使用Serializable接口实现序列化,这是Java常用的方法。  
2). 实现Parcelable接口,这里Android的部分类比如Bitmap类就已经实现了,同时Parcelable在Android AIDL中交换数据也很常见的
91、 能说下Android应用的入口点吗? 

  真正的Android入口点是application的main,你可以看下androidmanifest.xml的包含关系就清楚了。 可以没有Activity但是必须有Application
92、  SQLite支持事务吗 添加删除如何提高性能?  

SQLite作为轻量级的数据库,比MySQL还小,但支持SQL语句查询,提高性能可以考虑通过原始经过优化的SQL查询语句方式处理
93、你用过哪款Android手机,有哪些优点和不足,相对于iPhone或Symbian又有哪哪些优缺点?

94、 隐式显式Intent的区别 —  

显式意图  通过名字指明目标组件(这个组件名字字段component name field, 前面提到过, 有一个数值集)。既然组件名称通常不为其他应用程序的开发者所了解,显式意图典型的被用作应用程序的内部消息-例如一个活动启动一个附属服务或姊妹活动。    隐式意图  不命名目标组件(组件名称字段为空)。隐式意图经常用来激活其他应用程序的组件
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics