Why doesn't the MediaRecorder function throw an ANR error?

I am launching a service to reuse the screen using the MediaRecorder and MediaProjection functions in Android 5.1, I think Method 1 code will result in Application Not Responding error, since it works in the main thread.

  • I am testing the code of Method 1 , so that for a long time to recode the screen, the "Application that does not respond to the error" does not appear, why? Does this mean that the MediaRecorder and MediaProjection functions worked in a separate thread?

  • In Method 2 code, I create a thread to run mRecordHelper.StartRecord (mRecordArg, resultCode, mIntent); but I get java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare(), why?

Thank you for your help.

Call code

 MPublicPar.RecordArg mRecordArg =new MPublicPar().new RecordArg(mContext); Intent intent = new Intent(mContext,bll.RecordService.class); intent.putExtra("resultCode",resultCode); intent.putExtra("dataIntent",data); intent.putExtra("mRecordArg",mRecordArg); startService(intent); 

Method 1

 public class RecordService extends Service { private RecordHelper mRecordHelper; private Context mContext; @Override public void onCreate(){ mContext=this; mRecordHelper=new RecordHelper(mContext); } @Override public void onDestroy(){ mRecordHelper.StopRecord(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { final int resultCode=intent.getIntExtra("resultCode",0); final Intent mIntent=(Intent)intent.getParcelableExtra("dataIntent"); final MPublicPar.RecordArg mRecordArg=(MPublicPar.RecordArg)intent.getSerializableExtra("mRecordArg"); mRecordHelper.StartRecord(mRecordArg,resultCode,mIntent); return super.onStartCommand(intent, flags, startId); } } 

Method 2

 public class RecordService extends Service { private RecordHelper mRecordHelper; private Context mContext; @Override public void onCreate(){ mContext=this; mRecordHelper=new RecordHelper(mContext); } @Override public void onDestroy(){ mRecordHelper.StopRecord(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { final int resultCode=intent.getIntExtra("resultCode",0); final Intent mIntent=(Intent)intent.getParcelableExtra("dataIntent"); final MPublicPar.RecordArg mRecordArg=(MPublicPar.RecordArg)intent.getSerializableExtra("mRecordArg"); new Thread(new Runnable() { public void run() { mRecordHelper.StartRecord(mRecordArg,resultCode,mIntent); } }).start(); return super.onStartCommand(intent, flags, startId); } } 

RecordHelper.cs

 public class RecordHelper { private MediaRecorder mMediaRecorder; private MediaProjection mMediaProjection; private VirtualDisplay mVirtualDisplay; private MediaProjectionManager mProjectionManager; private Context mContext; private Toast mToastText; public RecordHelper(Context mContext){ this.mContext=mContext; mProjectionManager = (MediaProjectionManager) mContext.getSystemService(Context.MEDIA_PROJECTION_SERVICE); mMediaRecorder = new MediaRecorder(); } public void StartRecord(RecordArg mRecordArg, int resultCode, Intent data){ initRecorder(mRecordArg); prepareRecorder(); mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data); MediaProjectionCallback mMediaProjectionCallback = new MediaProjectionCallback(); mMediaProjection.registerCallback(mMediaProjectionCallback, null); mVirtualDisplay=createVirtualDisplay(mRecordArg); DelayStartRecord(mRecordArg); } public void StopRecord(){ try { mMediaRecorder.stop(); mMediaRecorder.reset(); mVirtualDisplay.release(); mMediaRecorder.release(); mMediaProjection.stop(); mMediaProjection = null; }catch (Exception e){ Utility.LogError("StopRecord Error " + e.getMessage() + " " + e.toString()); } } private void DelayStartRecord(RecordArg mRecordArg){ mMediaRecorder.start(); } private void initRecorder(RecordArg mRecordArg) { mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); mMediaRecorder.setVideoEncodingBitRate(512 * 1000); mMediaRecorder.setVideoFrameRate(30); mMediaRecorder.setVideoSize(mRecordArg.screenWidth, mRecordArg.screenHeight); mMediaRecorder.setOutputFile(mRecordArg.videoFilename); } private void prepareRecorder() { try { mMediaRecorder.prepare(); } catch (IllegalStateException e) { e.printStackTrace(); Utility.LogError(e.getMessage()); } catch (IOException e) { e.printStackTrace(); Utility.LogError(e.getMessage()); } } private VirtualDisplay createVirtualDisplay(RecordArg mRecordArg) { return mMediaProjection.createVirtualDisplay("ScreenRecord", mRecordArg.screenWidth, mRecordArg.screenHeight, mRecordArg.mScreenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mMediaRecorder.getSurface(), null /*Callbacks*/, null /*Handler*/); } //Called when the MediaProjection session is no longer valid. private class MediaProjectionCallback extends MediaProjection.Callback { @Override public void onStop() { } } } 
+7
android
source share
1 answer

but I get java.lang.RuntimeException error: cannot create a handler inside a thread that did not call Looper.prepare (), why?

I think you know, therefore, your second question. The fact that if you call mRecordHelper.StartRecord(mRecordArg,resultCode,mIntent); in the main thread, does not mean that all the functions of the code are executed in this thread, all it does is update the user interface information in the calling thread, which is the main thread, and hard work on the background thread. if you resort to a call from another thread, you instruct him to change the UI object from this thread, therefore, you will get this exception - an image of a class using an async task or SurfaceView , do not be confused, you can always check the source code and see how it working.

This is not a big deal - (I humbly say)

why? Does this mean that the MediaRecorder and MediaProjection functions worked in a separate branch?

check above - guess yes

+4
source share

All Articles