干货:Android工程师面试题(四)Android工程师

/ 厦门大学经济学院Android工程师 / 2017-04-01

Android工程师面试题第四弹已新鲜出炉,请关注汇鱼人才,汇鱼人才将会给大家带来更多的内容。

Android,Android工程师,汇鱼人才

1、请介绍下ContentProvider是如何实现数据共享的。


一个程序可以通过实现一个Content provider的抽象接口将自己的数据完全暴露出去,而且Content providers是以类似数据库中表的方式将数据暴露。Content providers存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方法。要想使应用程序的数据公开化,可通过2种方法:


(1)创建一个属于你自己的Content provider或者将你的数据添加到一个已经存在的Content provider中,前提是有相同数据类型并且有写入Content provider的权限。


(2)Android提供了ContentResolver,外界的程序可以通过ContentResolver接口访问ContentProvider提供的数据。


2、Android 的优势与不足


Android平台手机 5大优势:

(1)开放性

(2)挣脱运营商的束缚

(3)丰富的硬件选择

(4)不受任何限制的开发商

(5)无缝结合的Google应用


再说Android的5大不足


(1)安全和隐私

(2)首先开卖Android手机的不是最大运营商

(3)运营商仍然能够影响到Android手机

(4)同类机型用户减少

(5)过分依赖开发商缺少标准配置


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

(1)从MVC的角度考虑(应用程序内)


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


(2)程序间互通消息


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


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


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


AIDL全称Android Interface Definition Language(AndRoid接口描述语言)是一种借口描述语言; 编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程跨界对象访问的目的.AIDL的IPC的机制和COM或CORBA类似,是基于接口的,但它是轻量级的。它使用代理类在客户端和实现层间传递值。如果要使用AIDL需要完成2件事情: 1引入AIDL的相关类;(2调用aidl产生的class.理论上参数可以传递基本数据类型和String, 还有就是Bundle的派生类, 不过在Eclipse中,目前的ADT不支持Bundle做为参数,


具体实现步骤如下:


(1)创建AIDL文件, 在这个文件里面定义接口, 该接口定义了可供客户端访问的方法和属性。


(2)编译AIDL文件, Ant的话, 可能需要手动, 使用Eclipse plugin的话,可以根据adil文件自动生产java文件并编译, 不需要人为介入


(3)在Java文件中, 实现AIDL中定义的接口. 编译器会根据AIDL接口, 产生一个JAVA接口。这个接口有一个名为Stub的内部抽象类,它继承扩展了接口并实现了远程调用需要的几个方法。接下来就需要自己去实现自定义的几个接口了


(4)向客户端提供接口ITaskBinder, 如果写的是service,扩展该Service并重载onBind ()方法来返回一个实现上述接口的类的实例。


(5)在服务器端回调客户端的函数. 前提是当客户端获取的IBinder接口的时候,要去注册回调函数, 只有这样, 服务器端才知道该调用那些函数


AIDL语法很简单,可以用来声明一个带一个或多个方法的接口,也可以传递参数和返回值。 由于远程调用的需要,这些参数和返回值并不是任何类型。


下面AIDL支持的数据类型:


1. 不需要import声明的简单Java编程语言类型(int,boolean等)

2. String, CharSequence不需要特殊声明 

3. List, Map和Parcelables类型, 这些类型内所包含的数据成员也只能是简单数据类型, String等其他比支持的类型. 

实现接口时有几个原则:

(1)抛出的异常不要返回给调用者. 跨进程抛异常处理是不可取的


(2)IPC调用是同步的。如果你知道一个IPC服务需要超过几毫秒的时间才能完成地话,你应该避免在Activity的主线程中调用。 也就是IPC调用会挂起应用程序导致界面失去响应.。这种情况应该考虑单起一个线程来处理。


(3)不能在AIDL接口中声明静态属性。


IPC的调用步骤:

(1)声明一个接口类型的变量,该接口类型在.aidl文件中定义。


(2)实现ServiceConnection。


(3)调用ApplicationContext.bindService(),并在ServiceConnection实现中进行传递. 


(4)在ServiceConnection.onServiceConnected()实现中,你会接收一个IBinder实例(被调用的Service)。调YourInterfaceName.Stub.asInterface((IBinder)service)将参数转换为YourInterface类型。


(5)调用接口中定义的方法。 你总要检测到DeadObjectException异常,该异常在连接断开时被抛出。它只会被远程方法抛出。


(6)断开连接,调用接口实例中的ApplicationContext.unbindService()


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

Android中,不同进程之间传递信息要用到广播,可以有两种方式来实现。


第一种方式:Manifest.xml中注册广播,是一种比较推荐的方法,因为它不需要手动注销广播(如果广播未注销,程序退出时可能会出错)。

具体实现在Manifest的application中添加:


上面两个android:name分别是广播名和广播的动作(这里的动作是表示系统启动完成),如果要自己发送一个广播,在代码中为:

Intent i = new Intent(“android.intent.action.BOOT_COMPLETED”);

sendBroadcast(i);

这样,广播就发出去了,然后是接收。

接收可以新建一个类,继承至BroadcastReceiver,也可以建一个BroadcastReceiver的实例,然后得写onReceive方法,实现如下:

protected BroadcastReceiver mEvtReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

if (action.equals(“android.intent.action.BOOT_COMPLETED”)) {

//Do something

}

}

};


第二种方式直接在代码中实现,但需要手动注册注销,实现如下:

IntentFilter filter = new IntentFilter();

filter.addAction(“android.intent.action.BOOT_COMPLETED”);

registerReceiver(mEvtReceiver, filter); //这时注册了一个recevier ,名为 mEvtReceiver,然后同样用上面的方法以重写onReceiver,

最后在程序的onDestroy中要注销广播,实现如下:

@Override

public void onDestroy() {

super.onDestroy();

unregisterReceiver(mPlayerEvtReceiver);

}

Android系统中的广播是广泛用于应用程序之间通信的一种手段,它类似于事件处理机制,不同的地方就是广播的处理是系统级别的事件处理过程(一般事件处理是控件级别的)。在此过程中仍然是离不开Intent对象,理解广播事件的处理过程,灵活运用广播处理机制,在关键之处往往能实现特别的效果


Android中如果要发送一个广播必须使用sendBroadCast向系统发送对其感兴趣的广播接收器中。

使用广播必须要有一个intent 对象必设置其action动作对象

使用广播必须在配置文件中显式的指明该广播对象

每次接收广播都会重新生成一个接收广播的对象

BroadCast中尽量不要处理太多逻辑问题,建议复杂的逻辑交给Activity或者Service去处理

 

汇鱼人才已陆陆续续给大家晒出了四批干货,还将给大伙晒出第五批Android工程师面试题,大家拭目以待吧!



公众号,微信

汇鱼网海峡创乐汇
汇鱼网海峡创乐汇