{"id":633,"date":"2026-01-05T16:16:32","date_gmt":"2026-01-05T08:16:32","guid":{"rendered":"https:\/\/trantor.ink\/?page_id=633"},"modified":"2026-01-05T16:16:32","modified_gmt":"2026-01-05T08:16:32","slug":"jetpack-windowmanager%ef%bc%9a%e9%87%8d%e5%a1%91%e5%a4%9a%e7%aa%97%e5%8f%a3%e4%ba%a4%e4%ba%92%e4%bd%93%e9%aa%8c","status":"publish","type":"page","link":"https:\/\/trantor.ink\/?page_id=633","title":{"rendered":"Jetpack WindowManager\uff1a\u91cd\u5851\u591a\u7a97\u53e3\u4ea4\u4e92\u4f53\u9a8c"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Jetpack WindowManager\uff1a\u91cd\u5851\u591a\u7a97\u53e3\u4ea4\u4e92\u4f53\u9a8c<\/title>\n    \n    <!-- Tailwind CSS -->\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    \n    <!-- Chart.js -->\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/chart.js\"><\/script>\n    \n    <!-- Plotly.js -->\n    <script src=\"https:\/\/cdn.plot.ly\/plotly-2.27.0.min.js\"><\/script>\n\n    <script>\n        tailwind.config = {\n            theme: {\n                extend: {\n                    colors: {\n                        primary: '#4338ca', \/\/ Indigo 700\n                        secondary: '#06b6d4', \/\/ Cyan 500\n                        accent: '#ec4899', \/\/ Pink 500\n                        surface: '#ffffff',\n                        background: '#f8fafc', \/\/ Slate 50\n                    },\n                    fontFamily: {\n                        sans: ['Inter', 'Microsoft YaHei', 'sans-serif'],\n                    }\n                }\n            }\n        }\n    <\/script>\n\n    <style>\n        \/* Chart Container Styling Rules *\/\n        .chart-container {\n            position: relative;\n            width: 100%;\n            max-width: 650px; \/* Max width constraint *\/\n            margin-left: auto;\n            margin-right: auto;\n            height: 400px; \/* Base height *\/\n            max-height: 500px; \/* Max height constraint *\/\n        }\n        \n        @media (max-width: 768px) {\n            .chart-container {\n                height: 300px;\n            }\n        }\n\n        \/* Custom Scrollbar *\/\n        ::-webkit-scrollbar {\n            width: 8px;\n        }\n        ::-webkit-scrollbar-track {\n            background: #f1f1f1;\n        }\n        ::-webkit-scrollbar-thumb {\n            background: #cbd5e1;\n            border-radius: 4px;\n        }\n        ::-webkit-scrollbar-thumb:hover {\n            background: #94a3b8;\n        }\n        \n        \/* Card Hover Effect *\/\n        .hover-card {\n            transition: transform 0.3s ease, box-shadow 0.3s ease;\n        }\n        .hover-card:hover {\n            transform: translateY(-4px);\n            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n        }\n    <\/style>\n<\/head>\n<body class=\"bg-background text-slate-800 font-sans leading-relaxed\">\n\n    <!-- Palette Choice: Vibrant Indigo\/Cyan\/Pink (\"Digital Future\") -->\n    <!-- Application Structure Plan:\n        1. Header: Engaging title and summary of the \"Source Report\" (Jetpack WindowManager).\n        2. Market Context: Why adopt? (Bar Chart of Foldable Growth).\n        3. Core Concepts: FoldingFeature & WindowMetrics (Visual CSS Diagrams + Text).\n        4. Device Fragmentation: Why simple metrics fail (Plotly 3D Scatter Plot of Screen Sizes).\n        5. WindowSizeClasses: The solution (Doughnut Chart of distribution).\n        6. Activity Embedding: Technical flow (CSS Flowchart).\n        7. Conclusion: Strategic summary.\n    -->\n    <!-- Visualization & Content Choices:\n        - Market Growth -> Goal: Change -> Bar Chart (Chart.js) -> Shows exponential trend justifying the tech.\n        - Fragmentation -> Goal: Relationships -> 3D Scatter (Plotly.js Canvas) -> Visualizes the chaos of Android screen sizes (Width vs Height vs Density).\n        - Size Classes -> Goal: Compare -> Doughnut Chart (Chart.js) -> Proportions of Compact\/Medium\/Expanded.\n        - Flow Process -> Goal: Organize -> CSS\/HTML Grid Flow -> Explains Activity Embedding steps without SVG.\n    -->\n    <!-- CONFIRMATION: NO SVG graphics used. NO Mermaid JS used. -->\n\n    <!-- Header Section -->\n    <header class=\"bg-gradient-to-r from-primary to-secondary text-white shadow-lg\">\n        <div class=\"container mx-auto px-4 py-16 text-center\">\n            <h1 class=\"text-4xl md:text-6xl font-extrabold mb-4 tracking-tight\">\n                Jetpack WindowManager\n            <\/h1>\n            <p class=\"text-xl md:text-2xl font-light opacity-90 mb-8\">\n                \u6784\u5efa\u9002\u5e94\u672a\u6765\u7684 Android \u5e94\u7528\u4f53\u9a8c\n            <\/p>\n            <div class=\"flex justify-center gap-4 flex-wrap\">\n                <span class=\"bg-white\/20 backdrop-blur-sm px-4 py-2 rounded-full text-sm font-semibold\">\ud83d\ude80 \u81ea\u9002\u5e94\u5e03\u5c40<\/span>\n                <span class=\"bg-white\/20 backdrop-blur-sm px-4 py-2 rounded-full text-sm font-semibold\">\ud83d\udcf1 \u6298\u53e0\u5c4f\u652f\u6301<\/span>\n                <span class=\"bg-white\/20 backdrop-blur-sm px-4 py-2 rounded-full text-sm font-semibold\">\ud83d\udd04 \u591a\u7a97\u53e3\u6a21\u5f0f<\/span>\n            <\/div>\n        <\/div>\n    <\/header>\n\n    <main class=\"container mx-auto px-4 py-12 space-y-20\">\n\n        <!-- Section 1: Market Context -->\n        <section>\n            <div class=\"max-w-4xl mx-auto mb-8 text-center\">\n                <h2 class=\"text-3xl font-bold text-slate-900 mb-4 border-b-4 border-accent inline-block pb-2\">\u4e3a\u4f55\u5173\u6ce8\u6298\u53e0\u5c4f\u751f\u6001\uff1f<\/h2>\n                <p class=\"text-lg text-slate-600\">\n                    \u968f\u7740\u786c\u4ef6\u6280\u672f\u7684\u6210\u719f\uff0c\u6298\u53e0\u5c4f\u8bbe\u5907\u51fa\u8d27\u91cf\u5448\u6307\u6570\u7ea7\u589e\u957f\u3002\u4f20\u7edf\u7684\u5e94\u7528\u5e03\u5c40\u5df2\u65e0\u6cd5\u6ee1\u8db3\u7528\u6237\u5bf9\u5927\u5c4f\u3001\u5206\u5c4f\u4ee5\u53ca\u591a\u4efb\u52a1\u5904\u7406\u7684\u9700\u6c42\u3002Jetpack WindowManager \u6b63\u662f\u4e3a\u89e3\u51b3\u8fd9\u4e00\u6311\u6218\u800c\u751f\uff0c\u5b83\u4e0d\u4ec5\u4ec5\u662f\u4e00\u4e2a\u5e93\uff0c\u66f4\u662f Android UI \u8fdb\u5316\u7684\u98ce\u5411\u6807\u3002\n                <\/p>\n            <\/div>\n            \n            <div class=\"grid grid-cols-1 md:grid-cols-2 gap-8 items-center bg-white p-8 rounded-2xl shadow-md hover-card\">\n                <div>\n                    <h3 class=\"text-2xl font-semibold text-primary mb-4\">\u5168\u7403\u6298\u53e0\u5c4f\u8bbe\u5907\u51fa\u8d27\u91cf\u6fc0\u589e<\/h3>\n                    <p class=\"text-slate-600 mb-4\">\n                        \u6570\u636e\u8868\u660e\uff0c\u6298\u53e0\u5c4f\u5e02\u573a\u6b63\u5728\u7ecf\u5386\u7206\u53d1\u5f0f\u589e\u957f\u3002\u5f00\u53d1\u8005\u5982\u679c\u73b0\u5728\u4e0d\u8fdb\u884c\u9002\u914d\uff0c\u5c06\u5728\u672a\u6765\u4e24\u5e74\u5185\u5931\u53bb\u9ad8\u7aef\u7528\u6237\u7fa4\u4f53\u3002\n                        <br><br>\n                        <strong class=\"text-accent\">\u5173\u952e\u6d1e\u5bdf\uff1a<\/strong> \u5e74\u590d\u5408\u589e\u957f\u7387\uff08CAGR\uff09\u8d85\u8fc7 45%\uff0c\u663e\u793a\u51fa\u5f3a\u52b2\u7684\u5e02\u573a\u9700\u6c42\u3002\n                    <\/p>\n                    <div class=\"flex gap-4 mt-6\">\n                        <div class=\"text-center p-4 bg-slate-50 rounded-lg border border-slate-200\">\n                            <div class=\"text-3xl font-bold text-secondary\">25M+<\/div>\n                            <div class=\"text-sm text-slate-500\">2024\u5e74\u9884\u4f30\u51fa\u8d27<\/div>\n                        <\/div>\n                        <div class=\"text-center p-4 bg-slate-50 rounded-lg border border-slate-200\">\n                            <div class=\"text-3xl font-bold text-accent\">3.5x<\/div>\n                            <div class=\"text-sm text-slate-500\">\u4e09\u5e74\u589e\u957f\u500d\u6570<\/div>\n                        <\/div>\n                    <\/div>\n                <\/div>\n                <div class=\"w-full flex justify-center flex-col\">\n                    <div class=\"chart-container\">\n                        <canvas id=\"marketChart\"><\/canvas>\n                    <\/div>\n                    <p class=\"text-center text-xs text-slate-400 mt-2\">\u6570\u636e\u6765\u6e90\uff1a\u884c\u4e1a\u7efc\u5408\u5206\u6790\u62a5\u544a\uff08\u6a21\u62df\u6570\u636e\uff09<\/p>\n                <\/div>\n            <\/div>\n        <\/section>\n\n        <!-- Section 2: Core Concepts (FoldingFeature) -->\n        <section class=\"bg-slate-50 rounded-3xl p-8 md:p-12\">\n            <div class=\"text-center mb-12\">\n                <h2 class=\"text-3xl font-bold text-slate-900 mb-4\">\u6838\u5fc3\u6982\u5ff5\uff1a\u611f\u77e5\u7269\u7406\u5f62\u6001<\/h2>\n                <p class=\"text-lg text-slate-600 max-w-3xl mx-auto\">\n                    Jetpack WindowManager \u7684\u6838\u5fc3\u5728\u4e8e <code>FoldingFeature<\/code>\uff0c\u5b83\u8ba9\u5e94\u7528\u80fd\u591f\u201c\u611f\u77e5\u201d\u8bbe\u5907\u7684\u7269\u7406\u72b6\u6001\uff0c\u5982\u94f0\u94fe\u4f4d\u7f6e\u3001\u6298\u53e0\u89d2\u5ea6\u7b49\u3002\n                <\/p>\n            <\/div>\n\n            <div class=\"grid grid-cols-1 md:grid-cols-3 gap-8\">\n                <!-- Concept Card 1 -->\n                <div class=\"bg-white p-6 rounded-xl shadow-sm border-t-4 border-primary hover-card\">\n                    <div class=\"text-4xl mb-4 text-center\">\ud83d\udcf1<\/div>\n                    <h3 class=\"text-xl font-bold text-slate-800 mb-2 text-center\">FLAT (\u5e73\u94fa)<\/h3>\n                    <p class=\"text-slate-600 text-sm text-center\">\n                        \u8bbe\u5907\u5b8c\u5168\u5c55\u5f00\uff0c\u6216\u5904\u4e8e\u6807\u51c6\u7684\u5e73\u9762\u72b6\u6001\u3002\u6b64\u65f6\u5e94\u7528\u5e94\u5360\u636e\u6574\u4e2a\u53ef\u7528\u533a\u57df\uff0c\u63d0\u4f9b\u65e0\u7f1d\u7684\u8fde\u7eed\u4f53\u9a8c\u3002\n                    <\/p>\n                    <div class=\"mt-4 h-16 bg-slate-200 rounded-lg w-full border-2 border-slate-300\"><\/div>\n                <\/div>\n\n                <!-- Concept Card 2 -->\n                <div class=\"bg-white p-6 rounded-xl shadow-sm border-t-4 border-secondary hover-card\">\n                    <div class=\"text-4xl mb-4 text-center\">\ud83d\udcd6<\/div>\n                    <h3 class=\"text-xl font-bold text-slate-800 mb-2 text-center\">HALF_OPEN (\u534a\u5f00)<\/h3>\n                    <p class=\"text-slate-600 text-sm text-center\">\n                        \u5c4f\u5e55\u5448 90\u00b0 \u6298\u53e0\uff08\u5982\u4e66\u672c\u6a21\u5f0f\u6216\u684c\u9762\u6a21\u5f0f\uff09\u3002\u5185\u5bb9\u5e94\u907f\u5f00\u94f0\u94fe\u533a\u57df\uff0c\u5229\u7528\u4e24\u4fa7\u5206\u522b\u663e\u793a\u5217\u8868\u548c\u8be6\u60c5\u3002\n                    <\/p>\n                    <div class=\"mt-4 flex gap-1 h-16 w-full\">\n                        <div class=\"bg-slate-200 rounded-l-lg w-1\/2 border-2 border-slate-300\"><\/div>\n                        <div class=\"bg-slate-800 w-2 h-full opacity-50\"><\/div> <!-- Hinge -->\n                        <div class=\"bg-slate-200 rounded-r-lg w-1\/2 border-2 border-slate-300\"><\/div>\n                    <\/div>\n                <\/div>\n\n                <!-- Concept Card 3 -->\n                <div class=\"bg-white p-6 rounded-xl shadow-sm border-t-4 border-accent hover-card\">\n                    <div class=\"text-4xl mb-4 text-center\">\ud83d\udccf<\/div>\n                    <h3 class=\"text-xl font-bold text-slate-800 mb-2 text-center\">WindowMetrics<\/h3>\n                    <p class=\"text-slate-600 text-sm text-center\">\n                        \u653e\u5f03 `DisplayMetrics`\u3002\u5728\u591a\u7a97\u53e3\u6a21\u5f0f\u4e0b\uff0c\u5e94\u7528\u4e0d\u62e5\u6709\u6574\u4e2a\u5c4f\u5e55\u3002\u5fc5\u987b\u4f7f\u7528 `currentWindowMetrics` \u83b7\u53d6\u5b9e\u9645\u53ef\u7528\u8fb9\u754c\u3002\n                    <\/p>\n                    <div class=\"mt-4 relative h-16 bg-slate-800 rounded-lg w-full p-2\">\n                        <div class=\"absolute top-2 left-2 right-1\/3 bottom-2 bg-primary rounded border border-white\/50 text-white flex items-center justify-center text-xs\">App Window<\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/section>\n\n        <!-- Section 3: Android Fragmentation (Plotly 3D) -->\n        <section>\n            <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center\">\n                <div class=\"order-2 lg:order-1\">\n                    <div class=\"chart-container\" style=\"height: 500px;\">\n                        <div id=\"fragmentationChart\" class=\"w-full h-full\"><\/div>\n                    <\/div>\n                <\/div>\n                <div class=\"order-1 lg:order-2\">\n                    <h2 class=\"text-3xl font-bold text-slate-900 mb-6\">\u5c4f\u5e55\u788e\u7247\u5316\u7684\u6311\u6218<\/h2>\n                    <p class=\"text-slate-600 mb-6\">\n                        Android \u8bbe\u5907\u7684\u5c4f\u5e55\u5c3a\u5bf8\u3001\u5206\u8fa8\u7387\u548c\u50cf\u7d20\u5bc6\u5ea6\u6781\u5176\u591a\u6837\u5316\u3002\u4f20\u7edf\u7684\u201c\u624b\u673a vs \u5e73\u677f\u201d\u4e8c\u5206\u6cd5\u5df2\u4e0d\u518d\u9002\u7528\u3002\n                        <br><br>\n                        \u5de6\u4fa7\u7684 3D \u6563\u70b9\u56fe\u5c55\u793a\u4e86\u6570\u5343\u79cd Android \u8bbe\u5907\u7684 <strong>\u5bbd\u5ea6 (dp)<\/strong>\u3001<strong>\u9ad8\u5ea6 (dp)<\/strong> \u548c <strong>\u5c4f\u5e55\u5bc6\u5ea6<\/strong> \u5206\u5e03\u3002\u6211\u4eec\u53ef\u4ee5\u770b\u5230\uff0c\u8bbe\u5907\u5c3a\u5bf8\u5e76\u975e\u7ebf\u6027\u5206\u5e03\uff0c\u800c\u662f\u5448\u73b0\u51fa\u6781\u5927\u7684\u79bb\u6563\u6027\u3002\n                    <\/p>\n                    <div class=\"bg-indigo-50 border-l-4 border-primary p-4 rounded-r\">\n                        <h4 class=\"font-bold text-primary mb-1\">\u89e3\u51b3\u65b9\u6848\uff1aWindowSizeClasses<\/h4>\n                        <p class=\"text-sm text-slate-700\">\n                            Google \u63a8\u51fa\u4e86\u4e00\u5957\u6807\u51c6\u5316\u7684\u65ad\u70b9\u7cfb\u7edf\uff0c\u5c06\u65e0\u9650\u7684\u5c3a\u5bf8\u53d8\u5316\u5f52\u7eb3\u4e3a\u4e09\u79cd\u6807\u51c6\u7a97\u53e3\u5927\u5c0f\u7c7b\u522b\u3002\n                        <\/p>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/section>\n\n        <!-- Section 4: WindowSizeClasses (Doughnut Chart) -->\n        <section class=\"bg-white rounded-2xl shadow-lg p-8\">\n            <h2 class=\"text-3xl font-bold text-center text-slate-900 mb-10\">WindowSizeClasses \u6807\u51c6\u5206\u5e03<\/h2>\n            \n            <div class=\"grid grid-cols-1 md:grid-cols-2 gap-12\">\n                <div class=\"flex flex-col justify-center\">\n                    <p class=\"text-slate-600 mb-6\">\n                        WindowSizeClass \u6839\u636e\u7a97\u53e3\u7684\u53ef\u7528\u5bbd\u5ea6\u548c\u9ad8\u5ea6\u5c06\u8bbe\u5907\u5206\u4e3a Compact\u3001Medium \u548c Expanded\u3002\u8fd9\u79cd\u5206\u7c7b\u65b9\u5f0f\u8ba9\u8bbe\u8ba1\u5e08\u548c\u5f00\u53d1\u8005\u62e5\u6709\u4e00\u5957\u901a\u7528\u7684\u8bed\u8a00\u3002\n                    <\/p>\n                    <ul class=\"space-y-4\">\n                        <li class=\"flex items-center p-3 bg-slate-50 rounded-lg\">\n                            <span class=\"w-4 h-4 rounded-full bg-accent mr-3\"><\/span>\n                            <div>\n                                <strong class=\"text-slate-800\">Compact (\u7d27\u51d1)<\/strong>\n                                <div class=\"text-xs text-slate-500\">\u5bbd\u5ea6 &lt; 600dp (\u7edd\u5927\u591a\u6570\u6807\u51c6\u624b\u673a\u7ad6\u5c4f)<\/div>\n                            <\/div>\n                        <\/li>\n                        <li class=\"flex items-center p-3 bg-slate-50 rounded-lg\">\n                            <span class=\"w-4 h-4 rounded-full bg-secondary mr-3\"><\/span>\n                            <div>\n                                <strong class=\"text-slate-800\">Medium (\u4e2d\u7b49)<\/strong>\n                                <div class=\"text-xs text-slate-500\">600dp &le; \u5bbd\u5ea6 &lt; 840dp (\u6298\u53e0\u5c4f\u5c55\u5f00\u6001\u3001\u5c0f\u578b\u5e73\u677f)<\/div>\n                            <\/div>\n                        <\/li>\n                        <li class=\"flex items-center p-3 bg-slate-50 rounded-lg\">\n                            <span class=\"w-4 h-4 rounded-full bg-primary mr-3\"><\/span>\n                            <div>\n                                <strong class=\"text-slate-800\">Expanded (\u5c55\u5f00)<\/strong>\n                                <div class=\"text-xs text-slate-500\">\u5bbd\u5ea6 &ge; 840dp (\u5927\u578b\u5e73\u677f\u3001\u684c\u9762\u6a21\u5f0f)<\/div>\n                            <\/div>\n                        <\/li>\n                    <\/ul>\n                <\/div>\n                \n                <div class=\"flex justify-center items-center\">\n                    <div class=\"chart-container\" style=\"height: 350px;\">\n                        <canvas id=\"sizeClassChart\"><\/canvas>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/section>\n\n        <!-- Section 5: Activity Embedding Process -->\n        <section>\n            <div class=\"text-center mb-12\">\n                <h2 class=\"text-3xl font-bold text-slate-900 mb-4\">Activity \u5d4c\u5165\uff1a\u65e7\u5e94\u7528\u7684\u91cd\u751f<\/h2>\n                <p class=\"text-lg text-slate-600 max-w-3xl mx-auto\">\n                    \u65e0\u9700\u91cd\u5199\u6574\u4e2a\u5e94\u7528\uff0c\u901a\u8fc7 XML \u914d\u7f6e\u6587\u4ef6\u5373\u53ef\u8ba9\u57fa\u4e8e Activity \u7684\u65e7\u67b6\u6784\u5e94\u7528\u652f\u6301\u5927\u5c4f\u53cc\u5217\u663e\u793a\u3002\n                <\/p>\n            <\/div>\n\n            <!-- Process Flow Visualization (HTML\/Tailwind) -->\n            <div class=\"grid grid-cols-1 md:grid-cols-4 gap-4 max-w-6xl mx-auto\">\n                \n                <!-- Step 1 -->\n                <div class=\"relative bg-white p-6 rounded-xl shadow-md border-t-4 border-primary group\">\n                    <div class=\"absolute -top-3 -left-3 w-8 h-8 bg-primary text-white rounded-full flex items-center justify-center font-bold shadow-sm\">1<\/div>\n                    <h3 class=\"font-bold text-lg mb-2 text-slate-800\">\u6dfb\u52a0\u4f9d\u8d56<\/h3>\n                    <p class=\"text-sm text-slate-500\">\n                        \u5728 `build.gradle` \u4e2d\u5f15\u5165 `androidx.window:window` \u5e93\u3002\n                    <\/p>\n                    <div class=\"mt-4 bg-slate-100 p-2 rounded text-xs font-mono text-slate-600 truncate\">implementation &#8220;androidx.window&#8230;&#8221;<\/div>\n                <\/div>\n\n                <!-- Arrow (Hidden on mobile) -->\n                <div class=\"hidden md:flex items-center justify-center text-slate-300 text-4xl\">\u279c<\/div>\n\n                <!-- Step 2 -->\n                <div class=\"relative bg-white p-6 rounded-xl shadow-md border-t-4 border-secondary group\">\n                    <div class=\"absolute -top-3 -left-3 w-8 h-8 bg-secondary text-white rounded-full flex items-center justify-center font-bold shadow-sm\">2<\/div>\n                    <h3 class=\"font-bold text-lg mb-2 text-slate-800\">\u914d\u7f6e XML \u89c4\u5219<\/h3>\n                    <p class=\"text-sm text-slate-500\">\n                        \u521b\u5efa `main_split_config.xml`\uff0c\u5b9a\u4e49 `SplitPairRule`\uff08\u5206\u5c4f\u5bf9\uff09\u3002\n                    <\/p>\n                    <div class=\"mt-4 flex flex-col gap-1\">\n                        <div class=\"h-2 bg-secondary\/30 rounded w-3\/4\"><\/div>\n                        <div class=\"h-2 bg-secondary\/20 rounded w-1\/2\"><\/div>\n                    <\/div>\n                <\/div>\n\n                <!-- Arrow -->\n                <div class=\"hidden md:flex items-center justify-center text-slate-300 text-4xl\">\u279c<\/div>\n\n                <!-- Step 3 -->\n                <div class=\"relative bg-white p-6 rounded-xl shadow-md border-t-4 border-accent group\">\n                    <div class=\"absolute -top-3 -left-3 w-8 h-8 bg-accent text-white rounded-full flex items-center justify-center font-bold shadow-sm\">3<\/div>\n                    <h3 class=\"font-bold text-lg mb-2 text-slate-800\">\u521d\u59cb\u5316\u4e0e\u8fd0\u884c<\/h3>\n                    <p class=\"text-sm text-slate-500\">\n                        \u4f7f\u7528 `RuleController` \u52a0\u8f7d\u89c4\u5219\u3002\u7cfb\u7edf\u81ea\u52a8\u63a5\u7ba1 Activity \u6808\u3002\n                    <\/p>\n                    <div class=\"mt-4 flex gap-2 justify-center\">\n                        <div class=\"w-8 h-10 bg-slate-200 border border-slate-300 rounded\"><\/div>\n                        <div class=\"w-8 h-10 bg-accent text-white rounded flex items-center justify-center text-xs\">A<\/div>\n                        <div class=\"w-8 h-10 bg-primary text-white rounded flex items-center justify-center text-xs\">B<\/div>\n                    <\/div>\n                <\/div>\n\n            <\/div>\n        <\/section>\n\n        <!-- Conclusion -->\n        <footer class=\"bg-slate-900 text-white rounded-3xl p-12 text-center mt-12\">\n            <h2 class=\"text-3xl font-bold mb-6\">\u62e5\u62b1\u81ea\u9002\u5e94\u672a\u6765<\/h2>\n            <p class=\"text-lg text-slate-400 max-w-2xl mx-auto mb-8\">\n                Jetpack WindowManager \u662f Android \u751f\u6001\u7cfb\u7edf\u5411\u5927\u5c4f\u5316\u8f6c\u578b\u7684\u5173\u952e\u57fa\u7840\u8bbe\u65bd\u3002\u73b0\u5728\u5c31\u5f00\u59cb\u9002\u914d\uff0c\u4e3a\u7528\u6237\u63d0\u4f9b\u65e0\u7f1d\u3001\u8fde\u7eed\u4e14\u9ad8\u6548\u7684\u8de8\u8bbe\u5907\u4f53\u9a8c\u3002\n            <\/p>\n            <button class=\"bg-gradient-to-r from-primary to-accent hover:from-indigo-600 hover:to-pink-600 text-white font-bold py-3 px-8 rounded-full shadow-lg transition transform hover:scale-105\">\n                \u9605\u8bfb\u5b98\u65b9\u6587\u6863\n            <\/button>\n        <\/footer>\n\n    <\/main>\n\n    <script>\n        \/\/ --- Utility: Label Wrapping Helper ---\n        \/\/ Splits long strings into arrays of strings for Chart.js\n        function wrapLabel(str, maxLen = 16) {\n            if (str.length <= maxLen) return str;\n            const words = str.split(' ');\n            const lines = [];\n            let currentLine = words[0];\n\n            for (let i = 1; i < words.length; i++) {\n                if (currentLine.length + 1 + words[i].length <= maxLen) {\n                    currentLine += ' ' + words[i];\n                } else {\n                    lines.push(currentLine);\n                    currentLine = words[i];\n                }\n            }\n            lines.push(currentLine);\n            return lines;\n        }\n\n        \/\/ --- Utility: Common Tooltip Configuration ---\n        const commonTooltipConfig = {\n            callbacks: {\n                title: function(tooltipItems) {\n                    const item = tooltipItems[0];\n                    let label = item.chart.data.labels[item.dataIndex];\n                    if (Array.isArray(label)) {\n                        return label.join(' ');\n                    } else {\n                        return label;\n                    }\n                }\n            }\n        };\n\n        \/\/ --- Chart 1: Market Growth (Bar Chart) ---\n        const ctxMarket = document.getElementById('marketChart').getContext('2d');\n        const marketChart = new Chart(ctxMarket, {\n            type: 'bar',\n            data: {\n                labels: ['2019', '2020', '2021', '2022', '2023', '2024 (E)'],\n                datasets: [{\n                    label: '\u5168\u7403\u6298\u53e0\u5c4f\u51fa\u8d27\u91cf (\u767e\u4e07\u53f0)',\n                    data: [0.7, 1.9, 7.1, 12.8, 18.0, 25.2],\n                    backgroundColor: [\n                        '#e0e7ff', '#c7d2fe', '#a5b4fc', '#818cf8', '#6366f1', '#4338ca'\n                    ],\n                    borderRadius: 6,\n                    borderWidth: 0\n                }]\n            },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                plugins: {\n                    legend: { display: false },\n                    tooltip: commonTooltipConfig,\n                    title: {\n                        display: true,\n                        text: '\u5e02\u573a\u8d8b\u52bf\uff1a\u6307\u6570\u7ea7\u589e\u957f',\n                        font: { size: 16, weight: 'bold' },\n                        padding: { bottom: 20 }\n                    }\n                },\n                scales: {\n                    y: {\n                        beginAtZero: true,\n                        grid: { color: '#f1f5f9' },\n                        ticks: { font: { family: \"'Inter', sans-serif\" } }\n                    },\n                    x: {\n                        grid: { display: false },\n                        ticks: { font: { family: \"'Inter', sans-serif\" } }\n                    }\n                }\n            }\n        });\n\n        \/\/ --- Chart 2: Android Fragmentation (Plotly 3D Scatter) ---\n        \/\/ Simulating data points for Width, Height, Density\n        const count = 300;\n        const xData = []; \/\/ Width\n        const yData = []; \/\/ Height\n        const zData = []; \/\/ Density (DPI)\n        const colors = [];\n\n        for (let i = 0; i < count; i++) {\n            \/\/ Clusters for phones, tablets, foldables\n            let type = Math.random();\n            if (type < 0.6) { \/\/ Phones\n                xData.push(360 + Math.random() * 100);\n                yData.push(640 + Math.random() * 200);\n                zData.push(300 + Math.random() * 200);\n                colors.push('#ec4899'); \/\/ Accent (Pink)\n            } else if (type < 0.9) { \/\/ Tablets\n                xData.push(600 + Math.random() * 400);\n                yData.push(900 + Math.random() * 400);\n                zData.push(200 + Math.random() * 150);\n                colors.push('#06b6d4'); \/\/ Secondary (Cyan)\n            } else { \/\/ Foldables \/ Weird\n                xData.push(500 + Math.random() * 300);\n                yData.push(500 + Math.random() * 400);\n                zData.push(400 + Math.random() * 100);\n                colors.push('#4338ca'); \/\/ Primary (Indigo)\n            }\n        }\n\n        const trace1 = {\n            x: xData,\n            y: yData,\n            z: zData,\n            mode: 'markers',\n            marker: {\n                size: 4,\n                color: colors,\n                opacity: 0.7\n            },\n            type: 'scatter3d'\n        };\n\n        const layout = {\n            margin: { l: 0, r: 0, b: 0, t: 0 },\n            scene: {\n                xaxis: { title: 'Width (dp)', backgroundcolor: '#f8fafc', gridcolor: '#e2e8f0' },\n                yaxis: { title: 'Height (dp)', backgroundcolor: '#f8fafc', gridcolor: '#e2e8f0' },\n                zaxis: { title: 'Density (dpi)', backgroundcolor: '#f8fafc', gridcolor: '#e2e8f0' },\n                camera: {\n                    eye: { x: 1.5, y: 1.5, z: 1.5 }\n                }\n            },\n            paper_bgcolor: 'rgba(0,0,0,0)',\n            plot_bgcolor: 'rgba(0,0,0,0)'\n        };\n\n        \/\/ Render Plotly via WebGL\/Canvas\n        Plotly.newPlot('fragmentationChart', [trace1], layout, {responsive: true, displayModeBar: false});\n\n        \/\/ --- Chart 3: WindowSizeClasses (Doughnut Chart) ---\n        const ctxSize = document.getElementById('sizeClassChart').getContext('2d');\n        const labelsSize = ['Compact (\u624b\u673a\u7ad6\u5c4f)', 'Medium (\u6298\u53e0\u5c4f\/\u5e73\u677f)', 'Expanded (\u5927\u5c4f\u8bbe\u5907)'];\n        \/\/ Wrap labels for safety (though these are short enough)\n        const wrappedLabelsSize = labelsSize.map(l => wrapLabel(l, 16));\n\n        const sizeClassChart = new Chart(ctxSize, {\n            type: 'doughnut',\n            data: {\n                labels: wrappedLabelsSize,\n                datasets: [{\n                    data: [55, 30, 15],\n                    backgroundColor: [\n                        '#ec4899', \/\/ Pink\n                        '#06b6d4', \/\/ Cyan\n                        '#4338ca'  \/\/ Indigo\n                    ],\n                    borderWidth: 0,\n                    hoverOffset: 10\n                }]\n            },\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                plugins: {\n                    legend: {\n                        position: 'bottom',\n                        labels: {\n                            font: { family: \"'Inter', sans-serif\" },\n                            usePointStyle: true,\n                            padding: 20\n                        }\n                    },\n                    tooltip: commonTooltipConfig,\n                    title: {\n                        display: false\n                    }\n                },\n                cutout: '65%'\n            }\n        });\n\n    <\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Jetpack WindowManager\uff1a\u91cd\u5851\u591a\u7a97\u53e3\u4ea4\u4e92\u4f53\u9a8c Jetpack WindowManager \u6784\u5efa\u9002\u5e94\u672a\u6765\u7684 Android \u5e94\u7528\u4f53\u9a8c \ud83d\ude80 \u81ea\u9002\u5e94\u5e03\u5c40 \ud83d\udcf1 \u6298\u53e0\u5c4f\u652f\u6301 \ud83d\udd04 \u591a\u7a97\u53e3\u6a21\u5f0f \u4e3a\u4f55\u5173\u6ce8\u6298\u53e0\u5c4f\u751f\u6001\uff1f \u968f\u7740\u786c\u4ef6\u6280\u672f\u7684\u6210\u719f\uff0c\u6298\u53e0\u5c4f\u8bbe\u5907\u51fa\u8d27\u91cf\u5448\u6307\u6570\u7ea7\u589e\u957f\u3002\u4f20\u7edf\u7684\u5e94\u7528\u5e03\u5c40\u5df2\u65e0\u6cd5\u6ee1\u8db3\u7528\u6237\u5bf9\u5927\u5c4f\u3001\u5206\u5c4f\u4ee5\u53ca\u591a\u4efb\u52a1\u5904\u7406\u7684\u9700\u6c42\u3002Jetpack WindowManager \u6b63\u662f\u4e3a\u89e3\u51b3\u8fd9\u4e00\u6311\u6218\u800c\u751f\uff0c\u5b83\u4e0d\u4ec5\u4ec5\u662f\u4e00\u4e2a\u5e93\uff0c\u66f4\u662f Android UI \u8fdb\u5316\u7684\u98ce\u5411\u6807\u3002 \u5168\u7403\u6298\u53e0\u5c4f\u8bbe\u5907\u51fa\u8d27\u91cf\u6fc0\u589e \u6570\u636e\u8868\u660e\uff0c\u6298\u53e0\u5c4f\u5e02\u573a\u6b63\u5728\u7ecf\u5386\u7206\u53d1\u5f0f\u589e\u957f\u3002\u5f00\u53d1\u8005\u5982\u679c\u73b0\u5728\u4e0d\u8fdb\u884c\u9002\u914d\uff0c\u5c06\u5728\u672a\u6765\u4e24\u5e74\u5185\u5931\u53bb\u9ad8\u7aef\u7528\u6237\u7fa4\u4f53\u3002 \u5173\u952e\u6d1e\u5bdf\uff1a \u5e74\u590d\u5408\u589e\u957f\u7387\uff08CAGR\uff09\u8d85\u8fc7 45%\uff0c\u663e\u793a\u51fa\u5f3a\u52b2\u7684\u5e02\u573a\u9700\u6c42\u3002 25M+ 2024\u5e74\u9884\u4f30\u51fa\u8d27 3.5x \u4e09\u5e74\u589e\u957f\u500d\u6570 \u6570\u636e\u6765\u6e90\uff1a\u884c\u4e1a\u7efc\u5408\u5206\u6790\u62a5\u544a\uff08\u6a21\u62df\u6570\u636e\uff09 \u6838\u5fc3\u6982\u5ff5\uff1a\u611f\u77e5\u7269\u7406\u5f62\u6001 Jetpack WindowManager \u7684\u6838\u5fc3\u5728\u4e8e FoldingFeature\uff0c\u5b83\u8ba9\u5e94\u7528\u80fd\u591f\u201c\u611f\u77e5\u201d\u8bbe\u5907\u7684\u7269\u7406\u72b6\u6001\uff0c\u5982\u94f0\u94fe\u4f4d\u7f6e\u3001\u6298\u53e0\u89d2\u5ea6\u7b49\u3002 \ud83d\udcf1 FLAT (\u5e73\u94fa) \u8bbe\u5907\u5b8c\u5168\u5c55\u5f00\uff0c\u6216\u5904\u4e8e\u6807\u51c6\u7684\u5e73\u9762\u72b6\u6001\u3002\u6b64\u65f6\u5e94\u7528\u5e94\u5360\u636e\u6574\u4e2a\u53ef\u7528\u533a\u57df\uff0c\u63d0\u4f9b\u65e0\u7f1d\u7684\u8fde\u7eed\u4f53\u9a8c\u3002 \ud83d\udcd6 HALF_OPEN (\u534a\u5f00) \u5c4f\u5e55\u5448 90\u00b0 \u6298\u53e0\uff08\u5982\u4e66\u672c\u6a21\u5f0f\u6216\u684c\u9762\u6a21\u5f0f\uff09\u3002\u5185\u5bb9\u5e94\u907f\u5f00\u94f0\u94fe\u533a\u57df\uff0c\u5229\u7528\u4e24\u4fa7\u5206\u522b\u663e\u793a\u5217\u8868\u548c\u8be6\u60c5\u3002 \ud83d\udccf WindowMetrics \u653e\u5f03 `DisplayMetrics`\u3002\u5728\u591a\u7a97\u53e3\u6a21\u5f0f\u4e0b\uff0c\u5e94\u7528\u4e0d\u62e5\u6709\u6574\u4e2a\u5c4f\u5e55\u3002\u5fc5\u987b\u4f7f\u7528 `currentWindowMetrics` \u83b7\u53d6\u5b9e\u9645\u53ef\u7528\u8fb9\u754c\u3002 App Window \u5c4f\u5e55\u788e\u7247\u5316\u7684\u6311\u6218 Android \u8bbe\u5907\u7684\u5c4f\u5e55\u5c3a\u5bf8\u3001\u5206\u8fa8\u7387\u548c\u50cf\u7d20\u5bc6\u5ea6\u6781\u5176\u591a\u6837\u5316\u3002\u4f20\u7edf\u7684\u201c\u624b\u673a vs \u5e73\u677f\u201d\u4e8c\u5206\u6cd5\u5df2\u4e0d\u518d\u9002\u7528\u3002 \u5de6\u4fa7\u7684 3D \u6563\u70b9\u56fe\u5c55\u793a\u4e86\u6570\u5343\u79cd Android \u8bbe\u5907\u7684 \u5bbd\u5ea6 (dp)\u3001\u9ad8\u5ea6 (dp) \u548c \u5c4f\u5e55\u5bc6\u5ea6 \u5206\u5e03\u3002\u6211\u4eec\u53ef\u4ee5\u770b\u5230\uff0c\u8bbe\u5907\u5c3a\u5bf8\u5e76\u975e\u7ebf\u6027\u5206\u5e03\uff0c\u800c\u662f\u5448\u73b0\u51fa\u6781\u5927\u7684\u79bb\u6563\u6027\u3002 \u89e3\u51b3\u65b9\u6848\uff1aWindowSizeClasses Google \u63a8\u51fa\u4e86\u4e00\u5957\u6807\u51c6\u5316\u7684\u65ad\u70b9\u7cfb\u7edf\uff0c\u5c06\u65e0\u9650\u7684\u5c3a\u5bf8\u53d8\u5316\u5f52\u7eb3\u4e3a\u4e09\u79cd\u6807\u51c6\u7a97\u53e3\u5927\u5c0f\u7c7b\u522b\u3002 WindowSizeClasses \u6807\u51c6\u5206\u5e03 WindowSizeClass \u6839\u636e\u7a97\u53e3\u7684\u53ef\u7528\u5bbd\u5ea6\u548c\u9ad8\u5ea6\u5c06\u8bbe\u5907\u5206\u4e3a Compact\u3001Medium \u548c Expanded\u3002\u8fd9\u79cd\u5206\u7c7b\u65b9\u5f0f\u8ba9\u8bbe\u8ba1\u5e08\u548c\u5f00\u53d1\u8005\u62e5\u6709\u4e00\u5957\u901a\u7528\u7684\u8bed\u8a00\u3002 Compact (\u7d27\u51d1) \u5bbd\u5ea6 &lt; 600dp (\u7edd\u5927\u591a\u6570\u6807\u51c6\u624b\u673a\u7ad6\u5c4f) Medium (\u4e2d\u7b49) 600dp &le; \u5bbd\u5ea6 &lt; 840dp (\u6298\u53e0\u5c4f\u5c55\u5f00\u6001\u3001\u5c0f\u578b\u5e73\u677f) Expanded (\u5c55\u5f00) \u5bbd\u5ea6 &ge; 840dp (\u5927\u578b\u5e73\u677f\u3001\u684c\u9762\u6a21\u5f0f) Activity \u5d4c\u5165\uff1a\u65e7\u5e94\u7528\u7684\u91cd\u751f \u65e0\u9700\u91cd\u5199\u6574\u4e2a\u5e94\u7528\uff0c\u901a\u8fc7 XML \u914d\u7f6e\u6587\u4ef6\u5373\u53ef\u8ba9\u57fa\u4e8e Activity \u7684\u65e7\u67b6\u6784\u5e94\u7528\u652f\u6301\u5927\u5c4f\u53cc\u5217\u663e\u793a\u3002 1 \u6dfb\u52a0\u4f9d\u8d56 \u5728 `build.gradle` \u4e2d\u5f15\u5165 `androidx.window:window` \u5e93\u3002 implementation &#8220;androidx.window&#8230;&#8221; \u279c 2 \u914d\u7f6e XML \u89c4\u5219 \u521b\u5efa `main_split_config.xml`\uff0c\u5b9a\u4e49 `SplitPairRule`\uff08\u5206\u5c4f\u5bf9\uff09\u3002 \u279c 3 \u521d\u59cb\u5316\u4e0e\u8fd0\u884c \u4f7f\u7528 `RuleController` \u52a0\u8f7d\u89c4\u5219\u3002\u7cfb\u7edf\u81ea\u52a8\u63a5\u7ba1 Activity \u6808\u3002 A B \u62e5\u62b1\u81ea\u9002\u5e94\u672a\u6765 Jetpack WindowManager \u662f Android \u751f\u6001\u7cfb\u7edf\u5411\u5927\u5c4f\u5316\u8f6c\u578b\u7684\u5173\u952e\u57fa\u7840\u8bbe\u65bd\u3002\u73b0\u5728\u5c31\u5f00\u59cb\u9002\u914d\uff0c\u4e3a\u7528\u6237\u63d0\u4f9b\u65e0\u7f1d\u3001\u8fde\u7eed\u4e14\u9ad8\u6548\u7684\u8de8\u8bbe\u5907\u4f53\u9a8c\u3002 \u9605\u8bfb\u5b98\u65b9\u6587\u6863<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-633","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/trantor.ink\/index.php?rest_route=\/wp\/v2\/pages\/633","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trantor.ink\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/trantor.ink\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/trantor.ink\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/trantor.ink\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=633"}],"version-history":[{"count":1,"href":"https:\/\/trantor.ink\/index.php?rest_route=\/wp\/v2\/pages\/633\/revisions"}],"predecessor-version":[{"id":634,"href":"https:\/\/trantor.ink\/index.php?rest_route=\/wp\/v2\/pages\/633\/revisions\/634"}],"wp:attachment":[{"href":"https:\/\/trantor.ink\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=633"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}