繁体   English   中英

如何在Android中的onDestroy服务后使对象变量保持活动状态?

[英]How to keep object variable alive after service onDestroy in Android?

我的IntentService类中有一个MediaRecorder

我想要

  1. 运行IntentService以开始录制音频
  2. 运行IntentService停止录制音频

我使用IntentService是因为我希望即使在手机屏幕关闭的情况下也可以继续录音。 服务在后台运行,所以这是一个好方法,对吗?

不管怎么说,我开始我的MediaRecorder在我IntentService在第1步。 在步骤2,我实例化的MediaRecorder为NULL。 似乎IntentService内部的所有变量值都已重置,因为该服务结束并调用onDestroy

我该怎么办? 如何保留对MediaRecorder的引用?

更新:粘贴我的IntentService

package com.dan190.enregistreur.BackgroundService;

import android.app.IntentService;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;

import com.dan190.enregistreur.RecordedFilesActivity;
import com.dan190.enregistreur.Util.RecordingStatus;

import java.io.IOException;
import java.util.Calendar;

/**
 * Created by Dan on 17/03/2017.
 */
public class RecorderService extends IntentService {
    private static final String TAG = RecorderService.class.getName();

    private MediaRecorder mMediaRecorder;

    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public RecorderService(String name) {
        super(name);
    }

    public RecorderService() {
        super("RecorderService");
    }
    /**
     * Handles intent.
     * Unwraps intent to find out if we need to start, pause, or stop
     * @param intent
     */
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.d(TAG, "onHandleIntent");

        Bundle bundle = intent.getExtras();
        int status = bundle.getInt(RecordingStatus.RECORDING_STATUS_KEY);
        switch (status) {
        case RecordingStatus.STANDBY:
            //do nothing
            break;
        case RecordingStatus.RECORDING:
            //if mediaPlayer is null, initiate
            //set datasource
            //prepare
            //record
            Log.d(TAG, "start recording");
            startRecording();
            break;
        case RecordingStatus.PAUSED:
            //pause
            Log.d(TAG, "pause recording");
            break;
        case RecordingStatus.STOPPED:
            //stop
            Log.d(TAG, "stop recording");
            stopRecording();
            Intent newIntent = new Intent(this, RecordedFilesActivity.class);
            startActivity(newIntent);
            break;
        case RecordingStatus.OPENDIR:
            //open recorded files
            Log.d(TAG, "open directory");
            getFileName();
            Intent newIntent2 = new Intent(this, RecordedFilesActivity.class);
            startActivity(newIntent2);
            break;
        default:
            break;
        }

    }

    /**
     * File stuff
     */
    private static String pathName,
    fileName;

    public static String getPath() {
        return pathName;
    }

    public static String getFilePath() {
        return fileName;
    }

    private String getFileName() {
        Calendar calendar = Calendar.getInstance();

        PackageManager m = getPackageManager();
        pathName = getPackageName();
        PackageInfo p = null;
        try {
            p = m.getPackageInfo(pathName, 0);
        } catch(PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        pathName = p.applicationInfo.dataDir;

        //        fileName = Environment.getExternalStorageDirectory() + "/" + Environment.DIRECTORY_DCIM + "/Recordings";
        fileName = pathName;
        fileName += String.format("/%d_%d_%d_%d_%d_%d.3gp", calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.HOUR_OF_DAY) + 1, calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));

        return fileName;

    }

    /**
     * Recorder stuff
     */
    private void startRecording() {
        String fileName = getFileName();
        Log.d(TAG, String.format("file name is %s", fileName));

        if (mMediaRecorder == null) mMediaRecorder = new MediaRecorder();

        //NOTE that mediaRecorder cannot pause for API < 24, which is Android 7.0
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mMediaRecorder.setOutputFile(getFileName());
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

        try {
            mMediaRecorder.prepare();
        } catch(IOException e) {
            Log.e(TAG, "prepare() failed");
            e.printStackTrace();
        }

        try {
            mMediaRecorder.start();
        } catch(IllegalStateException e) {
            Log.e(TAG, e.getStackTrace().toString());
        }
    }

    private void stopRecording() {
        try {
            mMediaRecorder.stop();
            mMediaRecorder.reset();
        } catch(RuntimeException e) {
            e.printStackTrace();
        }
        releaseMediaRecorder();
    }

    private void releaseMediaRecorder() {
        if (mMediaRecorder != null) {
            mMediaRecorder.release();
            mMediaRecorder = null;
        } else {
            Log.w(TAG, "mediaRecroder is already Null");
        }

    }

    /**
     * Lifecycle stuff
     */
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy");
    }

}

通过使用服务而不是Intent服务对其进行了修复。

这篇文章被证明是有帮助的。 Service.onDestroy()在创建后直接调用,无论如何Service都会执行其工作

基本上,IntentService的设计旨在使onHandleIntent中的代码完成后立即停止所有服务。 因此,我永远无法保持MediaRecorder的生命。

使用正常的服务,我可以更好地控制服务的生命周期。 我可以在需要时启动和停止它。 使用IntentService,这是不可能的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM