>我测试代码方法1重新编码屏幕很长时间,它不会发生“应用程序无响应错误”,为什么?这是否意味着MediaRecorder和MediaProjection函数在分离的线程中工作?
>在代码方法2中,我创建了一个运行mRecordHelper.StartRecord的线程(mRecordArg,resultCode,mIntent);但我得到错误java.lang.RuntimeException:无法在没有调用Looper.prepare()的线程内创建处理程序,为什么?
谢谢你的帮助.
电话代码
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);
方法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,mIntent);
return super.onStartCommand(intent,flags,startId);
}
}
方法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,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,mIntent);
}
}).start();
return super.onStartCommand(intent,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,mIntent);在主线程上,并不意味着所有代码函数都在该线程上运行,它所做的只是更新调用Thread上的UI信息 – 这是主线程,以及后台线程上的辛勤工作.如果你从另一个线程中明确地调用你指示它从该线程更改一个UI对象,那么你得到的异常 – 图片是一个使用异步任务的类,或者SurfaceView,不要混淆先生,你可以随时去查看源代码并看看它是如何工作的.
这不是什么大不了的事 – (我谦卑地说)
why? Does it mean that the function MediaRecorder and MediaProjection worked in separated thread?
检查上面 – 我猜是的