postDelayed源码分析 View.postDelayed 导致将Runnable添加到消息队列中,并在经过指定的时间后运行。runnable将在用户界面线程上运行。 上面通过判断 mAttachInfo 是否为空分为两种情况: 间接调用 ViewRootHandler 的 postDelayed 方法; 调用 ViewRootImpl.RunQueue 的 postDelayed 方法最终也是间接调用 ViewRootHandler 的 postDelayed 方法。 也就是说这里只能执行主线程中 postDelayed 中的 Runnable 。 View.postDelayed 最终都调用 ViewRootHandler.postDelayed 。
View的postDelayed方法深度思考这篇文章知识点的实践。 那么问题到底出在哪里,而且为什么postDelayed替换为post问题的复现概率降低了? 回顾之前View的postDelayed方法深度思考这篇文章中关于View.postDelayed小结中的描述: postDelayed方法调用的时候,如果当前的View没有依附在Window上的时候 在View的postDelayed方法深度思考这篇文章中关于mAttachInfo对于View.postDelayed的影响,也都进行了分析。这里我们捡主要的源码阅读一下。 ,因为post最后执行的也是postDelayed方法。
//execute the task } }; Timer timer = new Timer(); timer.schedule(task, delay); Handler + postDelayed new Handler().postDelayed(new Runnable(){ public void run() { //execute the task } handler.sendMessage(message); } }; 开始定时任务 timer.schedule(task, 2000, 2000); 取消定时任务 timer.cancel(); 采用Handler的postDelayed runnable=new Runnable() { @Override public void run() { //要做的事情 handler.postDelayed (this, 2000); } }; 开始定时任务 handler.postDelayed(runnable, 2000);//每两秒执行一次runnable.
static void post(Runnable r) { sHandler.post(r); } public static final boolean postDelayed sAlarm); sContext.startService(playAlarm); } }; return sHandler.postDelayed (Alarms.ALARM_INTENT_EXTRA, alarm); // context.startService(playAlarm); AsyncHandler.postDelayed (context, alarm, 10000); AsyncHandler.removeCallbacks(); // remove the AsyncHandler.postDelayed
运行一个任务也有多种形式,既可在UI线程中调用处理器对象的post或者postDelayed方法,也能另外开启分线程来执行Runnable对象。 override fun run() { count++ tv_result.text = "当前计数值为:$count" handler.postDelayed handler.post(counter) 内部类与匿名内部类这两种方式,其实内部都拥有类的完整形态,故而它们的run方法允许使用关键字this指代这个人物类,示例代码中的“handler.postDelayed 鉴于这点变化,该方式内部不可再调用处理器的post或者postDelayed方法,意味着此时任务实例无法重复调用自身。因此,采取了匿名函数方式的任务对象,适用于不需要重复刷新的场合。 恢复了圆括号的Kotlin调用代码如下所示: //第3点:如果是延迟执行任务,则可将匿名实例作为postDelayed的输入参数 handler.postDelayed({
bannerVp.setCurrentItem(1, false) } } } }) 三、自动滑动 这里采用了view的postDelayed 方法进行实现 bannerVp.postDelayed(mLooper,1000) mLooper是我定义的Runnable,后面会讲原因 private val mLooper = object : Runnable { override fun run() { bannerVp.currentItem = ++bannerVp.currentItem bannerVp.postDelayed onWindowFocusChanged(hasFocus: Boolean) { super.onWindowFocusChanged(hasFocus) if (hasFocus){ bannerVp.postDelayed bannerVp.removeCallbacks(mLooper) } MotionEvent.ACTION_UP -> { bannerVp.postDelayed
{ bannerVp.setCurrentItem(1, false) } } } })三、自动滑动bannerVp.postDelayed Runnable { override fun run() { bannerVp.currentItem = ++bannerVp.currentItem bannerVp.postDelayed onWindowFocusChanged(hasFocus: Boolean) { super.onWindowFocusChanged(hasFocus) if (hasFocus){ bannerVp.postDelayed bannerVp.removeCallbacks(mLooper) } MotionEvent.ACTION_UP -> { bannerVp.postDelayed 这里采用了view的postDelayed方法进行实现 mLooper是我定义的Runnable,后面会讲原因 滑动实现了,但启停时机也很重要 所以这里选用onWindowFocusChanged因为它在窗体失去和获得焦点的时候会通知我们
启动Runnable 一、采用Handler类的post方法 Handler常用的post方法有下面几种: post : 立即启动Runnable postDelayed : 延迟指定时间间隔后启动 postAtTime : 在指定时间启动Runnable removeCallbacks : 回收/移除指定的Runnable 二、使用View类的post方法 View类也提供了post和postDelayed onClick(View v) { mCount = 0; if (v.getId() == R.id.btn_handler) { mOffset = 10; mHandler.postDelayed (mRun, 500); } else if (v.getId() == R.id.btn_view) { mOffset = 10; tv_runnable.postDelayed(mRun 3、在Runnable内部postDelayed自身,并持续post若干周期刷新视图,可实现动画效果。
这里我们利用View.postDelayed方法延时替换图片,这样就能做到逐帧动画的效果了,然后在替换图片之前,强制回收ImageView当前bitmap就可以减少内存消耗了,废话少说,上代码。 } @SuppressWarnings("unused") private void play(final int pFrameNo) { mImageView.postDelayed mDurations[pFrameNo]); } private void playConstant(final int pFrameNo) { mImageView.postDelayed callback, 0); } private void playOnce(FinishCallback callback, int frameNo) { mImageView.postDelayed
= null) { timerHandler .postDelayed(serverRefresh, 5000); } } 2.做事情,清除之前的定时器,启动定时器。 public void run() { timerHandler .removeCallbacks(serverRefresh); timerHandler .postDelayed
@Overide public void run(){ MainApp.showToastMsg(view.getHeight()); } }) 用View.postDelayed ()方法来防止段时间内多次点击view而触发多次不必要的点击事件 view.setEnabled(false); view.postDelayed(new Runnable(){ @Override
public void onRefresh() { Log.i(TAG, "onRefresh: "); mRecyclerView.postDelayed public void onLoadMore() { Log.i(TAG, "onLoadMore: "); mRecyclerView.postDelayed mPullToRefreshLayout.endLoadMore(); } }, 1000); } }); mRecyclerView.postDelayed
在android中,经常用到的定时器主要有以下几种实现: 一、采用Handler与线程的sleep(long )方法 二、采用Handler的postDelayed(Runnable, long) 方法 二、采用Handler的postDelayed(Runnable, long) 方法 这个实现比较简单一些: 1. new Runnable(){ @Override public void run() { // TODO Auto-generated method stub //要做的事情 handler.postDelayed (this, 2000); } }; 2.启动计时器: handler.postDelayed(runnable, 2000);//每两秒执行一次runnable. 3.停止计时器: handler.removeCallbacks
recyclerView.canRun) { recyclerView.scrollBy(2, 2); recyclerView.postDelayed if (running) stop(); canRun = true; running = true; postDelayed if (running) stop(); canRun = true; running = true; postDelayed
fromUserName, String fromUserNameAtDomain, String sn, String sourceID, String targetID) { handler_.postDelayed commandFromUserName, String commandFromUserNameAtDomain, String sourceID, String targetID) { handler_.postDelayed ntsOnInviteAudioBroadcastException(String sourceID, String targetID, String errorInfo) { handler_.postDelayed @Overridepublic void ntsOnInviteAudioBroadcastTimeout(String sourceID, String targetID) { handler_.postDelayed 回调处理如下:@Overridepublic void ntsOnTerminateAudioBroadcast(String sourceID, String targetID) { handler_.postDelayed
因为Handler类总是处理异步任务,每当它postDelayed一个任务时,依据postDelayed的间隔都得等待一段时间,倘若页面在这期间退出,就导致异步任务Runnable持有的引用无法回收,Runnable 下面是预防此类内存泄漏的三个方法: 1、如果异步任务是由Handler对象的postDelayed方法发起,那么可用对应的removeCallbacks方法回收之,把消息对象从消息队列移除就行了。 (mRefresh, 10000); } else if (mType == 1) { //引用有释放 mHandler.postDelayed(mRefresh, 10000); } else if (mType == 2) { //静态弱引用 mMyHandler.postDelayed(mRunnableRefresh, 10000); } else if (mType == 3) { //线程弱引用 mMyHandler.postDelayed(mThreadRefresh, 10000); } super.onStart(); } @Override
void post(final Runnable runnable) { mHandler.post(runnable); } public static void postDelayed (final Runnable runnable, long nDelay) { mHandler.postDelayed(runnable, nDelay); } / onDestroy中执行HandlerThread的销毁操作 BackgroundThread.destroyThread(); 3、在BackgroudThread的生命周期内,任何地方都可以调用post或者postDelayed
使用post,postDelayed 添加委托,使用 removeCallbacks移除委托。 由上面的特性我们可以简单看出“handler类似一个容器对象,它携带了消息的集合和委托的集合”。 String text = ""; text = ""+_number++; _txt1.setText(text); //再次传递一个Runnable对象,类似产生一种递归效果 _handler.postDelayed (run1,1000); }}; 上面已经看到 _handler.postDelayed方法了,这个方法就是把 run1这个被委托的内容方法,post传递给hander。 OnClickListener(){ public void onClick(View arg0) { //传递一个Runnable对象,1秒后执行该对象的run方法 _handler.postDelayed
我们可以利用Handler的postDelayed方法来实现定时执行代码的功能。 // 开始定时执行任务 startTimerTask(); } private void startTimerTask() { handler.postDelayed textView.setText("定时任务已执行"); // 再次延迟执行任务,实现循环定时 handler.postDelayed 我们在startTimerTask方法中使用handler.postDelayed方法来实现定时执行任务的逻辑。这个示例中,我们每隔1秒更新一次UI,显示"定时任务已执行"。 ️
savedInstanceState); setContentView(R.layout.splash); Handler x = new Handler(); x.postDelayed } }转载 http://www.cnblogs.com/dawei/archive/2010/04/29/1724044.html 加载后使用Handler的postDelayed