这份面试题整理涵盖了2025年Android开发的核心技术栈,建议根据目标职位的级别重点准备相应的技术深度。记住,面试不仅要展示技术能力,还要体现解决问题的思路和持续学习的态度。
Q: 详细说明Activity的生命周期,以及各个方法的调用时机?
A: Activity生命周期包含7个关键方法:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Activity首次创建时调用,进行初始化工作
// 设置布局、初始化变量、绑定数据等
}
override fun onStart() {
super.onStart()
// Activity变为可见但不可交互时调用
// 通常在这里注册广播接收器
}
override fun onResume() {
super.onResume()
// Activity获得焦点,用户可以交互时调用
// 开始动画、获取相机等独占资源
}
override fun onPause() {
super.onPause()
// Activity失去焦点但仍可见时调用
// 暂停动画、释放独占资源、保存数据
}
override fun onStop() {
super.onStop()
// Activity完全不可见时调用
// 停止耗时操作、注销广播接收器
}
override fun onRestart() {
super.onRestart()
// Activity从停止状态重新启动时调用
}
override fun onDestroy() {
super.onDestroy()
// Activity被销毁前调用
// 释放所有资源、取消网络请求
}
}Q: 详细解释Android的事件分发机制?
A: 事件分发遵循"U型"传递模式:
// ViewGroup事件分发
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
var handled = false
// 1. 首先检查是否拦截事件
val intercepted = onInterceptTouchEvent(ev)
if (!intercepted) {
// 2. 不拦截则分发给子View
for (child in children) {
if (child.dispatchTouchEvent(ev)) {
handled = true
break
}
}
}
// 3. 子View不处理或被拦截,则自己处理
if (!handled) {
handled = onTouchEvent(ev)
}
return handled
}
// View事件处理
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
// 处理按下事件
return true // 返回true表示消费事件
}
MotionEvent.ACTION_MOVE -> {
// 处理移动事件
}
MotionEvent.ACTION_UP -> {
// 处理抬起事件
performClick() // 触发点击事件
}
}
return super.onTouchEvent(event)
}Q: ViewModel的作用是什么?与LiveData如何配合使用?
A: ViewModel用于管理UI相关数据,在配置更改时保持数据:
class UserViewModel : ViewModel() {
private val _userData = MutableLiveData<User>()
val userData: LiveData<User> = _userData
private val _loading = MutableLiveData<Boolean>()
val loading: LiveData<Boolean> = _loading
fun loadUser(userId: String) {
_loading.value = true
viewModelScope.launch {
try {
val user = userRepository.getUser(userId)
_userData.value = user
} catch (e: Exception) {
// 处理错误
} finally {
_loading.value = false
}
}
}
override fun onCleared() {
super.onCleared()
// 清理资源
}
}
// Activity中使用
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: UserViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this)[UserViewModel::class.java]
// 观察数据变化
viewModel.userData.observe(this) { user ->
updateUI(user)
}
viewModel.loading.observe(this) { isLoading ->
progressBar.isVisible = isLoading
}
}
}Q: StateFlow与LiveData的区别?什么时候使用哪个?
A:
| 特性 | LiveData | StateFlow |
|---|---|---|
| 生命周期感知 | ✅ 自动感知 | ❌ 需手动处理 |
| 初始值 | ❌ 可选 | ✅ 必须有 |
| 线程安全 | ✅ | ✅ |
| 背压处理 | ❌ | ✅ |
| 操作符 | ❌ 有限 | ✅ 丰富 |
class ModernViewModel : ViewModel() {
// StateFlow - 适用于状态管理
private val _uiState = MutableStateFlow(UiState.Loading)
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
// LiveData - 适用于简单的UI更新
private val _message = MutableLiveData<String>()
val message: LiveData<String> = _message
// Flow - 适用于数据流处理
val searchResults = searchQuery
.debounce(300)
.distinctUntilChanged()
.flatMapLatest { query ->
repository.search(query)
}
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyList()
)
}Q: 什么是Kotlin协程?相比线程有什么优势?
A: 协程是轻量级的并发单元,主要优势:
class CoroutineExample {
// 1. 轻量级 - 可以创建大量协程
fun createManyCoroutines() {
runBlocking {
repeat(100_000) {
launch {
delay(1000)
println("Coroutine $it")
}
}
}
}
// 2. 结构化并发 - 自动管理生命周期
suspend fun fetchUserData(userId: String): User {
return coroutineScope {
val userDeferred = async { userService.getUser(userId) }
val profileDeferred = async { profileService.getProfile(userId) }
val user = userDeferred.await()
val profile = profileDeferred.await()
user.copy(profile = profile)
}
}
// 3. 异常处理
fun handleExceptions() {
val exceptionHandler = CoroutineExceptionHandler { _, exception ->
Log.e("Coroutine", "Exception: $exception")
}
GlobalScope.launch(exceptionHandler) {
// 可能抛出异常的代码
}
}
}Q: 常用的Flow操作符有哪些?如何使用?
A:
class FlowOperators {
fun demonstrateOperators() = flow {
repeat(10) {
emit(it)
delay(100)
}
}
.map { it * 2 } // 转换
.filter { it > 5 } // 过滤
.take(5) // 取前5个
.debounce(50) // 防抖
.distinctUntilChanged() // 去重
.catch { e -> // 异常处理
emit(-1)
}
.flowOn(Dispatchers.IO) // 指定执行线程
// 组合多个Flow
fun combineFlows() {
val flow1 = flowOf(1, 2, 3)
val flow2 = flowOf("A", "B", "C")
flow1.zip(flow2) { num, letter ->
"$num$letter"
}.collect { result ->
println(result) // 1A, 2B, 3C
}
}
// 热流转换
fun createHotFlow() {
val coldFlow = flow {
repeat(5) {
emit(it)
delay(1000)
}
}
val hotFlow = coldFlow.shareIn(
scope = GlobalScope,
started = SharingStarted.WhileSubscribed(),
replay = 1
)
}
}Q: 如何实现标准的MVVM架构?
A:
// Model层 - 数据层
data class User(
val id: String,
val name: String,
val email: String
)
interface UserRepository {
suspend fun getUser(id: String): User
suspend fun updateUser(user: User): User
}
class UserRepositoryImpl(
private val apiService: ApiService,
private val userDao: UserDao
) : UserRepository {
override suspend fun getUser(id: String): User {
return try {
val user = apiService.getUser(id)
userDao.insertUser(user)
user
} catch (e: Exception) {
userDao.getUser(id) ?: throw e
}
}
}
// ViewModel层 - 业务逻辑层
class UserViewModel(
private val repository: UserRepository
) : ViewModel() {
private val _uiState = MutableStateFlow(UserUiState())
val uiState: StateFlow<UserUiState> = _uiState.asStateFlow()
fun loadUser(userId: String) {
viewModelScope.launch {
_uiState.value = _uiState.value.copy(loading = true)
try {
val user = repository.getUser(userId)
_uiState.value = _uiState.value.copy(
user = user,
loading = false,
error = null
)
} catch (e: Exception) {
_uiState.value = _uiState.value.copy(
loading = false,
error = e.message
)
}
}
}
}
data class UserUiState(
val user: User? = null,
val loading: Boolean = false,
val error: String? = null
)
// View层 - UI层
class UserFragment : Fragment() {
private val viewModel: UserViewModel by viewModels()
private var _binding: FragmentUserBinding? = null
private val binding get() = _binding!!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycleScope.launch {
viewModel.uiState.collect { state ->
updateUI(state)
}
}
}
private fun updateUI(state: UserUiState) {
binding.apply {
progressBar.isVisible = state.loading
state.user?.let { user ->
textName.text = user.name
textEmail.text = user.email
}
state.error?.let { error ->
Snackbar.make(root, error, Snackbar.LENGTH_LONG).show()
}
}
}
}Q: 如何避免内存泄漏?常见的内存泄漏场景有哪些?
A:
// 1. Handler内存泄漏 - 错误示例
class BadActivity : AppCompatActivity() {
private val handler = Handler(Looper.getMainLooper()) // 持有Activity引用
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
handler.postDelayed({
// 可能在Activity销毁后执行
updateUI()
}, 10000)
}
}
// 正确做法
class GoodActivity : AppCompatActivity() {
private val handler = Handler(Looper.getMainLooper())
private val runnable = Runnable {
updateUI()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
handler.postDelayed(runnable, 10000)
}
override fun onDestroy() {
super.onDestroy()
handler.removeCallbacks(runnable) // 清理回调
}
}
// 2. 静态引用内存泄漏 - 使用弱引用
class Utils {
companion object {
private var contextRef: WeakReference<Context>? = null
fun init(context: Context) {
contextRef = WeakReference(context.applicationContext)
}
fun getContext(): Context? = contextRef?.get()
}
}
// 3. 监听器内存泄漏 - 及时注销
class LocationActivity : AppCompatActivity() {
private lateinit var locationManager: LocationManager
private val locationListener = object : LocationListener {
override fun onLocationChanged(location: Location) {
// 处理位置更新
}
}
override fun onResume() {
super.onResume()
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
1000L,
1f,
locationListener
)
}
override fun onPause() {
super.onPause()
locationManager.removeUpdates(locationListener) // 注销监听器
}
}Q: RecyclerView有哪些优化技巧?
A:
class OptimizedAdapter : RecyclerView.Adapter<OptimizedAdapter.ViewHolder>() {
private val items = mutableListOf<Item>()
// 1. 使用DiffUtil提高更新效率
fun updateItems(newItems: List<Item>) {
val diffCallback = ItemDiffCallback(items, newItems)
val diffResult = DiffUtil.calculateDiff(diffCallback)
items.clear()
items.addAll(newItems)
diffResult.dispatchUpdatesTo(this)
}
// 2. ViewHolder复用优化
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ItemLayoutBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(items[position])
}
// 3. 预加载优化
override fun onBindViewHolder(
holder: ViewHolder,
position: Int,
payloads: MutableList<Any>
) {
if (payloads.isEmpty()) {
super.onBindViewHolder(holder, position, payloads)
} else {
// 增量更新
holder.bindPayload(items[position], payloads)
}
}
class ViewHolder(private val binding: ItemLayoutBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: Item) {
binding.apply {
textTitle.text = item.title
textDescription.text = item.description
// 4. 图片加载优化
Glide.with(imageView.context)
.load(item.imageUrl)
.placeholder(R.drawable.placeholder)
.into(imageView)
}
}
fun bindPayload(item: Item, payloads: List<Any>) {
// 只更新变化的部分
payloads.forEach { payload ->
when (payload) {
"title" -> binding.textTitle.text = item.title
"description" -> binding.textDescription.text = item.description
}
}
}
}
}
// RecyclerView配置优化
class OptimizedRecyclerView {
fun setupRecyclerView(recyclerView: RecyclerView) {
recyclerView.apply {
// 5. 设置固定大小
setHasFixedSize(true)
// 6. 设置RecycledViewPool
val sharedPool = RecyclerView.RecycledViewPool()
setRecycledViewPool(sharedPool)
// 7. 设置ItemAnimator
itemAnimator = DefaultItemAnimator().apply {
supportsChangeAnimations = false
}
// 8. 预取优化
layoutManager = LinearLayoutManager(context).apply {
isItemPrefetchEnabled = true
initialPrefetchItemCount = 4
}
}
}
}Q: Jetpack Compose的核心概念是什么?与传统View系统有什么区别?
A:
// 1. 声明式UI - Compose
@Composable
fun UserProfile(user: User, onEditClick: () -> Unit) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
) {
Column(
modifier = Modifier.padding(16.dp)
) {
Text(
text = user.name,
style = MaterialTheme.typography.headlineSmall
)
Text(
text = user.email,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = onEditClick) {
Text("Edit Profile")
}
}
}
}
// 2. 状态管理
@Composable
fun CounterScreen() {
var count by remember { mutableStateOf(0) }
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxSize()
) {
Text(
text = "Count: $count",
style = MaterialTheme.typography.headlineMedium
)
Row {
Button(onClick = { count-- }) {
Text("-")
}
Spacer(modifier = Modifier.width(16.dp))
Button(onClick = { count++ }) {
Text("+")
}
}
}
}
// 3. 副作用处理
@Composable
fun UserListScreen(viewModel: UserViewModel = hiltViewModel()) {
val uiState by viewModel.uiState.collectAsState()
// LaunchedEffect - 启动协程
LaunchedEffect(Unit) {
viewModel.loadUsers()
}
// DisposableEffect - 资源清理
DisposableEffect(Unit) {
val listener = SomeListener()
registerListener(listener)
onDispose {
unregisterListener(listener)
}
}
when {
uiState.loading -> {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator()
}
}
uiState.error != null -> {
ErrorMessage(
message = uiState.error,
onRetry = { viewModel.loadUsers() }
)
}
else -> {
LazyColumn {
items(uiState.users) { user ->
UserItem(user = user)
}
}
}
}
}
// 4. 自定义Composable
@Composable
fun LoadingButton(
text: String,
loading: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
Button(
onClick = onClick,
enabled = !loading,
modifier = modifier
) {
if (loading) {
CircularProgressIndicator(
modifier = Modifier.size(16.dp),
strokeWidth = 2.dp
)
} else {
Text(text)
}
}
}Q: 如何优化网络请求性能?
A:
// 1. OkHttp配置优化
class NetworkModule {
@Provides
@Singleton
fun provideOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
// 连接池优化
.connectionPool(ConnectionPool(5, 5, TimeUnit.MINUTES))
// 超时设置
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
// 重试机制
.retryOnConnectionFailure(true)
// 缓存配置
.cache(Cache(File(context.cacheDir, "http_cache"), 50L * 1024 * 1024))
// 拦截器
.addInterceptor(HttpLoggingInterceptor().apply {
level = if (BuildConfig.DEBUG) {
HttpLoggingInterceptor.Level.BODY
} else {
HttpLoggingInterceptor.Level.NONE
}
})
.addInterceptor(AuthInterceptor())
.addNetworkInterceptor(CacheInterceptor())
.build()
}
}
// 2. 缓存策略
class CacheInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
// 无网络时使用缓存
val newRequest = if (!isNetworkAvailable()) {
request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build()
} else {
request
}
val response = chain.proceed(newRequest)
// 设置缓存策略
return if (isNetworkAvailable()) {
response.newBuilder()
.header("Cache-Control", "public, max-age=60")
.build()
} else {
response.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=86400")
.build()
}
}
}
// 3. API接口设计
interface ApiService {
@GET("users/{id}")
suspend fun getUser(@Path("id") userId: String): User
@GET("users")
suspend fun getUsers(
@Query("page") page: Int,
@Query("size") size: Int = 20
): PagedResponse<User>
@POST("users")
suspend fun createUser(@Body user: CreateUserRequest): User
@Multipart
@POST("upload")
suspend fun uploadFile(
@Part file: MultipartBody.Part,
@Part("description") description: RequestBody
): UploadResponse
}
// 4. 网络状态处理
sealed class NetworkResult<T> {
data class Success<T>(val data: T) : NetworkResult<T>()
data class Error<T>(val message: String, val code: Int? = null) : NetworkResult<T>()
class Loading<T> : NetworkResult<T>()
}
class NetworkRepository(private val apiService: ApiService) {
suspend fun <T> safeApiCall(apiCall: suspend () -> T): NetworkResult<T> {
return try {
val result = apiCall()
NetworkResult.Success(result)
} catch (e: HttpException) {
NetworkResult.Error(
message = e.message ?: "Unknown error",
code = e.code()
)
} catch (e: IOException) {
NetworkResult.Error("Network error: ${e.message}")
} catch (e: Exception) {
NetworkResult.Error("Unexpected error: ${e.message}")
}
}
suspend fun getUser(userId: String): NetworkResult<User> {
return safeApiCall { apiService.getUser(userId) }
}
}这份面试题整理涵盖了2025年Android开发的核心技术栈,包含详细的代码示例和最佳实践。建议根据面试职位的具体要求,重点准备相关技术领域的深度知识。