Android 谨慎使用Timer定时器
来源:互联网 发布:ubuntu搭建php7 编辑:程序博客网 时间:2024/05/09 20:13
在Android应用开发过程中,设置完Timer后,在Timer消息还没有到来之前,跳到设置里面把时间或者日期往前设置,会发现Timer永远来不了了。
经过源码分析发现:Timer是以系统时间System.currentTimeMillis()(从January 1, 1970 00:00:00算起)为基准,当我们设置了Timer之后,相当于系统会在System.currentTimeMillis()+delayLen (delayLen:Timer多久会来消息)之后给我们发Timer消息。而设置了时间和日期,System.currentTimeMillis()就会改变。从而造成System.currentTimeMillis()+delayLen 已经过时了,这样Timer再了来不了了。
同理把时间或日期向后设置会造成过很久时间才会来Timer消息。因此在用到定时器功能能要谨慎使用Timer,最好用ScheduledExecutorService来实现。
Android4.4源码中的录音文件中,采用获取当前时间来显示已录音的时间,测试发现,修改系统时间后,录音时间的显示就全乱了,(真是佩服咱公司的测试,这都能发现)。
Android中的SystemClock类之前不知道还有这个类,涨见识了。
修改后的核心代码如下:
经过源码分析发现:Timer是以系统时间System.currentTimeMillis()(从January 1, 1970 00:00:00算起)为基准,当我们设置了Timer之后,相当于系统会在System.currentTimeMillis()+delayLen (delayLen:Timer多久会来消息)之后给我们发Timer消息。而设置了时间和日期,System.currentTimeMillis()就会改变。从而造成System.currentTimeMillis()+delayLen 已经过时了,这样Timer再了来不了了。
同理把时间或日期向后设置会造成过很久时间才会来Timer消息。因此在用到定时器功能能要谨慎使用Timer,最好用ScheduledExecutorService来实现。
Android4.4源码中的录音文件中,采用获取当前时间来显示已录音的时间,测试发现,修改系统时间后,录音时间的显示就全乱了,(真是佩服咱公司的测试,这都能发现)。
Android中的SystemClock类之前不知道还有这个类,涨见识了。
修改后的核心代码如下:
</pre><pre name="code" class="java">
public class Recorder implements OnCompletionListener, OnErrorListener { private ScheduledExecutorService service = Executors.newScheduledThreadPool(1);; private TimerTask mTimerTask; private ScheduledFuture mScheduled; long mSampleStart = 0; // time at which latest record or play operation started int mSampleLength = 0; // length of current sample File mSampleFile = null; int mSamplePlayLength = 0; MediaRecorder mRecorder = null; MediaPlayer mPlayer = null; public Recorder() { } public int progress() { if (mState == RECORDING_STATE) { return mSampleLength; } else if (mState == PLAYING_STATE) { return mSamplePlayLength; } return 0; } public int sampleLength() { return mSampleLength ; } public String getStartRecordingTime() { return mTime; } /** * Resets the recorder state. If a sample was recorded, the file is deleted. */ public void delete() { stop(); if (mSampleFile != null) mSampleFile.delete(); mSampleFile = null; mSampleLength = 0; signalStateChanged(IDLE_STATE); } /** * Resets the recorder state. If a sample was recorded, the file is left on disk and will * be reused for a new recording. */ public void clear() { stop(); mSampleFile = null; mSampleLength = 0; signalStateChanged(IDLE_STATE); } public void startRecording(int outputfileformat, String extension, Context context, int audiosourcetype, int codectype) { stop(); if (mSampleFile != null) { delete(); } File sampleDir = new File(mStoragePath); if (!sampleDir.exists()) { sampleDir.mkdirs(); } if (!sampleDir.canWrite()) // Workaround for broken sdcard support on the device. sampleDir = new File("/sdcard/sdcard"); try { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT); String time = simpleDateFormat.format(new Date(System.currentTimeMillis())); mTime = time; if (extension == null) { extension = ".tmp"; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(SAMPLE_PREFIX).append(time).append(extension); String name = stringBuilder.toString(); mSampleFile = new File(sampleDir, name); if (!mSampleFile.createNewFile()) { mSampleFile = File.createTempFile(SAMPLE_PREFIX, extension, sampleDir); } } catch (IOException e) { setError(SDCARD_ACCESS_ERROR); return; } mRecorder = new MediaRecorder(); mRecorder.setAudioSource(audiosourcetype); //set channel for surround sound recording. if (mChannels > 0) { mRecorder.setAudioChannels(mChannels); } if (mSamplingRate > 0) { mRecorder.setAudioSamplingRate(mSamplingRate); } mRecorder.setOutputFormat(outputfileformat); try { mRecorder.setAudioEncoder(codectype); } catch(RuntimeException exception) { stopTimer(); setError(UNSUPPORTED_FORMAT); mRecorder.reset(); mRecorder.release(); if (mSampleFile != null) mSampleFile.delete(); mSampleFile = null; mSampleLength = 0; mRecorder = null; return; } mRecorder.setOutputFile(mSampleFile.getAbsolutePath()); // Handle IOException try { mRecorder.prepare(); } catch(IOException exception) { stopTimer(); setError(INTERNAL_ERROR); mRecorder.reset(); mRecorder.release(); if (mSampleFile != null) mSampleFile.delete(); mSampleFile = null; mSampleLength = 0; mRecorder = null; return; } // Handle RuntimeException if the recording couldn't start Log.e(TAG,"audiosourcetype " +audiosourcetype); try { mRecorder.start(); } catch (RuntimeException exception) { stopTimer(); AudioManager audioMngr = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE); boolean isInCall = ((audioMngr.getMode() == AudioManager.MODE_IN_CALL) || (audioMngr.getMode() == AudioManager.MODE_IN_COMMUNICATION)); if (isInCall) { setError(IN_CALL_RECORD_ERROR); } else { Intent intent = new Intent("android.intent.soundrecorder.ACTION_RECORDER_CAPTURE"); context.sendBroadcast(intent); } mRecorder.reset(); mRecorder.release(); if (mSampleFile != null) mSampleFile.delete(); mSampleFile = null; mSampleLength = 0; mRecorder = null; return; } startTimer(true); //mSampleStart = System.currentTimeMillis(); setState(RECORDING_STATE); } public void pauseRecording() { if (mRecorder == null) { return; } try { mRecorder.pause(); } catch (RuntimeException exception) { stopTimer(); setError(INTERNAL_ERROR); Log.e(TAG, "Pause Failed"); } stopTimer(); //mSampleLength = mSampleLength + (System.currentTimeMillis() - mSampleStart); setState(PAUSE_STATE); } public void resumeRecording() { if (mRecorder == null) { return; } try { mRecorder.start(); } catch (RuntimeException exception) { setError(INTERNAL_ERROR); Log.e(TAG, "Resume Failed"); } startTimer(true); //mSampleStart = System.currentTimeMillis(); setState(RECORDING_STATE); } public void stopRecording() { if (mRecorder == null) return; try { mRecorder.stop(); }catch (RuntimeException exception){ setError(INTERNAL_ERROR); Log.e(TAG, "Stop Failed"); } mRecorder.reset(); mRecorder.release(); mRecorder = null; mChannels = 0;// if (mState == RECORDING_STATE) {// mSampleLength = mSampleLength + (System.currentTimeMillis() - mSampleStart);// } stopTimer(); setState(IDLE_STATE); } public void startPlayback() { stop(); mSamplePlayLength = 0; mPlayer = new MediaPlayer(); try { mPlayer.setDataSource(mSampleFile.getAbsolutePath()); mPlayer.setOnCompletionListener(this); mPlayer.setOnErrorListener(this); mPlayer.prepare(); mPlayer.start(); } catch (IllegalArgumentException e) { setError(INTERNAL_ERROR); mPlayer = null; return; } catch (IOException e) { setError(SDCARD_ACCESS_ERROR); mPlayer = null; return; } //mSampleStart = System.currentTimeMillis(); startTimer(false); setState(PLAYING_STATE); } public void stopPlayback() { mSamplePlayLength = 0; if (mPlayer == null) // we were not in playback return; mPlayer.stop(); mPlayer.release(); mPlayer = null; stopTimer(); setState(IDLE_STATE); } public void stop() { stopRecording(); stopPlayback(); } public boolean onError(MediaPlayer mp, int what, int extra) { stop(); setError(SDCARD_ACCESS_ERROR); return true; } public void onCompletion(MediaPlayer mp) { stop(); } private void setState(int state) { if (state == mState) return; mState = state; signalStateChanged(mState); } private void signalStateChanged(int state) { if (mOnStateChangedListener != null) mOnStateChangedListener.onStateChanged(state); } private void setError(int error) { if (mOnStateChangedListener != null) mOnStateChangedListener.onError(error); } public void setStoragePath(String path) { mStoragePath = path; } /*** * * @param flag if flag is true,it will record the file length, or it will * record the length the recorder file already played. */ private void startTimer(final boolean flag) { if (mTimerTask == null) { mTimerTask = new TimerTask() { @Override public void run() { if (flag) { mSampleLength++; } else { mSamplePlayLength++; } } }; } if (service != null && mTimerTask != null) mScheduled = service.scheduleAtFixedRate(mTimerTask,0,1,TimeUnit.SECONDS); } private void stopTimer() { if (mScheduled != null) { mScheduled.cancel(true); mScheduled = null; } if (mTimerTask != null) { mTimerTask.cancel(); mTimerTask = null; } }}
0 0
- Android 谨慎使用Timer定时器
- Android程序中使用定时器Timer
- Android程序中使用定时器Timer
- Android中Timer定时器的使用
- java,android定时器(Timer)的使用
- Android 定时器Timer例子
- Android定时器Timer.schedule
- Android:Timer定时器
- Android Timer定时器
- Android Timer定时器
- Android定时器Timer.schedule
- Android定时器Timer
- 使用Timer实现定时器
- Delphi-Timer定时器使用
- timer 定时器的使用
- flex Timer定时器使用
- Timer定时器使用
- LDD3 Timer定时器使用
- 北京最好的整形医院-煤炭总医院美容整形中心
- 智能家居通用管理平台(一)-架构设计理念
- 计数,基数排序
- vs2012 编译 zlib 1.2.8
- js知识点
- Android 谨慎使用Timer定时器
- 敌使永苑参苍褐兑疑蛔哦汛辛鲁粗
- Ubuntu 14.04 配置php+nginx+mysql
- 寻找邻域内极大值及其坐标
- 在C#中 IPAddresss.Parse 的异常与处理方式
- hdu1022
- android camera(二):摄像头工作原理、s5PV310 摄像头接口(CAMIF)
- android 监听apk安装替换卸载广播
- 浏览器关闭事件 处理