首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android Service 在 onReceive 中呼叫 onDestroy() 卻無法真正停止服務?正確停止方式解析

     編輯:程式設計疑難解答

在 BroadcastReceiver 的 onReceive() 中直接呼叫 onDestroy() **只是執行該方法的程式碼**,並不會真正停止 Service。Android 元件生命週期方法(onCreate、onStartCommand、onDestroy 等)只能由系統呼叫,開發者手動呼叫不會觸發系統的元件銷毀流程。

錯誤示範

public class MyReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        onDestroy(); // 錯誤:僅執行方法體,服務仍在運行
    }
}

正確停止 Service 的方法

1. 從 Service 內部自我停止

stopSelf(); // 或 stopSelf(startId) 對應特定啟動請求

2. 從其他元件(Activity、Receiver)停止

context.stopService(new Intent(context, MyService.class));

3. 在 Receiver 中正確實作


public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 發送停止服務的 Intent
        context.stopService(new Intent(context, MyService.class));
    }
}

關鍵補充:START_STICKY 行為

你的 onStartCommand 回傳 START_STICKY,表示服務被系統殺死後會嘗試重建。若需彈性控制,可視情況回傳 START_NOT_STICKY 或 START_REDELIVER_INTENT。

完整修正範例


public class MyService extends Service {
    private MyReceiver receiver;

    @Override
    public void onCreate() {
        super.onCreate();
        receiver = new MyReceiver();
        IntentFilter filter = new IntentFilter("net.s5c.Changelink.wifiOff");
        registerReceiver(receiver, filter);
        Toast.makeText(this, "服務已啟動", Toast.LENGTH_SHORT).show();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_NOT_STICKY; // 視需求調整
    }

    @Override
    public void onDestroy() {
        if (receiver != null) unregisterReceiver(receiver);
        Toast.makeText(this, "服務已關閉", Toast.LENGTH_LONG).show();
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) { return null; }

    private class MyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            stopSelf(); // 正確:在 Service 內部停止自己
            // 或 context.stopService(new Intent(context, MyService.class));
        }
    }
}

核心原則:**永遠不要手動呼叫生命週期方法**,改用系統提供的 stopSelf() / stopService() 讓框架正常處理銷毀流程。

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