gpt4 book ai didi

android - 为什么 MediaRecorder 函数不会导致 ANR 错误?

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:02:04 31 4
gpt4 key购买 nike

我在 Android 5.1 中使用 MediaRecorder 和 MediaProjection 函数启动了一个重新记录屏幕的服务,我认为代码方法 1 会导致应用程序无响应错误,因为它在主线程中工作。

  1. 我测试代码方法1重新编码屏幕很长时间,它没有出现“应用程序无响应错误”,为什么?这是否意味着函数 MediaRecorder 和 MediaProjection 在单独的线程中工作?

  2. 在代码方法 2 中,我创建了一个线程来运行 mRecordHelper.StartRecord(mRecordArg,resultCode,mIntent);但我收到错误 java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare(), why?

感谢您的帮助。

调用代码

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);

方法一

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);
}

}

方法二

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() {

}
}

}

最佳答案

but I get the error java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare(), why?

我猜你知道你的第二个问题。事实上,如果您在主线程上调用 mRecordHelper.StartRecord(mRecordArg,resultCode,mIntent);,并不意味着所有代码函数都在该线程上运行,它所做的只是更新 UI 信息调用线程——这是主线程,在后台线程上努力工作。如果您明确地从不同的线程调用,那么您是在指示它从该线程更改 UI 对象,因此您会得到该异常-想象一个使用异步任务或 SurfaceView 的类,先生,请不要感到困惑,您可以随时去查看源代码,看看它是如何工作的。

这没什么大不了的-(我谦虚地说)

why? Does it mean that the function MediaRecorder and MediaProjection worked in separated thread?

检查上面的-我猜是

关于android - 为什么 MediaRecorder 函数不会导致 ANR 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33541279/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com