如何在Android中的onDestroy服务后保持对象变量活着?

时间:2017-03-18 04:37:20

标签: java android intentservice mediarecorder recording

我的MediaRecorder课程中有IntentService

我想

  1. 运行IntentService开始录制音频
  2. 运行IntentService以停止录制音频
  3. 我使用IntentService,因为即使我的手机屏幕关闭,我也想要录音。服务在后台运行,所以这是一个很好的方法,对吗?

    无论如何,我在步骤#1的MediaRecorder中发起了IntentService。 在步骤#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");
        }
    
    }
    

1 个答案:

答案 0 :(得分:0)

使用Service而不是Intent服务修复它。

这篇文章证明是有帮助的。 Service.onDestroy() is called directly after creation, anyway the Service does its work

基本上,IntentService的设计是为了在onHandleIntent中的代码完成后立即停止所有服务。因此,我永远无法让我的MediaRecorder保持活力。

通过正常的服务,我可以更好地控制服务的生命周期。我可以在我想要的时候开始和停止它。使用IntentService,这是不可能的。