第一章:Android 系统架构与核心原理

本章深入剖析 Android 系统的整体架构、四大组件、生命周期机制、Intent 通信体系和进程模型,是所有 Android 开发的基础与根基。


📋 章节目录

主题
1.1 Android 系统架构分层
1.2 四大组件详解
1.3 Activity 与 Fragment 完整生命周期
1.4 Intent 机制与组件通信
1.5 Application 类与进程模型
1.6 AndroidManifest 深度解析

1.1 Android 系统架构分层

系统分层全景

复制代码
┌─────────────────────────────────────────────┐
│              Applications(应用层)           │
│   Phone / Settings / Camera / 你的 App      │
├─────────────────────────────────────────────┤
│         Application Framework(框架层)       │
│  Activity Manager / Window Manager /        │
│  Content Providers / View System /          │
│  Package Manager / Notification Manager     │
├─────────────────────────────────────────────┤
│             Libraries + ART(运行时层)        │
│  SQLite / WebKit / OpenGL ES / Media /      │
│  ART(Android Runtime)/ Bionic libc        │
├─────────────────────────────────────────────┤
│          HAL(硬件抽象层)                    │
│  Camera HAL / Audio HAL / Bluetooth HAL     │
├─────────────────────────────────────────────┤
│          Linux Kernel(内核层)               │
│  驱动 / 内存管理 / 进程管理 / 安全 / 电源管理  │
└─────────────────────────────────────────────┘

ART vs Dalvik

特性 Dalvik (Android < 5.0) ART (Android 5.0+)
编译方式 JIT(运行时即时编译) AOT + JIT + PGO
启动速度 快(无需预编译) 安装时预编译,启动更快
运行性能 较低 大幅提升
存储占用 略高(存储 OAT 文件)
GC Stop-The-World 并发、分代 GC

Zygote 进程启动流程

复制代码
init 进程
  └─ Zygote(Java 世界的起点)
       ├─ 预加载 Android Framework 类
       ├─ 预加载常用资源(Drawable、Theme)
       └─ 等待 fork 请求
            ├─ system_server(系统服务进程)
            │    ├─ ActivityManagerService
            │    ├─ WindowManagerService
            │    └─ PackageManagerService
            └─ App 进程(每个 App fork 自 Zygote)

为什么要 fork Zygote?

  • 写时复制(Copy-on-Write):所有 App 共享 Zygote 已加载的内存页
  • 减少每个 App 的启动时间和内存占用

1.2 四大组件详解

Activity

应用的 UI 容器,每个界面对应一个 Activity。

kotlin 复制代码
// Demo: 基础 Activity
class MainActivity : AppCompatActivity() {

    // ViewBinding 推荐方式
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 使用 ViewBinding 替代 findViewById
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 恢复状态
        savedInstanceState?.let {
            val count = it.getInt("count", 0)
            binding.tvCount.text = count.toString()
        }

        binding.btnIncrement.setOnClickListener {
            val current = binding.tvCount.text.toString().toInt()
            binding.tvCount.text = (current + 1).toString()
        }
    }

    // 保存状态(系统回收时)
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putInt("count", binding.tvCount.text.toString().toInt())
    }
}

Service

在后台执行长时间运行任务的组件,无 UI 界面。

kotlin 复制代码
// 前台 Service(用户可见)
class MusicPlayerService : Service() {

    private val binder = MusicBinder()
    private var isPlaying = false

    inner class MusicBinder : Binder() {
        fun getService(): MusicPlayerService = this@MusicPlayerService
    }

    override fun onBind(intent: Intent): IBinder = binder

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        when (intent?.action) {
            ACTION_PLAY -> startPlaying()
            ACTION_PAUSE -> pausePlaying()
            ACTION_STOP -> stopSelf()
        }
        return START_STICKY // 系统杀死后自动重启
    }

    private fun startPlaying() {
        isPlaying = true
        // 创建前台通知(必须,否则 Android 8+ 会被杀死)
        val notification = buildNotification()
        startForeground(NOTIFICATION_ID, notification)
    }

    private fun buildNotification(): Notification {
        val channelId = "music_player"
        return NotificationCompat.Builder(this, channelId)
            .setContentTitle("正在播放")
            .setContentText("My Favorite Song")
            .setSmallIcon(R.drawable.ic_music)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .build()
    }

    private fun pausePlaying() {
        isPlaying = false
    }

    override fun onDestroy() {
        super.onDestroy()
        stopForeground(STOP_FOREGROUND_REMOVE)
    }

    companion object {
        const val ACTION_PLAY = "ACTION_PLAY"
        const val ACTION_PAUSE = "ACTION_PAUSE"
        const val ACTION_STOP = "ACTION_STOP"
        const val NOTIFICATION_ID = 1001
    }
}

BroadcastReceiver

监听系统或 App 广播事件的组件。

kotlin 复制代码
// 静态注册(AndroidManifest,适合接收系统广播)
class BootReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
            // 开机完成,启动服务
            context.startForegroundService(
                Intent(context, MusicPlayerService::class.java)
            )
        }
    }
}

// 动态注册(代码中注册,随 Activity 生命周期)
class NetworkActivity : AppCompatActivity() {

    private val networkReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val isConnected = checkNetworkConnectivity(context)
            updateNetworkUI(isConnected)
        }
    }

    override fun onResume() {
        super.onResume()
        val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
        registerReceiver(networkReceiver, filter)
    }

    override fun onPause() {
        super.onPause()
        unregisterReceiver(networkReceiver) // 必须注销,否则内存泄漏
    }

    // 推荐使用 LocalBroadcastManager 进行应用内通信
    private fun sendLocalBroadcast() {
        val intent = Intent("com.example.CUSTOM_ACTION")
        intent.putExtra("data", "Hello Local Broadcast")
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
    }

    private fun checkNetworkConnectivity(context: Context): Boolean {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        return cm.activeNetworkInfo?.isConnected == true
    }

    private fun updateNetworkUI(connected: Boolean) {
        // 更新 UI
    }
}

ContentProvider

用于跨进程共享数据,提供统一的数据访问接口。

kotlin 复制代码
// 自定义 ContentProvider
class UserContentProvider : ContentProvider() {

    private lateinit var database: UserDatabase

    companion object {
        const val AUTHORITY = "com.example.provider"
        val USERS_URI: Uri = Uri.parse("content://$AUTHORITY/users")

        private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH).apply {
            addURI(AUTHORITY, "users", 1)       // 全部用户
            addURI(AUTHORITY, "users/#", 2)     // 单个用户
        }
    }

    override fun onCreate(): Boolean {
        database = UserDatabase.getInstance(context!!)
        return true
    }

    override fun query(
        uri: Uri, projection: Array<String>?, selection: String?,
        selectionArgs: Array<String>?, sortOrder: String?
    ): Cursor? {
        return when (uriMatcher.match(uri)) {
            1 -> database.userDao().getAllCursor()
            2 -> {
                val userId = ContentUris.parseId(uri)
                database.userDao().getUserByIdCursor(userId)
            }
            else -> throw IllegalArgumentException("Unknown URI: $uri")
        }
    }

    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        val id = database.userDao().insert(values!!.toUser())
        context?.contentResolver?.notifyChange(uri, null)
        return ContentUris.withAppendedId(USERS_URI, id)
    }

    override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<String>?): Int = 0
    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int = 0
    override fun getType(uri: Uri): String? = null
}

1.3 Activity 与 Fragment 完整生命周期

Activity 生命周期

复制代码
         用户打开 App
              ↓
          onCreate()      ← 初始化(只执行一次)
              ↓
          onStart()       ← 可见(不可交互)
              ↓
          onResume()      ← 可见且可交互(前台)
              ↓
    ┌── 用户按 Home / 跳转其他 App
    │         ↓
    │     onPause()      ← 失去焦点(仍可见)
    │         ↓
    │     onStop()       ← 不可见
    │         ↓
    │   onRestart() ─────────────┐
    │         ↑                  │ 返回
    └─────────┘               返回此 Activity
              ↓
         onDestroy()     ← 销毁
kotlin 复制代码
class LifecycleDemo : AppCompatActivity() {
    private val TAG = "LifecycleDemo"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d(TAG, "onCreate: isRecreated=${savedInstanceState != null}")
        // 适合做:初始化 ViewModel、绑定 View、设置点击事件
    }

    override fun onStart() {
        super.onStart()
        Log.d(TAG, "onStart")
        // 适合做:注册 BroadcastReceiver(某些场景)
    }

    override fun onResume() {
        super.onResume()
        Log.d(TAG, "onResume")
        // 适合做:开始动画、恢复传感器、视频播放
    }

    override fun onPause() {
        super.onPause()
        Log.d(TAG, "onPause")
        // 适合做:暂停动画、释放摄像头(注意:方法要快,不能做耗时操作)
    }

    override fun onStop() {
        super.onStop()
        Log.d(TAG, "onStop")
        // 适合做:保存数据草稿、注销 BroadcastReceiver
    }

    override fun onRestart() {
        super.onRestart()
        Log.d(TAG, "onRestart")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "onDestroy")
        // 适合做:释放所有资源
    }
}

Fragment 生命周期(与 Activity 对比)

复制代码
Activity.onCreate()
    ↓
Fragment.onAttach()          ← Fragment 附加到 Activity
Fragment.onCreate()          ← 初始化(无 View)
Fragment.onCreateView()      ← 创建并返回 View
Fragment.onViewCreated()     ← View 已创建,适合初始化 UI ✅
Fragment.onStart()
Fragment.onResume()
    ↓ ... 运行中 ...
Fragment.onPause()
Fragment.onStop()
Fragment.onDestroyView()     ← View 被销毁(Fragment 可能仍存活)
Fragment.onDestroy()
Fragment.onDetach()
kotlin 复制代码
class UserProfileFragment : Fragment(R.layout.fragment_user_profile) {

    // 注意:使用 viewLifecycleOwner 而非 this,避免内存泄漏
    private val viewModel: UserViewModel by viewModels()
    private var _binding: FragmentUserProfileBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentUserProfileBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // ✅ 使用 viewLifecycleOwner 观察 LiveData(不是 this)
        viewModel.user.observe(viewLifecycleOwner) { user ->
            binding.tvName.text = user.name
            binding.tvEmail.text = user.email
        }

        // ✅ 在 lifecycleScope 中启动协程
        viewLifecycleOwner.lifecycleScope.launch {
            viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.uiState.collect { state ->
                    updateUI(state)
                }
            }
        }
    }

    private fun updateUI(state: UserUiState) {
        when (state) {
            is UserUiState.Loading -> binding.progressBar.isVisible = true
            is UserUiState.Success -> {
                binding.progressBar.isVisible = false
                binding.tvName.text = state.user.name
            }
            is UserUiState.Error -> {
                binding.progressBar.isVisible = false
                Snackbar.make(binding.root, state.message, Snackbar.LENGTH_LONG).show()
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null // ✅ 必须清空,防止内存泄漏
    }
}

Activity 启动模式(LaunchMode)

模式 说明 典型场景
standard 每次都新建实例 普通页面
singleTop 栈顶复用(调用 onNewIntent 通知点击
singleTask 栈中唯一实例 主页 / 登录页
singleInstance 独立任务栈 来电界面
kotlin 复制代码
// singleTop:处理通知重复点击
class NotificationActivity : AppCompatActivity() {
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        // 处理新 Intent,而不创建新实例
        val notifId = intent.getIntExtra("notif_id", -1)
        loadNotification(notifId)
    }

    private fun loadNotification(id: Int) { /* ... */ }
}

1.4 Intent 机制与组件通信

显式 Intent vs 隐式 Intent

kotlin 复制代码
// ✅ 显式 Intent(明确指定目标组件)
val explicitIntent = Intent(this, DetailActivity::class.java).apply {
    putExtra("product_id", 1001)
    putExtra("product_name", "Android 深度指南")
}
startActivity(explicitIntent)

// ✅ 隐式 Intent(通过 Action/Category/Data 匹配)
val implicitIntent = Intent(Intent.ACTION_VIEW).apply {
    data = Uri.parse("https://www.example.com")
}
// 先检查是否有应用能处理
if (implicitIntent.resolveActivity(packageManager) != null) {
    startActivity(implicitIntent)
}

// 拨打电话
val callIntent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:10086"))
startActivity(callIntent)

// 分享文本
val shareIntent = Intent.createChooser(
    Intent(Intent.ACTION_SEND).apply {
        type = "text/plain"
        putExtra(Intent.EXTRA_TEXT, "分享这段文字")
    },
    "分享到"
)
startActivity(shareIntent)

ActivityResultLauncher(现代方式替代 onActivityResult)

kotlin 复制代码
class CameraActivity : AppCompatActivity() {

    // ✅ 现代方式:ActivityResultLauncher
    private val takePictureLauncher = registerForActivityResult(
        ActivityResultContracts.TakePicturePreview()
    ) { bitmap ->
        bitmap?.let {
            binding.ivPhoto.setImageBitmap(it)
        }
    }

    private val pickImageLauncher = registerForActivityResult(
        ActivityResultContracts.GetContent()
    ) { uri ->
        uri?.let {
            binding.ivPhoto.setImageURI(it)
        }
    }

    // 自定义 Contract
    private val loginLauncher = registerForActivityResult(
        object : ActivityResultContract<Unit, Boolean>() {
            override fun createIntent(context: Context, input: Unit) =
                Intent(context, LoginActivity::class.java)

            override fun parseResult(resultCode: Int, intent: Intent?) =
                resultCode == RESULT_OK
        }
    ) { isLoggedIn ->
        if (isLoggedIn) {
            loadUserData()
        }
    }

    private fun loadUserData() { /* ... */ }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityCameraBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.btnCamera.setOnClickListener {
            takePictureLauncher.launch(null)
        }

        binding.btnGallery.setOnClickListener {
            pickImageLauncher.launch("image/*")
        }
    }

    private lateinit var binding: ActivityCameraBinding
}

进程间通信(AIDL)

kotlin 复制代码
// IRemoteService.aidl
interface IRemoteService {
    int getPid();
    String getAppName();
    void registerCallback(IRemoteCallback callback);
}

// 服务端实现
class RemoteService : Service() {
    private val binder = object : IRemoteService.Stub() {
        override fun getPid(): Int = Process.myPid()
        override fun getAppName(): String = "Remote Service App"
        override fun registerCallback(callback: IRemoteCallback?) {
            // 注册回调(Binder 传递)
        }
    }

    override fun onBind(intent: Intent): IBinder = binder
}

// 客户端连接
class ClientActivity : AppCompatActivity() {
    private var remoteService: IRemoteService? = null

    private val serviceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName, service: IBinder) {
            remoteService = IRemoteService.Stub.asInterface(service)
            Log.d("Client", "Service PID: ${remoteService?.pid}")
        }

        override fun onServiceDisconnected(name: ComponentName) {
            remoteService = null
        }
    }

    override fun onStart() {
        super.onStart()
        val intent = Intent().apply {
            component = ComponentName("com.example.server", "com.example.server.RemoteService")
        }
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
    }

    override fun onStop() {
        super.onStop()
        unbindService(serviceConnection)
    }
}

1.5 Application 类与进程模型

自定义 Application

kotlin 复制代码
// MyApplication.kt
@HiltAndroidApp // 使用 Hilt 时必须加此注解
class MyApplication : Application() {

    // 进程名(多进程时有多个 Application 实例)
    private val processName: String by lazy {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            getProcessName()
        } else {
            getCurrentProcessNameLegacy()
        }
    }

    override fun onCreate() {
        super.onCreate()

        // 只在主进程初始化
        if (isMainProcess()) {
            initMainProcessComponents()
        }

        // 所有进程都初始化
        initCommonComponents()
    }

    private fun isMainProcess(): Boolean =
        processName == packageName

    private fun initMainProcessComponents() {
        // 初始化崩溃监控
        initCrashReporter()
        // 初始化日志(主进程)
        initLogger()
    }

    private fun initCommonComponents() {
        // 初始化图片加载器等
    }

    private fun initCrashReporter() {
        Thread.setDefaultUncaughtExceptionHandler { thread, throwable ->
            // 全局异常捕获
            Log.e("Crash", "Uncaught exception in thread ${thread.name}", throwable)
            // 写入崩溃日志
            saveCrashLog(throwable)
            // 重启 App 或退出
            exitProcess(1)
        }
    }

    private fun initLogger() {
        if (BuildConfig.DEBUG) {
            Timber.plant(Timber.DebugTree())
        } else {
            Timber.plant(CrashlyticsTree()) // 生产环境上报
        }
    }

    private fun saveCrashLog(throwable: Throwable) { /* ... */ }
    private fun getCurrentProcessNameLegacy(): String = ""
}

Android 进程模型

复制代码
进程优先级(从高到低,越低越容易被系统回收):

1. 前台进程    ← 正在与用户交互的 Activity
2. 可见进程    ← 有 Activity 可见但不在前台
3. 服务进程    ← 运行 Service(如音乐播放)
4. 缓存进程    ← 按返回键退出的 App
kotlin 复制代码
// 防止低内存被杀:使用 onTrimMemory 释放缓存
class MyApplication : Application() {
    override fun onTrimMemory(level: Int) {
        super.onTrimMemory(level)
        when (level) {
            TRIM_MEMORY_UI_HIDDEN -> {
                // App 进入后台,释放 UI 相关缓存
                ImageCache.clearMemoryCache()
            }
            TRIM_MEMORY_RUNNING_LOW,
            TRIM_MEMORY_RUNNING_CRITICAL -> {
                // 内存紧张,释放所有缓存
                ImageCache.clearAllCache()
                DatabaseCache.clear()
            }
        }
    }
}

ANR(Application Not Responding)

kotlin 复制代码
// ANR 触发条件
// - 主线程被阻塞 > 5秒(Activity/BroadcastReceiver)
// - BroadcastReceiver 超过 10 秒
// - Service 超过 20 秒

// ❌ 错误:在主线程做网络请求
class BadActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 这会导致 ANR!
        val result = URL("https://api.example.com/data").readText()
    }
}

// ✅ 正确:使用协程在 IO 线程执行
class GoodActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lifecycleScope.launch {
            val result = withContext(Dispatchers.IO) {
                URL("https://api.example.com/data").readText()
            }
            // 回到主线程更新 UI
            binding.tvResult.text = result
        }
    }

    private lateinit var binding: ActivityGoodBinding
}

1.6 AndroidManifest 深度解析

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.myapp">

    <!-- 权限声明 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.CAMERA" />
    <!-- READ_EXTERNAL_STORAGE 在 Android 13+ 被粒度权限替代 -->
    <uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE"
        android:maxSdkVersion="32" />
    <!-- Android 13+ 精细媒体权限 -->
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />

    <!-- 硬件特性声明 -->
    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" /> <!-- required=false:没有相机的设备也可安装 -->

    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApp"
        android:networkSecurityConfig="@xml/network_security_config"
        tools:targetApi="31">

        <!-- 主 Activity -->
        <activity
            android:name=".ui.main.MainActivity"
            android:exported="true"
            android:launchMode="singleTask"
            android:windowSoftInputMode="adjustResize"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <!-- Deep Link 支持 -->
            <intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data
                    android:scheme="https"
                    android:host="www.example.com"
                    android:pathPrefix="/product/" />
            </intent-filter>
        </activity>

        <!-- 详情 Activity(不需要被外部调用,exported=false)-->
        <activity
            android:name=".ui.detail.DetailActivity"
            android:exported="false"
            android:parentActivityName=".ui.main.MainActivity" /> <!-- 支持返回按钮 -->

        <!-- Service -->
        <service
            android:name=".service.MusicPlayerService"
            android:exported="false"
            android:foregroundServiceType="mediaPlayback" />

        <!-- BroadcastReceiver(静态注册) -->
        <receiver
            android:name=".receiver.BootReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <!-- ContentProvider -->
        <provider
            android:name=".provider.UserContentProvider"
            android:authorities="com.example.myapp.provider"
            android:exported="false"
            android:grantUriPermissions="true" />

        <!-- FileProvider(用于分享文件)-->
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

    </application>
</manifest>
xml 复制代码
<!-- res/xml/network_security_config.xml -->
<!-- 配置网络安全(防止明文传输)-->
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="false">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
    <!-- 开发环境允许本地明文 -->
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">10.0.2.2</domain>
        <domain includeSubdomains="true">localhost</domain>
    </domain-config>
</network-security-config>

Demo 代码:chapter01

kotlin 复制代码
// chapter01/SystemArchDemo.kt
package com.example.androiddemos.chapter01

import android.app.Activity
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class Chapter01DemoActivity : AppCompatActivity() {

    private val TAG = "Chapter01"

    // ---- ActivityResultLauncher ----
    private val requestPermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        permissions.forEach { (permission, granted) ->
            Log.d(TAG, "$permission: ${if (granted) "已授权" else "拒绝"}")
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // 演示协程字典
        demonstrateCoroutineDispatcher()

        // 演示权限请求
        requestPermissionLauncher.launch(
            arrayOf(
                android.Manifest.permission.CAMERA,
                android.Manifest.permission.ACCESS_FINE_LOCATION
            )
        )
    }

    private fun demonstrateCoroutineDispatcher() {
        lifecycleScope.launch {
            Log.d(TAG, "主线程: ${Thread.currentThread().name}")

            val result = withContext(Dispatchers.IO) {
                Log.d(TAG, "IO线程: ${Thread.currentThread().name}")
                // 模拟耗时操作
                Thread.sleep(100)
                "任务完成"
            }

            Log.d(TAG, "回到主线程: $result, 线程: ${Thread.currentThread().name}")
        }
    }

    /**
     * 演示进程生命周期各回调时机
     */
    override fun onLowMemory() {
        super.onLowMemory()
        Log.w(TAG, "系统内存极低!释放所有缓存")
    }

    override fun onTrimMemory(level: Int) {
        super.onTrimMemory(level)
        Log.d(TAG, "onTrimMemory level=$level")
    }
}

章节总结

知识点 必掌握程度 面试频率
Android 分层架构 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
四大组件及使用场景 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
Activity 生命周期 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
Fragment 生命周期 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
Intent(显式/隐式) ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
ActivityResultLauncher ⭐⭐⭐⭐ ⭐⭐⭐
Activity 启动模式 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
Zygote 启动流程 ⭐⭐⭐⭐ ⭐⭐⭐⭐
ANR 原因与避免 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
AndroidManifest 配置 ⭐⭐⭐⭐ ⭐⭐⭐

👉 下一章:第二章------UI 开发与 Jetpack Compose

相关推荐
lI-_-Il2 小时前
适配工具箱:手机里的全能数字瑞士军刀
android·音视频
彳亍走的猪3 小时前
Android 全局防抖/防重复点击
android·java·开发语言
程序员陆业聪3 小时前
Android图片加载框架深度对比:Coil 3.4.0 vs Glide 5.0,该选哪个?
android
seabirdssss3 小时前
Android 模拟器搭建
android·经验分享
CYRUS STUDIO3 小时前
Frida 源码编译全流程:自己动手编译 frida-server
android·安全·逆向
程序员陆业聪3 小时前
Android内存优化:当LeakCanary遇上协程,内存泄漏治理进入新阶段
android
黄林晴3 小时前
解放双手!Android 发布官方 6 大技能,一键搞定迁移、优化、适配
android
FrontAI3 小时前
Next.js从入门到实战保姆级教程:实战项目(上)——全栈博客系统架构与核心功能
开发语言·前端·javascript·react.js·系统架构
REDcker3 小时前
iOS 与 Android:浏览器引擎、WebView 与生态差异概览
android·ios·内核·浏览器·webview