startService(intent) 呼叫無反應、無錯誤、Service 不執行,90% 原因是 Manifest 未註冊 Service。次要原因包括 Intent Action 拼寫錯誤、Service 類別名稱不符、權限缺失。
關鍵:android:name 必須與 Java 類別完整路徑一致(含包名或以點開頭表示相對包名)。
| 步驟 | 代碼/設定 | 常見錯誤 |
|---|---|---|
| 1. Manifest 註冊 | <service android:name=".UpdaterServiceManager" /> | 漏註冊、包名錯誤、大小寫不符 |
| 2. Intent 建立 | Intent intent = new Intent(this, UpdaterServiceManager.class); | 用 Action 字串啟動時拼寫錯、未在 Manifest 宣告 intent-filter |
| 3. 呼叫啟動 | startService(intent); | 在非 Context 環境呼叫、Intent 為 null |
| 4. Service onStartCommand | return START_STICKY; | 未實作、回傳錯誤值 |
// 方式一:顯式 Intent(推薦,編譯期檢查)
Intent intent = new Intent(this, UpdaterServiceManager.class);
startService(intent);
// 方式二:隱式 Intent(需 Manifest 宣告 action)
Intent intent = new Intent("com.example.ACTION_START_SERVICE");
intent.setPackage(getPackageName()); // 安全:限定自家套件
startService(intent);
Manifest 對應宣告:
// 1. 檢查 Service 是否在運行
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
for (RunningServiceInfo info : am.getRunningServices(Integer.MAX_VALUE)) {
if (UpdaterServiceManager.class.getName().equals(info.service.getClassName())) {
Log.d("Debug", "Service is running");
}
}
// 2. 檢查 Manifest 解析
PackageManager pm = getPackageManager();
try {
ServiceInfo si = pm.getServiceInfo(new ComponentName(this, UpdaterServiceManager.class), 0);
Log.d("Debug", "Service registered: " + si.name);
} catch (PackageManager.NameNotFoundException e) {
Log.e("Debug", "Service NOT registered in Manifest!", e);
}
startService() 會拋出 IllegalStateException。startForegroundService() 並在 Service onCreate 中呼叫 startForeground()。WorkManager 執行延遲/週期性工作。遇到 Service 不啟動先查 Manifest,養成「新增 Service 立即註冊」習慣,可避免此類低級錯誤浪費時間。