第一章: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

相关推荐
千里马学框架5 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台5 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone5 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc5 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo5 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077005 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼5 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone5 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen5 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone5 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui