xDocxDoc
AI
前端
后端
iOS
Android
Flutter
AI
前端
后端
iOS
Android
Flutter
  • Android 面试合集

    • Android面试基础篇(一):基础架构与核心组件深度剖析
    • Android中高级面试(二):架构组件与协程实战精要
    • Android中高级面试(三):架构组件与性能优化实战
    • Android 面试(四): Kotlin 基础
    • Android面试(五):深入Kotlin协程
    • Android面试(六):深入Kotlin Flow
    • Android面试(七):Jetpack Compose 深度解析与高频考点
    • Android架构面试(八):从Jetpack到模块化设计
    • Android架构面试(九):Clean Architecture 终极指南
    • Android面试全栈指南:从Kotlin到Jetpack Compose

Android架构面试(八):从Jetpack到模块化设计

🔍 现代Android架构演进史

从早期传统的MVC模式到如今主流的分层架构设计,Android架构经历了三次重大变革:

  1. 原始时代(2015前):Activity/Fragment承担所有逻辑,导致"God Activity"问题
// 典型反例:所有逻辑堆砌在Activity中
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        // UI初始化、网络请求、数据处理全部混杂
        val data = loadDataFromNetwork() // 阻塞主线程
        updateUI(data)
        saveToDatabase(data)
    }
}
  1. 架构组件革命(2017):Google推出Android Architecture Components

    • ViewModel:解决配置变更数据丢失
    • LiveData:生命周期感知的数据持有者
    • Room:SQLite对象映射库
  2. 现代架构(2020+):引入单向数据流(Unidirectional Data Flow)和响应式编程

🧩 核心架构组件深度解析

1. ViewModel 的生命周期管理

class UserViewModel(private val repo: UserRepository) : ViewModel() {
    private val _userData = MutableStateFlow<User?>(null)
    val userData: StateFlow<User?> = _userData.asStateFlow()

    init {
        viewModelScope.launch {
            repo.fetchUser().collect { user ->
                _userData.value = user
            }
        }
    }
}
// 关键特性:
// 1. 使用viewModelScope自动取消协程
// 2. StateFlow替代LiveData实现更纯粹的状态管理

2. LiveData vs Flow 性能对比

特性LiveDataKotlin Flow
生命周期感知✅ 原生支持❌ 需配合LifecycleScope
背压处理❌✅ 丰富操作符
线程控制❌ 主线程限定✅ 灵活调度器
数据重放✅ 最新数据✅ 可配置重放数量

3. Room数据库高级实践

@Dao
interface UserDao {
    @Query("SELECT * FROM user WHERE region = :region")
    fun getUsersByRegion(region: String): Flow<List<User>>

    @Transaction  // 支持复杂事务
    @Query("UPDATE user SET status = :status WHERE id = :userId")
    suspend fun updateUserStatus(userId: String, status: Int)
}

// 使用技巧:
// 1. 结合Flow实现数据库变化实时监听
// 2. 使用@Transaction确保多表操作原子性

🚀 主流架构模式实战

MVVM 最佳实践

// 分层结构示例
class LoginViewModel(
    private val authRepo: AuthRepository
) : ViewModel() {
    // UI状态集中管理
    data class LoginState(
        val isLoading: Boolean = false,
        val error: String? = null,
        val isSuccess: Boolean = false
    )

    private val _state = MutableStateFlow(LoginState())
    val state: StateFlow<LoginState> = _state.asStateFlow()

    fun login(username: String, password: String) {
        viewModelScope.llaunch {
            _state.value = LoginState(isLoading = true)
            try {
                authRepo.login(username, password)
                _state.value = LoginState(isSuccess = true)
            } catch (e: Exception) {
                _state.value = LoginState(error = e.message)
            }
        }
    }
}

MVI 模式实现

sealed class MainIntent {
    object LoadData : MainIntent()
    data class UpdateItem(val id: String) : MainIntent()
}

data class MainState(
    val items: List<Item> = emptyList(),
    val isLoading: Boolean = false
)

class MainViewModel : ViewModel() {
    private val _state = MutableStateFlow(MainState())
    val state: StateFlow<MainState> = _state.asStateFlow()

    fun processIntent(intent: MainIntent) {
        when (intent) {
            is MainIntent.LoadData -> loadData()
            is MainIntent.UpdateItem -> updateItem(intent.id)
        }
    }
}

📦 模块化架构设计

分层模块划分

app/
├── feature-auth/      // 认证模块
├── feature-home/      // 首页模块
├── feature-profile/   // 个人中心
├── core-network/      // 网络核心
├── core-database/     // 数据库核心
└── core-ui/           // UI组件库

模块间通信方案

// 使用Hilt依赖注入实现模块解耦
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
    @Provides
    fun provideRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl("https://api.example.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }
}

// 在feature模块中使用
@AndroidEntryPoint
class UserRepository @Inject constructor(
    private val apiService: ApiService
) { /* ... */ }

🧪 架构测试策略

ViewModel单元测试

@Test
fun `login should update state on success`() = runTest {
    // 1. 创建测试依赖
    val mockRepo = mockk<AuthRepository>()
    coEvery { mockRepo.login(any(), any()) } returns Unit
    
    // 2. 创建ViewModel
    val vm = LoginViewModel(mockRepo)
    
    // 3. 执行操作
    vm.login("test", "password")
    
    // 4. 验证状态变化
    val state = vm.state.first { !it.isLoading }
    assertTrue(state.isSuccess)
}

UI层测试方案

@HiltAndroidTest
class LoginScreenTest {
    @get:Rule
    val hiltRule = HiltAndroidRule(this)

    @Test
    fun display_error_when_login_fails() {
        // 1. 启动Compose测试
        composeTestRule.setContent {
            AppTheme { LoginScreen() }
        }
        
        // 2. 模拟错误状态
        val vm = hiltNavGraphViewModel<LoginViewModel>()
        vm.updateState(LoginState(error = "Invalid credentials"))
        
        // 3. 验证UI显示
        composeTestRule.onNodeWithText("Invalid credentials").assertIsDisplayed()
    }
}

💡 性能优化关键点

  1. 内存优化

    // 使用WeakReference避免内存泄漏
    class ImageLoader(context: Context) {
        private val weakContext = WeakReference(context)
        
        fun load(url: String) {
            weakContext.get()?.let { 
                // 加载图片
            }
        }
    }
  2. 启动速度优化

    <!-- 启动主题优化 -->
    <style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowBackground">@drawable/launch_screen</item>
    </style>
  3. 网络请求优化

    // 使用OkHttp拦截器实现请求缓存
    val client = OkHttpClient.Builder()
        .addInterceptor(CacheInterceptor())
        .cache(Cache(directory, 10 * 1024 * 1024)) // 10MB缓存
        .build()

🌟 架构趋势

  1. Kotlin Multiplatform 跨平台架构

    // 共享业务逻辑模块
    class SharedViewModel {
        fun businessLogic(): String {
            return "Core Logic"
        }
    }
    
    // Android端调用
    class AndroidViewModel : ViewModel() {
        private val shared = SharedViewModel()
        val data = shared.businessLogic()
    }
  2. Jetpack Compose 声明式UI架构

    @Composable
    fun UserProfile(user: User) {
        Column {
            AsyncImage(model = user.avatarUrl) 
            Text(text = user.name, style = MaterialTheme.typography.h5)
            // 状态提升示例
            var expanded by remember { mutableStateOf(false) }
            IconButton(onClick = { expanded = !expanded }) {
                Icon(Icons.Default.MoreVert)
            }
        }
    }
  3. AppStartup优化冷启动

    <!-- 初始化配置优化 -->
    <provider
        android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.androidx-startup"
        android:exported="false">
        <meta-data 
            android:name="com.example.LibraryInitializer"
            android:value="androidx.startup" />
    </provider>

🚨 常见架构陷阱

  1. ViewModel滥用

    // 错误示范:在ViewModel中持有Context
    class WrongViewModel(context: Context) : ViewModel() {
        // Context可能导致内存泄漏
    }
  2. 过度抽象

    // 不必要的接口抽象
    interface UserRepository {
        fun getUser(): User
    }
    
    class UserRepositoryImpl : UserRepository {
        override fun getUser(): User { ... }
    }
    
    // 直接使用具体类更简洁
    class UserRepository {
        fun getUser(): User { ... }
    }
  3. 忽视线程安全

    class UnsafeRepository {
        var data: List<Item> = emptyList()
    
        fun updateData() {
            // 多线程访问可能导致并发问题
            data = fetchData()
        }
    }

📝 总结

核心原则
  • 单一职责:每个组件/类只做一件事
  • 可测试性:依赖注入使测试更简单
  • 生命周期感知:自动管理资源释放
  • 单向数据流:保证状态可预测
技术选型
场景推荐方案
状态管理StateFlow + ViewModel
异步操作Kotlin协程
本地存储Room + Flow
依赖注入Hilt
UI框架Jetpack Compose
性能指标
{
  type: 'radar',
  data: {
    labels: ['启动时间', '内存占用', '帧率', '耗电量', '网络请求'],
    datasets: [{
      label: '架构优化前',
      data: [65, 59, 80, 81, 75],
      fill: true,
      backgroundColor: 'rgba(255, 99, 132, 0.2)'
    }, {
      label: '架构优化后',
      data: [85, 75, 95, 79, 92],
      fill: true,
      backgroundColor: 'rgba(75, 192, 192, 0.2)'
    }]
  }
}

总结

📚 架构设计核心要点

现代Android架构设计已形成以分层解耦为基础、响应式编程为手段、单向数据流为指导原则的标准范式。关键演进体现在:

  1. 关注点分离:Activity/Fragment仅处理UI逻辑,业务逻辑移至ViewModel
  2. 生命周期感知:LiveData/Flow自动管理订阅,避免内存泄漏
  3. 异步处理革命:协程替代Callback/RxJava简化异步代码
  4. 声明式UI:Compose推动UI开发范式转变

🛠️ 建议

  1. 渐进式改造:从新模块开始采用新架构,逐步重构旧代码
  2. 模块化先行:先划分功能模块再实施具体架构模式
  3. 测试驱动:编写ViewModel单元测试保障核心逻辑
  4. 性能监控:集成Profiler持续监控内存/CPU使用
最后更新: 2025/9/29 08:41
Prev
Android面试(七):Jetpack Compose 深度解析与高频考点
Next
Android架构面试(九):Clean Architecture 终极指南