首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Android 開發避坑指南 2024:從 Theme 色值到 WebView 跨域、華為殺進程、Service 跨進程廣播

     編輯:Java 相關知識

注意:原文章標題為「JAVA 實現鏈表試題」,但內容實為 Android 開發實戰避坑筆記。本文依實際內容重寫並補充 2024 年最新適配要點。

Android 碎片化嚴重:系統版本 (API 21~34)、廠商 ROM (MIUI, ColorOS, HarmonyOS, OneUI)、硬體差異、權限政策頻繁變更。本文彙總 6 大類高頻坑位,附根因分析、修復代碼與最佳實踐,助你少踩坑、快交付。

一、Material Theme 色值陷阱 (API 21+)

現象

設置 colorPrimary 為帶透明度的顏色 (如 #80FF0000),App 啟動崩潰:

java.lang.RuntimeException: A TaskDescription's primary color should be opaque

根因

ActivityManager.TaskDescription 構造函數強制檢查 Color.alpha(color) == 255,用於近期任務列表顯示,不支援半透明。

修復


@color/primary_opaque 
@color/primary_dark_opaque

二、Android 5.0+ WebView 跨域 Cookie 失效

現象

API 21+ CookieManager 預設 acceptThirdPartyCookies = false,導致 WebView 無法讀取第三方域 Cookie (如嵌入 H5 登錄態)。

修復

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
}
// 同步 Cookie 到原生網絡層 (OkHttp/Retrofit)
CookieManager.getInstance().setCookie(url, cookieString);
CookieSyncManager.getInstance().sync(); // API 21- 已棄用但兼容

最佳實踐:避免跨域 Cookie 依賴,改用 Token Header 或原生登錄態同步方案。

三、華為/榮耀 EMUI/HarmonyOS 殺進程機制

現象

  • 鎖屏/後台運行數分鐘後進程被殺,推送斷連、定位停止、音樂暫停。
  • 用戶需手動在「電池優化」→「允許後台運行」/「鎖定應用」才能恢復。

根因

華為自研 BASTET (Battery Saving Technology) 機制:基於耗電量、用戶行為、應用類別智能清理。預設策略激進,甚至新安裝應用默認「不允許後台」。

應對策略

  1. 引導用戶授權:啟動頁/設定頁檢測權限狀態,跳轉系統授權頁:
// 跳轉華為電池優化設置
Intent intent = new Intent();
intent.setClassName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity");
startActivity(intent);
  1. 前台服務:核心功能 (音樂、導航、即時通訊) 必須用 Service.startForeground() + 通知欄,系統不敢輕易殺。
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("正在播放").setSmallIcon(R.drawable.ic_notif)
    .setContentIntent(pendingIntent).setOngoing(true);
startForeground(NOTIFICATION_ID, builder.build());
  1. 推送通道整合:集成華為 Push Kit (HMS Core),走系統級推送通道,不依賴長連接保活。

四、Service 跨進程 BroadcastReceiver 接收異常

現象

同一 App 不同進程 (:remote) 中,Service 註冊網絡變化廣播 (CONNECTIVITY_CHANGE):

  • 主進程 UI 能收到連接/斷開廣播。
  • Service 進程**只能收到斷開,收不到連接**廣播。

根因

華為/部分 ROM 對非前台進程的隱式廣播進行優化攔截,CONNECTIVITY_ACTION 在 Android 7.0+ 已廢棄靜態註冊,動態註冊亦受限。

現代替代方案

// 1. NetworkCallback API (API 21+ 推薦)
ConnectivityManager cm = getSystemService(ConnectivityManager.class);
cm.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback() {
    @Override public void onAvailable(Network network) { /* 已連網 */ }
    @Override public void onLost(Network network) { /* 斷網 */ }
});

// 2. WorkManager 週期性檢查 (延遲容忍場景)
Constraints constraints = new Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED).build();
PeriodicWorkRequest request = new PeriodicWorkRequest.Builder(NetworkCheckWorker.class, 15, TimeUnit.MINUTES)
    .setConstraints(constraints).build();
WorkManager.getInstance(context).enqueue(request);

五、Drawable 共享狀態導致顏色污染

現象

從資源獲取 Drawable 後修改顏色/Alpha,導致**全應用**所有使用該資源的地方同步變色。

根因

Resources.getDrawable() 返回同一 ConstantState 實例,內部共享狀態。

修復

// 方式 1: mutate() 破壞共享狀態 (API 1+)
Drawable d = ContextCompat.getDrawable(context, R.drawable.ic_icon).mutate();
d.setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);

// 方式 2: 新建實例 (API 23+)
Drawable d = ResourcesCompat.getDrawable(res, R.drawable.ic_icon, theme).mutate();

六、其他高頻坑位速查

坑位現象修復/規避
8.0+ 通知渠道無 Channel 通知不顯示NotificationManager.createNotificationChannel() (API 26+)
9.0+ 明文流量HTTP 請求失敗android:usesCleartextTraffic="true" 或全 HTTPS
10+ 儲存權限外部存儲讀寫受限Scoped Storage: MediaStore / SAF / requestLegacyExternalStorage (臨時)
11+ 套件可見性queryIntentActivities 返回空<queries> 清單聲明需查詢的包/意圖
12+ 藍牙權限掃描/連接需新權限BLUETOOTH_SCAN, BLUETOOTH_CONNECT (API 31+)
13+ 通知權限通知需用戶授權POST_NOTIFICATIONS 運行時請求 (API 33+)
14+ 前台服務類型缺類型崩潰foregroundServiceType="mediaPlayback|location|..." (API 34+)

七、持續避坑的工程化建議

  1. 最低版本策略:minSdk 24+ (Android 7.0) 可棄用大量兼容代碼,compileSdk/targetSdk 34 強制適配最新政策。
  2. 自動化測試矩陣:Firebase Test Lab / 蒼雲測試跑主流機型 (小米/華為/OPPO/vivo/三星/Google Pixel) API 28/30/33/34。
  3. 依賴鎖定與掃描:dependencyVerification + OWASP Dependency Check 防供應鏈攻擊。
  4. 廠商適配清單:維護內部 Wiki,記錄各 ROM 特有行為 (如小米自啟動、OPPO 凍結、vivo 高耗電預警) 及對應代碼片段。
  5. 漸進式遷移:Jetpack Compose、Kotlin Coroutines/Flow、Hilt、Room、DataStore 逐步替換舊技術棧,減少歷史包袱。

Android 開發的本質是「在約束中尋找確定性」。建立團隊級避坑知識庫、自動化驗證體系、漸進式現代化技術棧,才能在碎片化浪潮中穩健前行。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved