Android面试题大全精心整理

更新时间:2023-05-24 12:41:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

1. 什么是Activity?

通俗的讲,Activity就是一个应用程序的门面,也可以理解成就是WEB程序中一个页面,当然与web程序中的页面不同的是,web中的一个页面可能只是一个纯粹的展示页面不与用户进行任何交互,而几乎所有的Activity都会与用户交互。当然两者在架构上也有本质区别,Activity与用户的交互通过触发UI的不同事件完成的。而Web程序是通过请求,响应来完成交互的。还有在android中颠覆了很多常规想法,比如在一个Activity中可以打开另一个不在同一应用的Activity。这在其他程序是不可想象的。当然这种设计的出发点也是为了节省系统资源。从View层的角度来看,Activity承载了与用户交互的不同控件。从控制层看,也就是内部逻辑,Activity需要保持各个界面的状态,背后会做很多持久化的操作。包括妥善管理生命周期的各个阶段。

2. 请描述一下Activity生命周期。

创建 onCreate - 启动onStart – 开始 onResume – 暂停 onPause – 结束 onStop – 销毁onDestroy

在一个Activity正常启动的过程中,他们被调用的顺序是 onCreate -> onStart -> onResume, 在Activity被干掉的时候顺序是onPause -> onStop -> onDestroy ,这样就是一个完整的生命周期,但是有人问了,程序正运行着呢来电话了,这个程序咋办?中止了呗,如果中止的时候新出的一个Activity是全屏的那么:onPause->onStop ,恢复的时候onStart->onResume ,如果打断这个应用程序的是一个Theme为Translucent 或者Dialog 的Activity那么只是onPause ,恢复的时候onResume 。

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

startActivity(Intent intent) ;

startActivityForResult (Intent intent, int requestCode) ;

onActivityResult (int requestCode, int resultCode, Intent data);

setResult(int resultCode);

4. 横竖屏切换时候Activity的生命周期。

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

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

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

5. 全屏的 Activity // 设置全屏模式

getWindow().setFlags(youtParams.FLAG_FULLSCREEN,

youtParams.FLAG_FULLSCREEN);

// 去除标题栏

requestWindowFeature(Window.FEATURE_NO_TITLE);

6. 如何将一个Activity设置成窗口的样式。 Activity属性设定:有时候会做个应用程序是漂浮在手机主界面的。这个只需要在设置下Activity的主题theme,即在Manifest.xml定义Activity的地方加一句:

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

如果是作半透明的效果:

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

7. Activity 中的对象的生命周期大于Activity?

调试方法: DDMS----> HEAPSIZE --->dataobject ---> [Total Size]

8. 你后台的Activity被系统回收怎么办?

被回收的Activity就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上参数 savedInstanceState,没被收回的就还是onResume就好了。

9. 如何退出Activity?如何安全退出已调用多个Activity的Application?

1、抛异常强制退出:

该方法通过抛异常,使程序Force Close。

验证可以,但是,需要解决的问题是,如何使程序结束掉,而不弹出Force Close的窗口。

2、记录打开的Activity:

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

3、发送特定广播:

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

4、递归退出

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

10. 如果后台的Activity由于某原因被系统回收了,如何在被系统回收之前保存当前状态? android 系统会记录下回收前Activity 的状态,再次调用被回收的Activity 就要重新调用onCreate(),不同于直接启动的是这回onCreate()里包括参数savedInstanceState。

使用 savedInstanceState 可以恢复到回收前的状态。

11. 两个Activity之间怎么传递数据?

通过Intent来传递数据

12. 怎么让在启动一个Activity时就启动一个service? 在activity的onCreate里面进行连接并bindservice或者直接startService。

(服务里启动Activity

Intent intent = new Intent();

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

intent.setClass(getApplicationContext(),FileBrowserActivity.class);

startActivity(intent);)

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

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

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

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

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

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

当需要创建在后台运行的程序的时候,就要使用到Service .

17. Service有哪些启动方法,有什么区别,怎样停用Service? startService

Service会经历 onCreate 到onStart,然后处于运行状态,stopService的时候调用onDestroy方法。

bindService

Service会运行onCreate,然后是调用onBind,这个时候调用者和Service绑定在一起。调用者退出了,Srevice就会调用onUnbind->onDestroyed方法。

所谓绑定在一起就共存亡了。调用者也可以通过调用unbindService方法来停止服务,这时候Srevice就会调用onUnbind->onDestroyed方法。

如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行

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

19. View如何刷新?

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

20. 什么是IntentService?有何优点?

IntentService是一个通过Context.startService(Intent)启动可以处理异步请求的Service,使用时你只需要继承IntentService和重写其中的onHandleIntent(Intent)方法接收一个Intent对象,在适当的时候会停止自己(一般在工作完成的时候). 所有的请求的处理都在一个工作线程中完成,它们会交替执行(但不会阻塞主线程的执行),一次只能执行一个请求。

优点:IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker

thread(线程)来处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的worker thread中处理,不会阻塞应用程序的主线程,这里就给我们提供了一个思路,如果有耗时的操作与其在Service里面开启新线程还不如使用IntentService来处理耗时操作。

21. 请描述一下Intent 和 Intent Filter。 Intent 在Android 中被翻译为"意图",也就是目的,它们是应用程序四种基本组件

——————activity,service和broadcast receiver 之间互相激活的手段。在调用Intent 名称时使用结构全名时为显示调用。这种方式一般用于应用程序的内部调用,因为你不一定会知道别人写的类的全名。关于隐式Intent 的用法,这里有配置Activity 的Intent Filter 在调用的时候指定Intent 的action,系统就会自动的去对比是哪个 intent-filter 符合相应的Activity,找到后就会启动Activity.

一个intent filter 是 IntentFilter 类的实例,但是它一般不出现在代码中,而是出现在

androidManifest.xml文件中,以的形式(有一个例外是broadcast receiver 的intent filter 是使用Context.registerReceiver() 来动态设定的,其intent filter 也是在代码中创建的。) 一个filter 有action,data,category等字段.一个隐式intent 为了能被某个intent filter 接受,必须通过3个测试,一个intent 为了被某个组件接受,则必须通过它所有的intent filter 中的一个。

22. Intent传递数据时,可以传递哪些类型数据?

Serializable、Charsequence、Parcelable、Bundle

23. 说说Activity,Intent,Service是什么关系。

一个 Activity 通常是一个单独的屏幕,每一个Activity 都被实现为一个单独的类,这些类都是从Activity 基类中继承来的,Activity 类会显示由视图控件组成的用户接口,并对视图控件的事件做出响应。

Intent 的调用是用业进行架构屏幕之间的切换的,Intent 是描述应用想要做什么。Intent 数据结构中两个最重要的部分是动作和动作对应的数据,一个动作对应一个动作数据。 Android Service 是运行在后台的代码,不能与用户交互,可以运行在自己的进程,也可以运行在其他应用程序进程的上下文里。需要通过某一个Activity 或者其他 Context 对象来调用.

Activity 跳转到 Activity ,Activity 启动Service ,Service 打开Activity都需要Intent 表时跳转的意图,以及传递参灵敏,Intent 是这些组件间信号传递的承载者。

24. 请描述一下Broadcast Receiver。

广播接收器没有用户界面。然而,它们可以启动一个activity或serice 来响应它们收到的信息,或者用NotificationManager 来通知用户。分为两种一种是普通广播还有一种是有序广播。普通广播,通过Context.sendBroadcast(Intent myIntent)发送的

有序广播,通过Context.sendOrderedBroadcast(intent, receiverPermission)发送的,该方法第2个参数决定该广播的级别,级别数值是在 -1000 到 1000 之间 , 值越大 , 发送的优先级越高;

25. 在manifest和代码中如何注册和使用 broadcast receiver 。

<receiver android:name="NewBroad">

<intent-filter>

<action android:name="android.provider.action.NewBroad"/>

<action>

</intent-filter>

</receiver>

26. 动态绑定broadcast receiver。

动态注册,一般在Activity可交互时onResume()内注册BroadcastReceiver

IntentFilter intentFilter=new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); registerReceiver(mBatteryInfoReceiver ,intentFilter);

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

ContentResolver接口访问ContentProvider提供的数据。

28. 请介绍下Android的数据存储方式。

Sharedpreference、文件、SQLite、Contentprovider、网络

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

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

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

LinearLayout、FrameLayout、RelativeLayout、AbsoluteLayout、TableLayout

31. 谈谈UI中, Padding和Margin有什么区别?

32. 描述一下android的系统架构 android系统架构分从下往上为Linux内核层、运行库、应用程序框架层和应用程序层。 Linux内核层:负责硬件的驱动程序、网络、电源、系统安全以及内存管理等功能。 运行库和androidruntion:运行库:即c/c++函数库部分,大多数都是开放源代码的函数库,例如webkit,该函数库负责android网页浏览器的运行;例如标准的c函数库libc、openssl、sqlite等,当然也包括支持游戏开发的2dsgl和3dopengles,在多媒体方面有mediaframework框架来支持各种影音和图形文件的播放与显示,如mpeg4、h.264、mp3、aac、amr、jpg和png等众多的多媒体文件格式。Androidruntion负责解释和执行生成的dalvik格式的字节码

应用软件架构:java应用程序开发人员主要是使用该层封装好的api进行快速开发的。

应用程序层:该层是java的应用程序层,android内置的googlemaps、email、IM、浏览器等,都处于该层,java开发人员工发的程序也处于该层,而且和内置的应用程序具有平等的地位,可以调用内置的应用程序,也可以替换内置的应用程序

33. 说明onSaveInstanceState() 和 onRestoreInstanceState()在什么时候被调用 Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它们不同于 onCreate()、onPause()等生命周期方法,它们并不一定会被触发。当应用遇到意外情况(如:内存不足、用户直接按Home键)由系统销毁一个Activity时,

onSaveInstanceState()才会被调用。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。

另外,当屏幕的方向发生了改变, Activity会被摧毁并且被重新创建,如果你想在Activity被摧毁前缓存一些数据,并且在Activity被重新创建后恢复缓存的数据。可以重写Activity的 onSaveInstanceState() 和 onRestoreInstanceState()方法。

34. android的broadcast的生命周期

1)Broadcast receiver生命周期中仅有一个回调方法:

void onReceive(Context curContext, Intent broadcastMsg)

当接收器接收到一条broadcast消息,Android就会调用onReceiver(),并传递给它一个Intent对象,这个对象携带着那条broadcast消息。我们认为仅当执行这个方式时,Broadcast receiver是活动的;这个方法返回时,它就终止了。这就是Broadcast receiver的生命周期。

2)由于Broadcast receiver的生命周期很短,一个带有活动的Broadcast receiver的进程是受保护的,以避免被干掉;但是别忘了有一点,Android会在任意时刻干掉那些携带不再活动的组件的进程,所以很可能会造成这个问题。

3)解决上述问题的方案采用一个Service来完成这项工作,Android会认为那个进程中(Service所在的进程)仍然有在活动的组件.

35. res目录有默认几项resource ?

5项, drawable-hdpi,drawable-ldpi,drawable-mdpi,layout,values

36. android 中有哪几种解析xml 的类,它们的原理和区别 ?

DOM 解析

优点:

1. XML 树在内存中完整理存储,因此可以直接修改其数据和结构。

2. 可以通过该解析器随时访问XML树中的任何一个节点.

3. DOM 解析器的 API 在使用上也相对比较简单

缺点: 如果XML 文档体积比较大时,将文档读入内存是非常消耗系统资源的。

使用场景:

DOM 是用与平台和语言无关的方式表示 XML 文档的官方 W3C标准.DOM 是以层次结构组织的节点的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能进行工作.DOM 是基于对象层次结构的。

SAX解析

优点: SAX 对内存的要求比较低,因为它让开发人员自己来决定所要处理的标签。特别是当开发人员只需要处理文档中所包含的部分数据时,SAX 这种扩展能力得到了更好的体现。

缺点: 用SAX 方式进行XML解析时,需要顺序执行,所以很难访问到同一文档中的不同数据。此外,在基于该方式的解析编码过程也相对复杂。

使用场景: 对于含有数据量十分巨大,而又不用对文档的所有数据进行遍历或者分析的时候,使用该方法十分有效。该方法不用将整个文档读入内存,而只需读取到程序所需的文档标签即可.

Xmlpull 解析

android 提供了xmlpull api ,xmlpull 和sax 类似,是基于流(stream) 操作文件,然后根据节点事件回调开发者编写的处理程序。因为是基于流的处理,因此xmlpull 和 sax 都比较节约内存资源,不会象DOM 那样要把所有节点以对象树的形式展现在内存中。 xmlpull 比sax 更简明,而且不需要扫描完整个流.

37. widget相对位置的完成在antivity的哪个生命周期阶段实现。

38. 谈谈Android的IPC机制

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

39. 请解释下在单线程模型中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对象。

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

AIDL 是一种接口定义语言,用于约束两个进程间的通信规则,供编译器生成代码,实现Android 设备上的进程间通信。

进程之间的通信信息首先会被转换成AIDL 协议消息,然后发送给对方,对方受到 AIDL 协议消息后再转换成相应的对象。

AIDL 支持的类型包括Java 原生类型和String,List,Map,CharSequence,如果使用自定义类型,必须实现Parcelable 接口

41. 请解释下Android程序运行时权限与文件系统权限的区别。

要区分apk运行时的拥有的权限与在文件系统上被访问(读写执行)的权限两个概念。apk程序是运行在虚拟机上的,对应的是Android独特的权限机制,只有体现到文件系统上时才使用linux的权限设置。

(一)linux文件系统上的权限

-rwxr-x--x system system 4156 2010-04-30 16:13 test.apk

代表的是相应的用户/用户组及其他人对此文件的访问权限,与此文件运行起来具有的权限完全不相关。比如上面的例子只能说明system用户拥有对此文件的读写执行权限;system组的用户对此文件拥有读、执行权限;其他人对此文件只具有执行权限。而test.apk运行起来后可以干哪些事情,跟这个就不相关了。千万不要看apk文件系统上属于

system/system用户及用户组,或者root/root用户及用户组,就认为apk具有system或root权限

(二)Android的权限规则

(1)Android中的apk必须签名

这种签名不是基于权威证书的,不会决定某个应用允不允许安装,而是一种自签名证书。重要的是,android系统有的权限是基于签名的。比如:system等级的权限有专门对应的签名,签名不对,权限也就获取不到。默认生成的APK文件是debug签名的。获取system权限时用到的签名,

(2)基于UserID的进程级别的安全机制

大家都知道,进程有独立的地址空间,进程与进程间默认是不能互相访问的,是一种很可靠的保护机制。Android通过为每一个安装在设备上的包(apk)分配唯一的linux userID来实现,名称为"app_"加一个数字,比如app_43不同的UserID,运行在不同的进程,所以apk之间默认便不能相互访问。Android提供了如下的一种机制,可以使两个apk打破前面讲的这种壁垒。在AndroidManifest.xml中利用sharedUserId属性给不同的package分配相同的userID,通过这样做,两个package可以被当做同一个程序,系统会分配给两个程序相同的UserID。当然,基于安全考虑,两个package需要有相同的签名,否则没有验证也就没有意义了。(这里补充一点:并不是说分配了同样的UserID,两程序就运行在同一进程, 下面为PS指令摘取的,显然,system、app_2分别对应的两个进程的PID都不同,不知Android到底是怎样实现它的机制的)

User PID PPID

system 953 883 187340 55052 ffffffff afe0cbcc S system_server

app_2 1072 883 100264 19564 ffffffff afe0dcc4 S com.android.inputmethod.

system 1083 883 111808 23192 ffffffff afe0dcc4 S android.process.omsservi

app_2 1088 883 156464 45720 ffffffff afe0dcc4 S android.process.acore (3)默认apk生成的数据对外是不可见的

实现方法是:Android会为程序存储的数据分配该程序的UserID。借助于Linux严格的文件系统访问权限,便实现了apk之间不能相互访问似有数据的机制。

例:我的应用创建的一个文件,默认权限如下,可以看到只有UserID为app_21的程序才能读写该文件。

-rw------- app_21 app_21 87650 2000-01-01 09:48 test.txt

如何对外开放?

<1>使用MODE_WORLD_READABLE and/or MODE_WORLD_WRITEABLE 标记。 When creating a new file with getSharedPreferences(String, int), openFileOutput(String, int), or openOrCreateDatabase(String, int, SQLiteDatabase.CursorFactory), you can use the

MODE_WORLD_READABLE and/or MODE_WORLD_WRITEABLE flags to allow any other package to read/write the file. When setting these flags, the file is still owned by your application, but its global read and/or write permissions have been set appropriately so any other application can see it.

(4)AndroidManifest.xml中的显式权限声明

Android默认应用是没有任何权限去操作其他应用或系统相关特性的,应用在进行某些操作时都需要显式地去申请相应的权限。

一般以下动作时都需要申请相应的权限:

A particular permission may be enforced at a number of places during your program's operation:

At the time of a call into the system, to prevent an application from executing certain functions. When starting an activity, to prevent applications from launching activities of other applications. Both sending and receiving broadcasts, to control who can receive your broadcast or who

can send a broadcast to you.

When accessing and operating on a content provider. Binding or starting a service. 在应用安装的时候,package installer会检测该应用请求的权限,根据该应用的签名或者提示用户来分配相应的权限。在程序运行期间是不检测权限的。如果安装时权限获取失败,那执行就会出错,不会提示用户权限不够。大多数情况下,权限不足导致的失败会引发一个 SecurityException,会在系统log(system log)中有相关记录。

(5)权限继承/UserID继承

当我们遇到apk权限不足时,我们有时会考虑写一个linux程序,然后由apk调用它去完成某个它没有权限完成的事情,很遗憾,这种方法是行不通的。前面讲过,android权限是经营在进程层面的,也就是说一个apk应用启动的子进程的权限不可能超越其父进程的权限(即apk的权限),即使单独运行某个应用有权限做某事,但如果它是由一个apk调用的,那权限就会被限制。实际上,android是通过给子进程分配父进程的UserID实现这一机制的。

(三)常见权限不足问题分析

首先要知道,普通apk程序是运行在非root、非system层级的,也就是说看要访问的文件的权限时,看的是最后三位。另外,通过system/app安装的apk的权限一般比直接安装或adb install安装的apk的权限要高一些。

言归正传,运行一个android应用程序过程中遇到权限不足,一般分为两种情况:

(1)Log中可明显看到权限不足的提示。

此种情况一般是AndroidManifest.xml中缺少相应的权限设置,好好查找一番权限列表,应该就可解决,是最易处理的情况。有时权限都加上了,但还是报权限不足,是什么情况呢?Android系统有一些API及权限是需要apk具有一定的等级才能运行的。比如

SystemClock.setCurrentTimeMillis()修改系统时间,WRITE_SECURE_SETTINGS权限好像都是需要有system级的权限才行。也就是说UserID是system。

(2)Log里没有报权限不足,而是一些其他Exception的提示,这也有可能是权限不足造成的。比如:我们常会想读/写一个配置文件或其他一些不是自己创建的文件,常会报

java.io.FileNotFoundException错误。系统认为比较重要的文件一般权限设置的也会比较严格,特别是一些很重要的(配置)文件或目录。如

-r--r----- bluetooth bluetooth 935 2010-07-09 20:21 dbus.conf

drwxrwx--x system system 2010-07-07 02:05 data

dbus.conf好像是蓝牙的配置文件,从权限上来看,根本就不可能改动,非bluetooth用户连读的权利都没有。/data目录下存的是所有程序的私有数据,默认情况下android是不允许普通apk访问/data目录下内容的,通过data目录的权限设置可知,其他用户没有读的权限。所以adb普通权限下在data目录下敲ls命令,会得到opendir failed, Permission denied的错误,通过代码file.listfiles()也无法获得data目录下的内容。

上面两种情况,一般都需要提升apk的权限,目前我所知的apk能提升到的权限就是system(具体方法见:如何使Android应用程序获取系统权限),

42. 系统上安装了多种浏览器,能否指定某浏览器访问指定页面?

答案当然是:肯定的。

具体方法如下:

Intent intent = new Intent();

intent.setAction("android.intent.action.VIEW");

Uri content_uri_browsers = Uri.parse("");

intent.setData(content_uri_browsers);

intent.setClassName("com.android.browser", "com.android.browser.BrowserActivity"); startActivity(intent);

43. 对多线程的运用和理解,及多线程之间handle的传值。

44. 对android虚拟机的理解,包括内存管理机制垃圾回收机制。

45. Framework工作方式及原理,Activity是如何生成一个view的,机制是什么。

46. android本身的一些限制,比如apk包大小限制,读取大文件时的时间限。

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

48. ListView如何提高其效率?

49. 启动应用后,改变系统语言,应用的语言会改变么?

50. 启动一个程序,可以主界面点击图标进入,也可以从一个程序中跳转过去,二者有什么区

别?

51. Android程序与JavaME程序的区别?

一.区别: 1.Android是一个完整的移动设备操作系统,由linux操作系统,中间件,C类库和核心应用程序组成。 2.java Me是java的一个微型版本,针对移动设备开发应用程序的开发包,它必须有底层操作系统支持。

二.联系: 1.可以说其实它们是没什么关系。 2.非要找关系的话就是:都是用java语言编写应用程序。

三.各自的优势: 1.Android的优势在于开发性和开源,是一个优秀的移动设备操作系统。

2.Java Me 是一个移动设备软件开发包,跨平台是其主要特点。不少学生对这个很感兴趣,还有一些疑问,特进一步说明: 其实它们真是没什么关系,只是编写应用的话都是Java语法。Android本身是个手机操作系统,它有多层结构组成,其中应用层是用Java语言开发的,语法当然一样,不过Android有自己的API,可喜的是有不少API android直接使用的就是Java API,只是运行环境不一样了。JavaME是Java的一个版本,跨平台和JavaSE的原理是一样的,它的运行需要JRE,操作系统支持的。比如你在NOKIA使用JavaME开发不仅需要虚拟机还需要它的操作系统支持。最少应该清楚一点:Android应用程序不能在JavaME环境下运行,JavaME程序也不能直接在Android里运行,因为它们都有自己的API。

52. Android中Task任务栈的分配。

53. 在Android中,怎么节省内存的使用,怎么主动回收内存?

54. 不同工程中的方法是否可以相互调用?

55. 在Android中是如何实现判断区分通话记录中的电话状态,去电,来电、未接来电?

56. dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念

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

57. sim卡的EF 文件有何作用

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

58. 如何判断是否有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(Enviroment.MEDIA_MOUNTED)

Environment.getExternalStorageState() 方法用于获取SDCard 的状态,如果手机装有SDCard,并且可以进行读写,那么方法返回的状态等于Environment.MEDIA_MOUNTED。

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

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

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

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

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

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

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

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

63. 一条最长的短信息约占多少byte?

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

64. Linux中跨进程通信的几种方式。

65. 谈谈对Android NDK的理解。

NDK是一系列工具的集合

NDK提供了一系列的工具,帮助开发者迅速的开发C/C++的动态库,并能自动将so和java应用打成apk包

NDK集成了交叉编译器,并提供了相应的mk文件和隔离cpu,平台等的差异,开发人员只需简单的修改mk文件就可以创建出so

66. 谈谈Android的优点和不足之处。

67. Android系统中GC什么情况下会出现内存泄露呢?

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

2). 构造 adapter 时,没有使用缓存contentview

衍生listview 的优化问题----减少创建view 的对象,充分使用contentview,可以使用一静态类来优化处理 getView 的过程

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

68. Android UI中的View如何刷新。\

Android中对View的更新有很多种方式,使用时要区分不同的应用场合。我感觉最要紧的是分清:多线程和双缓冲的使用情况。

1).不使用多线程和双缓冲

这种情况最简单了,一般只是希望在View发生改变时对UI进行重绘。你只需在Activity中显式地调用View对象中的invalidate()方法即可。系统会自动调用 View的onDraw()方法。

2).使用多线程和不使用双缓冲

这种情况需要开启新的线程,新开的线程就不好访问View对象了。强行访问的话会报:android.view.ViewRoot$CalledFromWrongThreadException:Only the originalthread that created a view hierarchy can touch its views.

这时候你需要创建一个继承了android.os.Handler的子类,并重写handleMessage(Messagemsg)方法。android.os.Handler是能发送和处理消息的,你需要在Activity中发出更新UI的消息,然后再你的Handler(可以使用匿名内部类)中处理消息(因为匿名内部类可以访问父类变量,你可以直接调用View对象中的invalidate()方法)。也就是说:在新线程创建并发送一个Message,然后再主线程中捕获、处理该消息。

3).使用多线程和双缓冲

Android中SurfaceView是View的子类,她同时也实现了双缓冲。你可以定义一个她的子类并实现SurfaceHolder.Callback接口。由于实现SurfaceHolder.Callback接口,新线程就不需要android.os.Handler帮忙了。SurfaceHolder中lockCanvas()方法可以锁定画布,绘制玩新的图像后调用unlockCanvasAndPost(canvas)解锁(显示),还是比较方便得。

69. 简单描述下Android 数字签名。

70. 什么是ANR 如何避免它?

ANR : Application Not Responding ,五秒

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

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

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

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

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

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

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

72. handler机制的原理。

android提供了handler和looper来满足线程间的通信。Handler先进先出原则。looper用来管理特定线程内对象之间的消息交换(message Exchange).

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

2)handler:你可以构造一个handler对象来与looper沟通,以便push新消息到messagequeue里;或者接收looper(从messagequeue里取出)所送来的消息。

3)messagequeue:用来存放线程放入的消息。

4)线程:UI thread 通常就是main thread,而android启动程序时会为它建立一个message queue.

73. android中线程与线程,进程与进程之间如何通信。

74. 说说mvc模式的原理,它在android中的运用。 android的官方建议应用程序的开发采用mvc模式。何谓mvc?

mvc是model,view,controller的缩写,mvc包含三个部分:

l模型(model)对象:是应用程序的主体部分,所有的业务逻辑都应该写在该层。 2视图(view)对象:是应用程序中负责生成用户界面的部分。也是在整个mvc架构中用户唯一可以看到的一层,接收用户的输入,显示处理结果。

3控制器(control)对象:是根据用户的输入,控制用户界面数据显示及更新model对象状态的部分,控制器更重要的一种导航功能,想用用户出发的相关事件,交给m哦得了处理。

android鼓励弱耦合和组件的重用,在android中mvc的具体体现如下:

1)视图层(view):一般采用xml文件进行界面的描述,使用的时候可以非常方便的引入,当然,如何你对android了解的比较的多了话,就一定可以想到在android中也可以使用javascript+html等的方式作为view层,当然这里需要进行java和javascript之间的通信,幸运的是,android提供了它们之间非常方便的通信实现。

2)控制层(controller):android的控制层的重任通常落在了众多的acitvity的肩上,这句话也就暗含了不要在acitivity中写代码,要通过activity交割model业务逻辑层处理,这样做的另外一个原因是android中的acitivity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。

3)模型层(model):对数据库的操作、对网络等的操作都应该在model里面处理,当然对业务计算等操作也是必须放在的该层的。

75. android中有哪几种解析xml的类,官方推荐哪种?以及它们的原理和区别。

XML解析主要有三种方式,SAX、DOM、PULL。常规在PC上开发我们使用Dom相对轻松些,但一些性能敏感的数据库或手机上还是主要采用SAX方式,SAX读取是单向的,优点:不占内存空间、解析属性方便,但缺点就是对于套嵌多个分支来说处理不是很方便。而DOM方式会把整个XML文件加载到内存中去,这里Android开发网提醒大家该方法在查找方面可以和XPath很好的结合如果数据量不是很大推荐使用,而PULL常常用在J2ME对于节点处理比较好,类似SAX方式,同样很节省内存,在J2ME中我们经常使用的KXML库来解析。

76. DDMS与TraceView的区别?

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

77. android的哪个版本是一次重大的升级?

78. android有序广播和无序广播的区别?

BroadcastReceiver所对应的广播分两类:普通广播和有序广播。

普通广播:通过Context.sendBroadcast()方法来发送,它是完全异步的。

所有的receivers(接收器)的执行顺序不确定,因此所有的receivers(接收器)接收broadcast的顺序不确定。

这种方式效率更高,但是BroadcastReceiver无法使用setResult系列、getResult系列及abort(中止)系列API

有序广播:是通过Context.sendOrderedBroadcast来发送,所有的receiver依次执行。 BroadcastReceiver可以使用setResult系列函数来结果传给下一个BroadcastReceiver,通过getResult系列函数来取得上个BroadcastReceiver返回的结果,并可以abort系列函数来让系统丢弃该广播,使用该广播不再传送到别的BroadcastReceiver。

可以通过在intent-filter中设置android:priority属性来设置receiver的优先级,优先级相同的receiver其执行顺序不确定。

如果BroadcastReceiver是代码中注册的话,且其intent-filter拥有相同android:priority属性的话,先注册的将先收到广播。

有序广播,即从优先级别最高的广播接收器开始接收,接收完了如果没有丢弃,就下传给下一个次高优先级别的广播接收器进行处理,依次类推,直到最后。

这里接收短信的广播是有序广播,因此可以设置你自己的广播接收器的级别高于系统原来的级别,就可以拦截短信,并且不存收件箱,也不会有来信提示音。

实现方法是:

<receiver android:name=".SmsReceiver">

<intent-filter android:priority="100">

<action android:name="android.provider.Telephony.SMS_RECEIVED"/>

</intent-filter>

</receiver>

里面的android:priority="100"就是设定广播接收器的级别,这个值从1000~-1000,数值越大,优先级别就越高。

79. Android之Wifi学习 大致可以分为四个主要的类ScanResult,wifiConfiguration,WifiInfo,WifiManager

(1)ScanResult,主要是通过wifi 硬件的扫描来获取一些周边的wifi 热点的信息。

(2)wifiConfiguration 在我们连通一个wifi 接入点的时候,需要获取到的一些信息。大家可以跟我们有线的设备进行对比一下。

(3)WifiInfo 在我们的wifi 已经连通了以后,可以通过这个类获得一些已经连通的wifi 连接的信息获取当前链接的信息,这里信息就比较简单了,这里简单介绍一下这里的方法:

getBSSID() 获取BSSID getDetailedStateOf() 获取客户端的连通性 getHiddenSSID() 获得SSID 是否被隐藏 getIpAddress() 获取IP 地址

getLinkSpeed() 获得连接的速度

getMacAddress() 获得Mac 地址

getRssi() 获得802.11n 网络的信号

getSSID() 获得SSID

getSupplicanState() 返回具体客户端状态的信息

(4)wifiManager 这个不用说,就是用来管理我们的wifi 连接,这里已经定义好了一些类,可以供我们使用。这里来说相对复杂,里面的内容比较多,但是通过字面意思,我们还是可

以获得很多相关的信息。这个类里面预先定义了许多常量,我们可以直接使用,不用再次创建。

80. Android总Activity的启动模式分为四种? Activity启动模式设置:

<activity android:name=".MainActivity" android:launchMode="standard" />

Activity的四种启动模式:

. standard

模式启动模式,每次激活Activity时都会创建Activity,并放入任务栈中。

. singleTop

如果在任务的栈顶正好存在该Activity的实例,就重用该实例,否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例)。

. singleTask

如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的onNewIntent())。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移除栈。如果栈中不存在该实例,将会创建新的实例放入栈中。

. singleInstance

在一个新栈中创建该Activity实例,并让多个应用共享改栈中的该Activity实例。一旦改模式的Activity的实例存在于某个栈中,任何应用再激活改Activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用,不管谁激活该Activity都会进入同一个应用中。

81. android view,surfaceview,glsurfaceview的区别 SurfaceView是从View基类中派生出来的显示类,直接子类有GLSurfaceView和VideoView,可以看出GL和视频播放以及Camera摄像头一般均使用SurfaceView

SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。

那么在UI的主线程中更新画面可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。

当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步。比如你触屏了一下,你需要surfaceView中thread处理,一般就需要有一个event queue的设计来保存touch event,这会稍稍复杂一点,因为涉及到线程同步。

所以基于以上,根据游戏特点,一般分成两类。

1)被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是依赖于 onTouch 来更新,可以直接使用 invalidate。因为这种情况下,这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。

2)主动更新。比如一个人在一直跑动。这就需要一个单独的thread不停的重绘人的状态,避免阻塞main UI thread。所以显然view不合适,需要surfaceView来控制。

本文来源:https://www.bwwdw.com/article/4r24.html

Top