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

问题描述:

我的MediaRecorder在我的IntentService类中。如何在Android中服务onDestroy后保持对象变量存活?

我想

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

我使用IntentService,因为我希望把音频记录,即使运行我手机屏幕关闭。服务在后台运行,所以这是一个好方法,对吧?

无论如何,我在步骤1中在我的IntentService中启动我的MediaRecorder。 在步骤#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

在此处粘贴IntentService类 –

+0

完成@ZeeshanShabbir – Dan

通过使用服务,而不是意图服务的固定它。

这个帖子证明有帮助。 Service.onDestroy() is called directly after creation, anyway the Service does its work

基本上,IntentService被设计为在onHandleIntent内的代码完成后立即停止所有服务。因此,我从来没有能够保持我的MediaRecorder活着。

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