Android常见面试题(一)
总结了一些常见的Android面试题,内容会随着不断学习陆续添加。答案有误地方希望大家能够指正 ,同一时候希望大家一起补充总结很多其它常见问题。谢谢^_^
1. 简述Activity的生命周期
2. 请简单说下对广播接收者有哪些了解
3. view怎样刷新?简述什么是双缓冲?
4、AIDL的全称是什么?怎样工作?能处理哪些类型的数据?
5、java中怎样引用本地语言
6、谈谈Android的IPC(进程间通信)机制
7、NDK 是什么
8、怎样将SQLite数据库(xxx.db文件)与apk文件一起公布
1.简述Activity的生命周期
1、Activity可见并获得焦点
当Activity启动的时候。首先调用onCreate()、onStart(),onResume()方法,此时Activity对用户来说。是可见的状态
2、Activity可见但没获得焦点
当Activity从可见状态变为被Dialog遮挡的状态的时候,会调用onPause()方法,此时的Activity对用户可见,可是不能获得焦点
3、Activity不可见
当Activity从可见状态变为被其它的Activity全然覆盖或者是点击Home进入后台的时候,会依次调用onPause()//onStop()方法。假设在这个期间。系统内存不足,导致Activity被回收的话。还会调用onDestory()方法
4、Activity可见、没获得焦点状态 –> Activity可见、获得焦点状态
当Activity从被Dialog遮挡的状态恢复的时候。会调用onResume()方法,从而恢复能够点击的状态
5、Activity不可见、没获得焦点状态 –> Activity可见、获得焦点状态
当Activity从被其它Activity遮挡或者是进入后台状态后恢复,若没有被系统回收。会依次调用onRestart()、onStart()、onResume()方法。恢复到能够与用户进行交互的状态
6、Activity不可见状态–> Activity被回收 –> Activity可见、获得焦点状态
当Activity从被其它Activity遮挡或者进入后台,而且被系统回收的时候,此时恢复Activity,相当于又一次打开一个Activity。既调用onCreate()、onStart()//onResume()方法,从而恢复到可与用户进行交互的状态(期间可调用onRestoreInstanceState()。进行界面恢复)。
7、Activity可见、获得焦点状态 –> Activity可见、没获得焦点状态 或 不可见状态
在onPause()方法运行后,系统会停止一些消耗 CPU 的操作,由于这个时候程序的优先级减少。非常有可能被系统收回,所以我们应该在这种方法里做数据持久化处理。保存的数据可在 onResume() 里读出来,帮用户恢复到之前的状态。
8、Activity结束
在onDestroy()运行后,activity生命周期就结束了,可用 isFinishing()方法来推断。
假设此时有 Progress Dialog显示。我们应该在onDestroy()里 cancel 掉。否则线程结束的时候,调用Dialog 的 cancel 方法会抛异常。
2.请简单说下对广播接收者有哪些了解
广播接收者(BroadcastReceiver)用于接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast()、Context.sendOrderedBroadcast()来实现的。
通常一个广播Intent能够被订阅了此Intent的多个广播接收者所接收,这个特性跟JMS中的Topic消息接收者相似。
要实现一个广播接收者方法例如以下:
第一步:继承BroadcastReceiver,并重写onReceive()方法。
public class IncomingSMSReceiver extends BroadcastReceiver {
@Override public void onReceive(Context context, Intent intent) {
}
}
第二步:订阅指定的广播Intent,订阅方法有两种:
第一种:使用代码进行订阅
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
IncomingSMSReceiver receiver = new IncomingSMSReceiver();
registerReceiver(receiver, filter);
另外一种:在AndroidManifest.xml文件里的节点里进行订阅:
<receiver android:name=".IncomingSMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
广播类型:
广播分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”。普通广播是全然异步的。能够在同一时刻(逻辑上)被全部接收者接收到,消息传递的效率比較高,但缺点是:接收者不能将处理结果传递给下一个接收者,而且无法终止广播Intent的传播;然而有序广播是依照接收者声明的优先级别,被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C 。
优先级别声明在intent-filter元素的android:priority属性中,数越大优先级别越高,取值范围:-1000到1000,优先级别也能够调用IntentFilter对象的setPriority()进行设置 。
有序广播的接收者能够终止广播Intent的传播,广播Intent的传播一旦终止,后面的接收者就无法接收到广播。另外,有序广播的接收者能够将数据传递给下一个接收者,如:A得到广播后。能够往它的结果对象中存入数据,当广播传给B时,B能够从A的结果对象集合中得到A存入的数据。
Context.sendBroadcast() 发送的是普通广播,全部订阅者都有机会获得并进行处理。
Context.sendOrderedBroadcast() 发送的是有序广播。系统会依据接收者声明的优先级别按顺序逐个运行接收者,前面的接收者有权终止广播
BroadcastReceiver.abortBroadcast()。假设广播被前面的接收者终止,后面的接收者就再也无法获取到广播。对于有序广播,前面的接收者能够将数据通过setResultExtras(Bundle)方法存放进结果对象,然后传给下一个接收者。下一个接收者通过代码:Bundle bundle = getResultExtras(true))能够获取上一个接收者存入在结果对象中的数据。
系统收到短信,发出的广播属于有序广播。假设想阻止用户收到短信,能够通过设置优先级,让你们自己定义的接收者先获取到广播,然后终止广播。这样用户就接收不到短信了。
广播接收者的响应:
在Android中。每次广播消息到来时都会创建BroadcastReceiver实例并运行onReceive() 方法。 onReceive() 方法运行完后,BroadcastReceiver 的实例就会被销毁。当onReceive() 方法在10秒内没有运行完毕,Android会觉得该程序无响应。所以在BroadcastReceiver里不能做一些比較耗时的操作,否側会弹出ANR(Application No Response)的对话框。假设须要完毕一项比較耗时的工作。应该通过发送Intent给Service,由Service来完毕。这里不能使用子线程来解决。由于BroadcastReceiver的生命周期非常短,子线程可能还没有结束BroadcastReceiver就先结束了。BroadcastReceiver一旦结束,此时BroadcastReceiver的所在进程非常easy在系统须要内存时被优先杀死,由于它属于空进程(没有不论什么活动组件的进程)。假设它的宿主进程被杀死。那么正在工作的子线程也会被杀死。
所以採用子线程来解决是不可靠的。
public class IncomingSMSReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//发送Intent启动服务,由服务来完毕比較耗时的操作
Intent service = new Intent(context, XxxService.class);
context.startService(service);
}
}
经常使用广播Intent:
除了短信到来广播Intent。Android还有非常多广播Intent,如:开机启动、电池电量变化、时间已经改变等广播Intent。
接收开机启动广播Intent,在AndroidManifest.xml文件里的节点里订阅此Intent:
<receiver android:name=".IncomingSMSReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
而且要进行权限声明:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
接收电池电量变化广播Intent ,在AndroidManifest.xml文件里的节点里订阅此Intent:
<receiver android:name=".IncomingSMSReceiver">
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED"/>
</intent-filter>
</receiver>
广播接收者的生命周期及使用注意事项
1、广播接收者的生命周期是非常短暂的。在接收到广播的时候创建,onReceive()方法结束之后销毁
2、广播接收者中不要做一些耗时的工作,否则会弹出Application No Response错误对话框,耗时的较长的工作最好放在服务中完毕
3、最好也不要在广播接收者中创建子线程做耗时的工作,由于广播接收者被销毁后进程就成为了空进程,非常easy被系统杀掉
3.view怎样刷新?简述什么是双缓冲?
android中实现view的刷新有两个方法。一个是invalidate()。还有一个是postInvalidate(),当中前者是在UI线程自身中使用,而后者在非UI线程中使用。
出现屏幕闪烁是图形编程的一个常见问题。当进行复杂的绘制操作时会导致呈现的图像闪烁或具有其它不可接受的外观。双缓冲的使用解决这些问题。双缓冲使用内存缓冲区来解决由多重绘制操作造成的闪烁问题。当使用双缓冲时。首先在内存缓冲区里完毕全部绘制操作,而不是在屏幕上直接进行绘图。当全部绘制操作完毕后,把内存缓冲区完毕的图像直接拷贝到屏幕。
由于在屏幕上仅仅运行一个图形操作,所以消除了由复杂绘制操作造成的图像闪烁问题。
在android中实现双缓冲,能够使用一个后台画布backcanvas,先把全部绘制操作都在这上面进行。等图画好了,然后在把backcanvas拷贝到
与屏幕关联的canvas上去,例如以下:
Bitmap bitmapBase = new Bitmap()
Canvas backcanvas = new Canvas(bitmapBase)
backcanvas.draw()...//绘图
Canvas c = lockCanvas(null);
c.drawbitmap(bitmapBase);//把已经画好的图像输出到屏幕上
unlock(c)....
4、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 相似, 是基于接口的,但它是轻量级的。它使用代理类在client和实现层间传递值。假设要使用 AIDL, 须要完毕 2 件事情: 1. 引入 AIDL 的相关类; 2.调用 aidl 产生的 class。
AIDL 的创建方法:
AIDL 语法非常简单,能够用来声明一个带一个或多个方法的接口。也能够传递參数和返回值。
由于远程调用的须要, 这些參数和返回值并非不论什么类型。以下是些 AIDL 支持的数据类型:
1、 不须要 import 声明的简单 Java 编程语言类型(int,boolean 等);
2、String, CharSequence 不须要特殊声明。
3、 List, Map 和 Parcelables 类型, 这些类型内所包括的数据成员也仅仅能是简单数据类型, String 等其它支持的类型。
5、java中怎样引用本地语言
能够用JNI(java native interface java 本地接口)接口
6、谈谈Android的IPC(进程间通信)机制
IPC 是内部进程通信的简称。是共享”命名管道”的资源。Android 中的 IPC 机制是为了
让 Activity 和 Service 之间能够随时的进行交互,故在 Android 中该机制。仅仅适用于 Activity和 Service 之间的通信。相似于远程方法调用,相似于 C/S 模式的訪问。通过定义 AIDL 接口文件来定义 IPC 接口。Servier 端实现 IPC 接口,Client 端调用 IPC 接口本地代理。
7、NDK 是什么
NDK 是一些列工具的集合。 NDK 提供了一系列的工具,帮助开发人员迅速的开发 C/C++的动态库,并能自己主动将 so 和 java 应用打成 apk 包。
NDK 集成了交叉编译器,并提供了对应的 mk 文件和隔离 cpu、平台等的差异。开发人员仅仅需简单的改动 mk 文件就能够创建出 so。
8、怎样将SQLite数据库(xxx.db文件)与apk文件一起公布
能够将xxx.db文件拷贝到Eclipse Androidproject中的res aw文件夹中。全部在res aw文件夹中的文件不会被压缩。这样能够直接提取该文件夹中的文件。能够将xxx.db文件拷贝到res aw文件夹中。