从零到上线:完整Kotlin App开发实战教程【带项目源码】 | 适合初学者与进阶开发者

94 阅读2分钟

在 Kotlin 中开发互联网 App(如社交、电商、资讯类应用)需要结合现代 Android 开发实践、网络通信、数据存储和 UI 设计。以下是完整的开发流程与核心步骤,涵盖从项目初始化到发布的全生命周期。


一、项目初始化与架构设计(有讠果:itazs。fun)

1. 环境准备

  • 安装 Android Studio:最新稳定版(如 Flamingo 或北极狐版本)。

  • 配置 Kotlin 插件:确保项目默认使用 Kotlin(File > New Project > Empty Activity 时勾选 Kotlin)。

  • SDK 与依赖管理

    • 在 build.gradle(Module 级别)中配置依赖:

      kotlin
      plugins {
          id("com.android.application")
          id("org.jetbrains.kotlin.android") // Kotlin 支持
          id("kotlin-kapt") // 注解处理器支持(如 Room、Dagger)
      }
      
      dependencies {
          implementation("androidx.core:core-ktx:1.12.0")
          implementation("androidx.appcompat:appcompat:1.6.1")
          implementation("com.google.android.material:material:1.9.0")
          // 其他依赖...
      }
      

2. 选择架构模式

  • 推荐架构MVI(Model-View-Intent)  或 MVVM(结合 Jetpack Compose)。

  • 核心组件

    • ViewModel:管理 UI 相关数据,处理业务逻辑。
    • Repository:抽象数据层(网络/本地数据库)。
    • UseCase(可选):封装单一职责的业务逻辑。
  • 示例目录结构

    /app
      ├── /data          # 数据库、网络请求、Repository
      ├── /domain        # UseCase、实体类
      ├── /ui            # Activity、Fragment、ViewModel
      └── /di            # 依赖注入(如 Hilt)
    

二、网络通信与数据获取

1. 选择网络库

  • Retrofit + OkHttp(推荐):

    kotlin
    // 定义 API 接口
    interface ApiService {
        @GET("users/{id}")
        suspend fun getUser(@Path("id") userId: String): Response<User>
    }
    
    // 创建 Retrofit 实例
    val retrofit = Retrofit.Builder()
        .baseUrl("https://api.example.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .client(OkHttpClient.Builder().build())
        .build()
    
    val apiService = retrofit.create(ApiService::class.java)
    
  • Ktor(轻量级替代方案):适合纯 Kotlin 多平台项目。

2. 处理异步请求

  • 协程(Coroutines)

    kotlin
    // 在 ViewModel 中调用
    viewModelScope.launch {
        try {
            val response = apiService.getUser("123")
            if (response.isSuccessful) {
                _userLiveData.value = response.body()
            }
        } catch (e: Exception) {
            _errorLiveData.value = "网络请求失败"
        }
    }
    
  • Flow(响应式流):替代 LiveData 的更灵活方案。

3. 数据缓存策略

  • 本地数据库(Room)

    kotlin
    @Database(entities = [User::class], version = 1)
    abstract class AppDatabase : RoomDatabase() {
        abstract fun userDao(): UserDao
    }
    
    // 在 Repository 中结合网络和本地数据
    class UserRepository(private val api: ApiService, private val db: AppDatabase) {
        suspend fun getUser(userId: String): User {
            val cachedUser = db.userDao().getUser(userId)
            if (cachedUser != null) return cachedUser
    
            val response = api.getUser(userId)
            response.body()?.let { db.userDao().insert(it) }
            return response.body()!!
        }
    }
    

三、UI 开发与状态管理

1. 选择 UI 框架

  • Jetpack Compose(推荐):

    kotlin
    @Composable
    fun UserScreen(viewModel: UserViewModel) {
        val user by viewModel.user.observeAsState()
        val error by viewModel.error.observeAsState()
    
        LaunchedEffect(Unit) {
            viewModel.fetchUser("123")
        }
    
        when {
            error != null -> Text(error!!)
            user != null -> Text("用户名: ${user!!.name}")
            else -> CircularProgressIndicator()
        }
    }
    
  • 传统 XML 布局:结合 DataBinding 或 ViewBinding。

2. 状态管理

  • ViewModel + LiveData/Flow

    kotlin
    class UserViewModel(private val repository: UserRepository) : ViewModel() {
        private val _user = MutableLiveData<User?>()
        val user: LiveData<User?> = _user
    
        fun fetchUser(userId: String) {
            viewModelScope.launch {
                _user.value = repository.getUser(userId)
            }
        }
    }
    
  • StateFlow/SharedFlow:更精细的流控制。

3. 导航组件(Navigation)

  • 配置导航图:

    xml
    <!-- navigation.xml -->
    <navigation>
        <fragment
            android:id="@+id/userFragment"
            android:name=".ui.UserFragment"
            android:label="User">
            <argument
                android:name="userId"
                app:argType="string" />
        </fragment>
    </navigation>
    
  • 在 Activity 中设置:

    kotlin
    val navController = findNavController(R.id.nav_host_fragment)
    NavHostFragment.create(R.navigation.nav_graph).also {
        supportFragmentManager.beginTransaction()
            .replace(R.id.container, it)
            .commit()
    }
    

四、依赖注入与测试

1. 依赖注入(Hilt)

  • 配置 Hilt:

    kotlin
    @HiltAndroidApp
    class MyApp : Application()
    
    @Module
    @InstallIn(SingletonComponent::class)
    object AppModule {
        @Provides
        fun provideApiService(): ApiService = Retrofit.Builder()...create()
    }
    
    @AndroidEntryPoint
    class UserViewModel : ViewModel() {
        @Inject lateinit var repository: UserRepository
    }
    

2. 单元测试

  • 测试 ViewModel:

    kotlin
    @Test
    fun `fetchUser success`() = runTest {
        val repository = mock(UserRepository::class.java)
        whenever(repository.getUser("123")).thenReturn(User("Alice"))
    
        val viewModel = UserViewModel(repository)
        viewModel.fetchUser("123")
    
        assertEquals("Alice", viewModel.user.value?.name)
    }
    

3. UI 测试(Espresso)

kotlin
@Test
fun displayUserName() {
    val scenario = launchFragmentInContainer<UserFragment>(
        bundleOf("userId" to "123")
    )
    onView(withText("Alice")).check(matches(isDisplayed()))
}

五、发布与优化

1. 构建与签名

  • 生成签名密钥:

    bash
    keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias
    
  • 在 build.gradle 中配置:

    kotlin
    android {
        signingConfigs {
            release {
                storeFile file("my-release-key.jks")
                storePassword "password"
                keyAlias "my-alias"
                keyPassword "password"
            }
        }
        buildTypes {
            release {
                signingConfig signingConfigs.release
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    

2. 发布到 Google Play

3. 性能优化

  • 启动优化:延迟初始化非关键组件。
  • 内存泄漏检测:使用 LeakCanary。
  • 网络优化:启用 OkHttp 缓存、压缩响应数据。

六、完整代码示例(核心片段)

1. ViewModel 示例

kotlin
class UserViewModel(private val repository: UserRepository) : ViewModel() {
    private val _userState = MutableStateFlow<User?>(null)
    val userState: StateFlow<User?> = _userState

    fun fetchUser(userId: String) {
        viewModelScope.launch {
            _userState.value = repository.getUser(userId)
        }
    }
}

2. Compose UI 示例

kotlin
@Composable
fun UserScreen(viewModel: UserViewModel) {
    val user by viewModel.userState.collectAsState()

    Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
        if (user != null) {
            Text("欢迎, ${user!!.name}")
        } else {
            CircularProgressIndicator()
        }
    }
}

七、关键工具与库推荐

类别工具/库
网络Retrofit, OkHttp, Ktor
数据库Room, SQLDelight
依赖注入Hilt, Koin
响应式编程Coroutines, Flow, LiveData
UIJetpack Compose, XML
测试JUnit, Espresso, MockK
日志Timber, Logcat

通过以上流程,你可以高效地使用 Kotlin 开发一个结构清晰、性能优良的互联网 App。核心原则包括:分层架构响应式编程自动化测试持续优化