Android应用基于Seismic库的震动计数跳转页面异常问题
问题原因分析
你的问题核心在于每次触发onShake回调时,都会创建并提交一个独立的延迟跳转任务:
- 当你震动1次时,程序提交了一个1800ms后打开page1的任务;
- 紧接着震动第2次时,又提交了一个1800ms后打开page2的任务;
- 这两个任务会各自在延迟时间到期后执行,所以就出现了先跳page1、再跳page2的连续跳转问题,而非等待最终震动计数再跳转。
解决方案
解决思路很简单:每次新的震动触发时,取消之前还未执行的延迟任务,只保留基于最新震动计数的任务。这样只有最后一次震动对应的跳转任务会在延迟后执行,就能根据最终计数打开正确页面。
修改后的Home类代码
首先把Handler和Runnable改为Home类的成员变量,方便后续取消任务:
// 在Home类的成员变量区域添加 private Handler mShakeHandler = new Handler(); private Runnable mShakeRunnable;
然后修改onShake的逻辑:
mShakeDetector.setOnShakeListener(new ShakeDetector.OnShakeListener() { @Override public void onShake(final int count) { System.out.println(count); // 第一步:取消之前未执行的跳转任务 if (mShakeRunnable != null) { mShakeHandler.removeCallbacks(mShakeRunnable); } // 第二步:创建新的跳转任务,使用当前最新的count值 mShakeRunnable = new Runnable() { @Override public void run() { Intent targetIntent = null; switch(count) { case 1: targetIntent = new Intent(context, ttsScreen.class); break; case 2: targetIntent = new Intent(context, sttScreen.class); break; case 3: targetIntent = new Intent(context, cbbScreen.class); break; case 4: targetIntent = new Intent(context, ocrScreen.class); break; default: // 可以处理超过4次的情况,比如不跳转或者提示 break; } if (targetIntent != null) { // 如果context不是Activity,需要添加FLAG_ACTIVITY_NEW_TASK // targetIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(targetIntent); } } }; // 第三步:提交新的延迟任务 mShakeHandler.postDelayed(mShakeRunnable, 1800); } });
额外说明
- 这样修改后,每次震动都会“刷新”延迟任务,只有用户停止震动满1800ms后,才会根据最终的震动计数跳转页面;
- 如果你的
context不是Activity实例(比如Application上下文),启动Intent时需要添加Intent.FLAG_ACTIVITY_NEW_TASK标记,否则会抛出异常; - 你还可以根据需求调整延迟时间(1800ms),比如和ShakeDetector里的
SHAKE_COUNT_RESET_TIME_MS(3000ms)配合,让逻辑更统一。
内容的提问来源于stack exchange,提问作者ScuffedCoder
相关产品推荐
相关产品推荐

