【问题标题】:How to stop IntentService Android如何停止 IntentService Android
【发布时间】:2020-04-22 07:45:29
【问题描述】:

我已经在 Android 中构建了一个 IntentService。

因此,如果我收到 pushNotification 消息,我会停止此服务。

public class DosimeterDataSensingService extends IntentService {
    private static final String TAG = "DosimeterDataSensingService";
    public static boolean isStarted = false;
    private Context mContext;
    private int mStatus;
    private BluetoothDevice mDevice;
    private BluetoothGatt mConnGatt;
    private boolean notificationsEnabled;
    private long dosimeterScanningTime;
    private boolean isThreadStarted = false;
    private List<DosimeterDataRequest.DataBean> dosimeterDataList;
    private List<DosimeterDataRequest.DataBean> dosimeterDataListMqtt;
    private DosimeterMqttParcel dosimeterMqttParcel = new DosimeterMqttParcel();
    private DosimeterDataRequest dosimeterDataRequest;
    private String macAddress;
    private boolean isRecordingEnabled = false;
    private String dose = "";
    private int battery = -1;
    private Boolean syncRadiactionWS = false;
    private Boolean syncRadiactionMQTT = false;
    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public DosimeterDataSensingService(String name) {
        super(name);
    }

    public DosimeterDataSensingService() {
        super(null);
    }


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

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.d("dosimetro", "ON HANDLE INTENT");
        if(intent!=null){
            String action = intent.getStringExtra(PreferenceHandler.ACTION_STOP);

            Log.d("dosimetro", action!=null ? action : "no action");
            if(action!=null && action.equals(PreferenceHandler.ACTION_STOP)){
                Log.d("dosimetro", "fermo il servizio");
                String syncScanTime = PreferenceHandler.readString(getApplicationContext(), PreferenceHandler.DOSIMETER_SCANNING_TIME, null);
                Log.d("dosimetro", syncScanTime!=null ? syncScanTime : "nullo");
                String syncRotTime = PreferenceHandler.readString(getApplicationContext(), PreferenceHandler.DOSIMETER_ROTATION_TIME, null);
                Log.d("dosimetro", syncRotTime!=null ? syncRotTime : "nullo");
                super.stopSelf();
                Log.d("dosimetro", "ho stoppato");
                onDestroy();
                return;
            }
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Paper.init(this);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = createNotificationChannel();
        }

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, getString(R.string.default_notification_channel_id))
                .setSmallIcon(R.drawable.logoxhdpi)
                .setCategory(Notification.CATEGORY_SERVICE)
                .setContentTitle("Cardio App")
                .setContentText("Getting data from Dosimeter")
                .setPriority(NotificationCompat.PRIORITY_DEFAULT);

        Notification notification = mBuilder.build();
        startForeground((int) (System.currentTimeMillis() + 1), notification);
        isStarted = true;

        if (PreferenceHandler.readString(this, PreferenceHandler.TYPE_USER, null).equals("2")) {
            checkDosage();
        }
        List<GetAssignedDevicesListResponse.Parameters> preferenzeParametri= Paper.book().read(PreferenceHandler.PARAMETRI_VITALI, new ArrayList<>());
        if(preferenzeParametri!=null && preferenzeParametri.size()>0){
            for (GetAssignedDevicesListResponse.Parameters p: preferenzeParametri) {
                if(p.getIdParameter() == PreferenceHandler.ID_RADIACTION){
                    //VERIFICO COME L'RR DEVE ESSERE SINCRONIZZATO
                    syncRadiactionWS = p.getSyncWs()!=null ? p.getSyncWs() : false;
                    syncRadiactionMQTT =  p.getSyncMqtt()!=null ? p.getSyncMqtt() : false;
                    Log.e("DOSIMETER", "syncRadiactionWS true");
                }
            }
        }else{
            Log.e("DOSIMETER", "paperi init false");
        }

        checkBattery();
        Log.i("SCANNINGTIME", "SYNC WS STARTED");
        syncRadiactionLevel();
        syncMqtt();
    }


    @Override
    public void onDestroy() {
        Log.d("DOSIMETRO", "ondestroy");
        isStarted = false;
        disconnectDosimeter();
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);

        return START_STICKY;
    }



    @SuppressLint("LongLogTag")
    public void disconnectDosimeter() {

        if (mConnGatt != null) {
            isThreadStarted = false;
            if ((mStatus != BluetoothProfile.STATE_DISCONNECTING)
                    && (mStatus != BluetoothProfile.STATE_DISCONNECTED)) {
                mConnGatt.disconnect();
                mConnGatt.close();
                mConnGatt = null;
                mStatus = BluetoothProfile.STATE_DISCONNECTED;
            }
        }
        try {
            Method m = mDevice.getClass().getMethod("removeBond", (Class[]) null);
            m.invoke(mDevice, (Object[]) null);
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }

        Log.v("Dosimeter", "isRecordingEnabled" + isRecordingEnabled);
        Log.v("Dosimeter", "Disconnecteddd");
    }




    /**
     * Enable recording of values
     */
    private void startRecordingData() {
        String dosimeterRotation = PreferenceHandler.readString(getApplicationContext(), PreferenceHandler.DOSIMETER_ROTATION_TIME, null);
        Log.i("ROTATIONTIME", dosimeterRotation);
        long dosimeterRotationTime = 0L;
        if (dosimeterRotation != null) {
            dosimeterRotationTime = Long.parseLong(dosimeterRotation);
            new Handler().postDelayed(() -> {
                isRecordingEnabled = true;
                isThreadStarted = false;
            }, dosimeterRotationTime);
        }
    }



}

使用此代码停止我正在使用的服务:

Intent i = new Intent(this, DosimeterDataSensingService.class);
i.putExtra(PreferenceHandler.ACTION_STOP,PreferenceHandler.ACTION_STOP);
stopService(new Intent(this, DosimeterDataSensingService.class));

从我的日志中我可以看到系统调用

super.stopSelf();
onDestroy();

方法,但 IntentService 始终有效。

【问题讨论】:

标签: android intentservice


【解决方案1】:

您无需为IntentService 调用stopSelf()stopService()

根据文档中提到的描述:

因为大多数启动的服务不需要同时处理多个请求(这实际上可能是危险的多线程场景),所以最好使用 IntentService 类来实现服务。

IntentService 类执行以下操作:

It creates a default worker thread that executes all of the intents that are delivered to onStartCommand(), separate from your application's main thread.

Creates a work queue that passes one intent at a time to your onHandleIntent() implementation, so you never have to worry about multi-threading.

Stops the service after all of the start requests are handled, **so you never have to call stopSelf().**

Provides a default implementation of onBind() that returns null.

Provides a default implementation of onStartCommand() that sends the intent to the work queue and then to your onHandleIntent() implementation.

如果服务仍在运行,可能是一些意图正在运行。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多