近期有位Android 开发的朋友在吐槽说:现在的招聘信息网站是假的吧,我都怀疑一些公司的人事在冲他们的KPI,三个月了,简历投了上百份,结果收到回应的才个位数,去面试还一套Framework底层原理面试题狂炸……
面试题有(精选15题):
1. 请解释Activity的生命周期。
Activity的生命周期可分为7个阶段:
- 创建(Created):当Activity被创建时调用onCreate()方法。
- 开始(Started):当Activity已经完成onCreate()方法时,进入Started状态。在进入此状态时,Activity变得可见,但并未进入前台开始运行。此时,系统可以在Activity已经可见,但并未开始运行时决定是否直接暂停。
- 工作中(Resumed):在Activity进入前台时,就进入Resumed状态。此时Activity已经准备好与用户进行交互。此时应该将Activity的启动细节实现完成,可以进行相应的UI相关操作。
- 暂停(Paused):当Activity被覆盖到后台某个可见Activity时,onPause()方法会被调用。此时Activity不再与用户进行交互。应该在此状态下保存Activity所需要的状态和数据。
- 停止(Stopped):当某个Activity被遮挡时,onStop()方法会被调用,此时Activity已经不再可见。可以在此状态下释放之前所占用的资源。
- 重新开始(Restarted):当Activity重新进入前台时,onRestart()方法会被调用。从Stopped状态到此状态的转换并不会触发onCreate()方法,因此在此方法中要特别处理。
- 销毁(Destroyed):当Activity被销毁时,onDestroy()方法会被调用。在此方法中,应该释放所有Activity所占用的内存和资源。此时Activity 不可再次进入任何状态。
2. 解释Android应用程序组件,并给出它们的用途。
Android应用程序组件是构成Android应用程式的基本单元,包含以下四个组件:
- Activity:是一种用户界面,可以为用户提供可交互的界面,显示信息,处理用户的事件和实现交互。
- Service:在后台执行长时间运行的操作或处理远程接口的组件。一个Service没有用户界面,它可以在后台运行,即使应用已经被最后一个Activity关闭也可以继续运行。
- Broadcast Receiver:处理应用或系统发出的广播消息的组件。一个Broadcast Receiver会在应用甚至系统的状态发生变化时拦截消息,然后可以将消息交给Service或Activity进行处理。
- Content Provider:提供应用程序数据的安全标准访问机制。Content Provider允许应用程序共享数据,并对外提供数据的增删改查功能。
3. 什么是IPC(进程间通信),它与Android Framework有什么关系?
IPC(Inter-Process Communication)是指在不同进程间传递数据或通信的技术。在Android Framework中,进程间通信可通过以下几种方式实现:
- intent:用于在不同组件间传递数据,包括跨进程传递数据。通过设置Action/Category/Type等属性,在通过startActivity()方法和startService方法来发送和处理Intent。
- Binder:用于在不同进程间进行远程过程调用(RPC),主要是在Service中使用。它可以让客户端使用与服务端相同的操作,以此简化客户端和服务端之间的通信。
- Content Provider:是一种Android Framework提供的进程间通信机制。Content Provider可以向其他应用程序暴露数据,允许其他应用程序读取和修改该数据。其他应用程序可以使用URI来进行访问,并可以通过Content Resolver来管理它们。
4. 请解释什么是Looper,Handler和MessageQueue?
- Looper:是一种用于循环接收消息的工具类。它是在一个线程中架上一个消息循环,在消息队列中接收来自其他线程的消息并由Handler进行处理。
- Handler:用于在UI线程中操作工作队列。它通常与Looper一起使用,可以将Runnable或Message添加到消息队列中,以此执行延迟任务或处理异步消息。
- MessageQueue:是一种先进先出的消息队列,用于保存Handler接收到的Android消息,并立即移交给UI线程Loop用于处理。
5. 解释Binder和AIDL(Android接口定义语言)。
Binder是一种轻量级的Android IPC机制,它是Android Framework中基于C/S模式的一种通信机制。其中一个进程提供服务,而其他进程向该进程请求服务。Binder的实现基于Linux的IPC技术,但添加了诸如线程池、内存池和其他优化,以此提高效率。
AIDL (Android接口定义语言)是一种解析Android API接口的工具。AIDL描述了将要对远程方法进行编码的IPC通信接口。在Binder API中,需要指定所有的接口、输入和输出参数以及可能的例外情况。编写AIDL可以帮助程序员解析这些接口,确保客户端和服务端相互间的通信能够顺利实现。
6. 请解释Android应用程序如何与系统服务进行交互。
Android应用程序可以通过以下方式与系统服务进行交互:
- Intent:可以使用Intent启动系统服务,并在Intent中包含附加的数据,以此指定执行服务的详细要求。可以使用getService()启动服务或使用startActivity(),以便启动活动并交互。
- Content Resolver:是一种访问系统数据的机制,并且用于向Android应用程序提供系统服务。应用程序可以使用ContentResolver访问系统服务,包括媒体服务、存储服务、位置服务等。
- IBinder接口:可以使用IBinder接口是一种进程间通信机制,Binder API支持远程方法调用(RPC),可以通过Binder API实现同一进程内或不同进程间的通信。可以在Activity中实现该接口的方法,并使用IPC机制实现与服务交互。
7. 解释Content Provider的作用及其用途。
Content Provider是Android Framework提供的一种机制,可以将应用程序的数据进行标准化和安全化,提供给其他应用程序进行访问。它提供了类似于数据库的类似API,允许其他应用程序读取、更新和发布数据。Content Provider的一些用途包括:
- 可以与其他应用程序共享数据,允许其他应用程序访问数据。
- 进行数据的标准化和安全化,可以控制对特定数据的访问权限。
- 提供搜索和过滤机制,对于特定应用程序需要搜索和查询的数据非常有用。
- 可以用于在不同应用程序中共享特定的信息,如联系人信息、电子邮件地址等。
8. 什么是Android资源管理器,它的作用是什么?
Android资源管理器(ResourcesManager)是Android Framework中的一种管理应用程序缺省设置和自定义资源的机制。 它可以加载、管理和维护应用程序资源,例如图像、音频、字符串、小数等数据。 Android的资源文件存储在res /子文件夹中,运行后系统会将这些文件打包为APK格式的单个文件。 资源管理器可以在运行时加载和解析这些文件。
其中,资源管理器的作用包括:
- 提供了一种加载和管理应用程序资源的机制,可确保系统随时可以访问和使用特定资源。
- 管理应用程序缺省设置和自定义资源,使得用户可以自由地使用各种主题和UI等定制设定。
- 使开发人员能够轻松地将资源添加到应用程序中,提供了一种标准化方法来组织、管理和使用应用程序资源。
9. 如何在Android应用程序中处理多线程和异步任务?
在Android应用程序中,多线程和异步任务处理非常关键,可以通过以下方式实现:
- 使用Handler:通过Handler可以在UI线程中操作工作队列。它通常与Looper一起使用,可以将Runnable或Message添加到消息队列中,以此执行延迟任务或处理异步消息。
- 使用AsyncTask:它是Android Framework中一个方便易用的类,在UI线程上执行后台任务,也可以进行进度更新和结果返回。
- 使用Loaders:也是一种异步处理机制,可用于加载和管理大型数据集合或重量级资源。
- 使用线程池和Future:可以将工作线程提交到线程池中,并使用Future代表正在执行的任务的结果。
- 使用RxJava:RxJava是一种基于异步事件流衔接的响应式编程模式,它可以帮助开发人员处理复杂的异步操作,比如执行多个网络请求、数据库查询等。
10. 解释什么是依赖注入,Android Framework如何支持依赖注入?
依赖注入是一种软件设计模式,它通过解耦使应用程序更容易维护和扩大。在Android开发中,它可用于解决组件之间的耦合问题,简化代码,并提高代码的可维护性和可重用性。Android Framework支持依赖注入的机制包括:
- Dagger:是一种依赖注入框架,通过使用注解和实现模式将依赖对象绑定到应用程序的组件中。它使得Android应用程序的开发过程更加简洁和高效。
- ButterKnife:是一个简化Android开发中的UI实现的工具库。它允许将View和其他Android UI元素自动与代码绑定在一起,从而简化了许多传统的UI实现代码。
- AndroidAnnotations:是一个Java库,使用注解来简化UI组件的初始化和事件处理过程。例如,您可以使用@ViewById注解将View与布局相对应,或使用@Click注解处理按钮单击事件。
11. 如何使用Android Framework支持的依赖注入库,例如Dagger或ButterKnife?
Dagger和ButterKnife都是常见的Android Framework依赖注入库。使用这些库可以简化代码,并提高代码的可维护性和可重用性。使用这些库的一般步骤包括:
- 添加相应的依赖:在build.gradle文件中添加相关的库依赖,例如:
dependencies {
// Dagger
implementation 'com.google.dagger:dagger:2.35.1'
kapt 'com.google.dagger:dagger-compiler:2.35.1'
// ButterKnife
implementation 'com.jakewharton:butterknife:10.2.3'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'
}
- 在代码中添加注解:使用注解来标记要注入的组件或属性,例如:
// Dagger
@Module
public class MyModule {
@Provides
MyDependency provideMyDependency() {
return new MyDependency();
}
}
class MyActivity extends AppCompatActivity {
@Inject
MyDependency myBean;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMyComponent.builder().build().inject(this);
myBean.doStuff();
}
}
// ButterKnife
public class MyActivity extends AppCompatActivity {
@BindView(R.id.my_button)
Button myButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MyActivity.this, "Button clicked", Toast.LENGTH_SHORT).show();
}
});
}
}
- 构建依赖注入组件:使用依赖注入库提供的一些构建器和组件方法创建用于注入组件的对象。例如:
// Dagger
@Component(modules = { MyModule.class })
public interface MyComponent {
void inject(MyActivity myActivity);
}
// ButterKnife不需要构建组件
- 注入组件:使用依赖注入库提供的组件构造器注入组件,例如:
// Dagger
DaggerMyComponent.builder().build().inject(this);
// ButterKnife不需要显式注入
12. 请解释Android Framework中的BroadcastReceiver,以及它的使用场景和生命周期。
BroadcastReceiver 是 Android 的一种组件,它允许应用程序接收系统广播和应用内部的自定义广播,并在接收到广播时执行特定的操作。广播接收器可以来自系统,例如电池电量,网络变化,屏幕锁定等事件; 也可以来自我们自己的应用程序。
BroadcastReceiver 的使用场景包括但不限于:
- 系统事件监听:例如网络连接、屏幕开关、电池电量、手机信号强度等;
- 应用内自定义广播:例如应用内部的状态变更、数据更新、系统通知等;
- 应用与应用之间的通讯:例如 A 应用向 B 应用发送广播通知等;
BroadcastReceiver 的生命周期分为两个阶段:注册和运行。
注册阶段:
BroadcastReceiver 通常在 AndroidManifest.xml 中声明,以指定它可以处理哪些广播。当应用启动时,系统会扫描其清单文件,找到所有已注册的 BroadcastReceiver,并在系统发出广播时通知它们。
运行阶段:
当系统发出一个广播时,所有注册了相应广播的 BroadcastReceiver 都会收到通知。如果在处理广播时,BroadcastReceiver 执行了一些异步任务或者需要长时间执行的操作,建议使用 IntentService、HandlerThread 等组件,避免阻塞主线程。在广播接收器的操作完成后,可以选择继续执行任务或停止广播传递。
BroadcastReceiver 是 Android 系统中非常重要的组件,可以用来处理各种系统和应用内的广播事件。由于其灵活性和可扩展性,它被广泛地应用于各种 Android 应用程序中。
13.如何使用Android Framework支持的网络库,例如Volley或Retrofit?
Android Framework支持多种网络库,其中Volley和Retrofit是比较常用的库。下面是它们的简单使用方法:
使用Volley:
- 在Gradle文件中添加Volley库的依赖关系。
dependencies {
implementation 'com.android.volley:volley:1.1.0'
}
- 创建一个RequestQueue对象,将网络请求加入队列中。例如,构建一个GET请求:
// 建立请求队列
RequestQueue queue = Volley.newRequestQueue(this);
String url = "https://www.example.com";
// 创建RequestQueue对象发起GET请求
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
// handle response
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// handle error
}
});
// 将请求加入队列中
queue.add(jsonObjectRequest);
使用Retrofit:
- 在Gradle文件中添加Retrofit库的依赖关系。
dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.7.2'
implementation 'com.squareup.retrofit2:converter-gson:2.7.2'
}
- 创建Retrofit对象,并定义接口与服务端通信。
public interface ApiService {
@GET("/api/endpoint")
Call<ResponseBody> getData();
}
// 创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://www.example.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
// 绑定接口与服务端通信
ApiService service = retrofit.create(ApiService.class);
// 发起GET请求
Call<ResponseBody> call = service.getData();
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
// handle response
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
// handle error
}
});
需要注意的是,Retrofit在解析响应体时需要指定解析器,例如Gson解析器,以便将响应体转换为Java bean或其他数据类。 这里使用GsonConverterFactory将响应体转为Json解析的数据类。
使用Volley和Retrofit很容易,只需按照上述步骤安装它们以及创建网络请求,便可以快速地从服务端获取网络数据。
14.解释Android Framework中的Service,以及它的用途和生命周期。
Service指的是在后台执行长时间运行操作的Android组件。它没有用户界面,但可以接收其他组件的请求并执行需要完成的任务。Service通常用于执行一些耗时的操作,如下载文件、播放音乐或者进行数据同步等。
Service可以使用以下方法来创建:
- 扩展Service类:开发者可以创建一个类来扩展Service类,并在其中实现相关的逻辑。
- 使用匿名类:也可以使用匿名类的方式创建Service,这种方式适用于少量的任务。
Service的生命周期包括以下三个阶段: - Created: Service在调用startService()方法时创建,并调用onCreate()方法。
- Running: 当Service处于Running状态时,它可以通过Intent接收请求执行任务,执行完任务后将继续保持Running状态。
- Destroyed: Service在调用stopService()方法时销毁并调用onDestroy()方法。
Service可以通过以下方式停止运行:
- 调用stopService():Service在接收到stopService()方法调用时,会自行关闭。
- 调用stopSelf():Service在任务完成后,可以调用stopSelf()方法来主动结束自身。
- 系统关闭:Service在系统资源不足时,会被系统强制关闭。
Service是一种非常重要的Android组件,它可以在后台执行复杂的任务,并且生命周期较长。在应用开发中,Service被广泛地应用于音乐播放、文件下载、数据同步和推送服务等方面。
最后
去面试过的一些公司问的还有很多,这里我只是选了15道比较经典的问题给大家进行参考一下。虽然只收到了个别公司的面试,但面试基本都过了,只是不想去,主要的原因是薪资被腰斩了,还没我私活赚得多,唉!再等等我相信缘分总会来得。
通过这几次的面试,我发现现在的市场已经巨变,以前对开发者要求没有深入到底层这块过,现如今十几有九家要问到 Framework底层这块(小型公司除外)。而大多数Android 开发基本之前做的是业务层的开发,对Framework 底层并不是特别的了解。
所以为了帮助到大家更好的了解Android Framework框架中的知识点,这边查阅大量的素材,整理了一下的 Android Framework 核心知识点手册,里面记录了:有Handler、Binder、AMS、WMS、PMS、事件分发机制、UI绘制……等等,几乎把更Framework相关的知识点全都记录在册了,还有一些Android 相关的面试题
《Android Framework学习手册》:https://qr18.cn/AQpN4J
- 开机Init 进程
- 开机启动 Zygote 进程
- 开机启动 SystemServer 进程
- Binder 驱动
- AMS 的启动过程
- PMS 的启动过程
- Launcher 的启动过程
- Android 四大组件
- Android 系统服务 - Input 事件的分发过程
- Android 底层渲染 - 屏幕刷新机制源码分析
- Android 源码分析实战
Framework底层对于现在的Android开发至关重要,因为它提供了许多基础服务和API,使得应用程序可以与操作系统进行交互和通信。以下是Framework底层对于现在的Android开发的重要性:
-
应用程序开发:Android Framework提供了许多API和工具,可以协助开发人员创建和测试应用程序,以及与其他应用程序进行通信。例如,Activity Manager和Window Manager可以帮助开发人员管理应用程序的生命周期和窗口布局,而Resource Manager可以管理应用程序的资源。
-
系统性能管理:Framework底层还提供了许多服务和API,可以帮助开发人员在应用程序运行时优化系统性能。例如,Process Manager可以帮助开发人员管理内存和CPU资源,防止应用程序因为内存泄露或占用过多CPU资源而导致系统崩溃。
-
跨应用程序数据共享:Android Framework提供了许多服务和API,允许应用程序之间共享数据。例如,Activity Binder可以帮助应用程序之间进行跨进程通信,而Content Provider可以帮助不同应用程序之间共享数据。
-
多媒体文件管理:Framework底层还提供了许多服务和API,可以帮助应用程序处理和管理多媒体文件,例如图片、音频、视频等。例如,Multimedia Framework可以帮助应用程序处理各种多媒体文件的格式和编解码。
Framework底层对于现在的Android开发非常重要,因为它提供了许多基础服务和API,可以帮助开发人员创建高效、稳定和功能丰富的Android应用程序。开发人员必须深入了解Framework底层,以便更好地了解Android系统的内部工作原理,并在应用程序开发过程中合理地使用这些服务和API。