android模拟器 后退键,MainActivity返回键模拟home效果,容易出现的问题

很多app都会将返回键模拟成home效果,代码如下:

@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

if (keyCode == KeyEvent.KEYCODE_BACK) {

IntentWrapper.onBackPressed(this);

moveTaskToBack(true);

}

return true;

}

return super.onKeyDown(keyCode, event);

}

这是之前写的代码,但是在bugtags统计上出现很多异常:

java.lang.NullPointerException: Attempt to invoke virtual method 'void com.android.server.am.TaskRecord.setTaskToReturnTo(int)' on a null object reference at android.os.Parcel.readException(Parcel.java:1565)

at android.os.Parcel.readException(Parcel.java:1512)

at android.app.ActivityManagerProxy.moveActivityTaskToBack(ActivityManagerNative.java:3291)

at android.app.Activity.moveTaskToBack(Activity.java:5088)

at com.icourt.alpha.activity.MainActivity.onKeyDown(MainActivity.java)

at android.view.KeyEvent.dispatch(KeyEvent.java:2651)

at android.app.Activity.dispatchKeyEvent(Activity.java:2785)

at android.support.v7.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java)

at android.support.v7.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java)

at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.dispatchKeyEvent(AppCompatDelegateImplBase.java)

at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2331)

at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4230)

at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4184)

at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3724)

at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3787)

at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3743)

at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3870)

at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3751)

at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3927)

at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3724)

at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3787)

at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3743)

at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3751)

at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3724)

at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3787)

at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3743)

at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3903)

at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:4064)

at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2218)

at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1859)

at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1850)

at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2195)

at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141)

at android.os.MessageQueue.nativePollOnce(Native Method)

at android.os.MessageQueue.next(MessageQueue.java:150)

at android.os.Looper.loop(Looper.java:139)

at android.app.ActivityThread.main(ActivityThread.java:5532)

at java.lang.reflect.Method.invoke(Native Method)

at java.lang.reflect.Method.invoke(Method.java:372)

at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)

在MainActivity.onKeyDown这个方法中出现的异常,看源码:

/**

* Move the task containing this activity to the back of the activity

* stack. The activity's order within the task is unchanged.

*

* @param nonRoot If false then this only works if the activity is the root

* of a task; if true it will work for any activity in

* a task.

*

* @return If the task was moved (or it was already at the

* back) true is returned, else false.

*/

public boolean moveTaskToBack(boolean nonRoot) {

try {

return ActivityManagerNative.getDefault().moveActivityTaskToBack(

mToken, nonRoot);

} catch (RemoteException e) {

// Empty

}

return false;

}

大概意思是说,nonRoot 为 false 时,当前activity必须为栈底,也就是最底层的activity,如果其他activity没有及时finish掉,就会出现异常,导致崩溃;nonRoot 为 true 时,不需要考虑当前activity是否在栈底。看完源码瞬间柳暗花明又一村,nice。

在这记录一下,出现的手机机型:android 5.1.1 (22),OPPO:OPPO R7sm:arm64-v8a 特别注意!!!

补充说明:

经过反复测试,如果设置为true,签名打包之后会失效:

在第一次安装后,activity管理栈似乎对进入的activity不做任何判断与标记(是否是栈顶的activity),每次都会入栈,在将栈清空后又回复正常(就是Task对activity做记录了,哪个处于栈顶,是否在栈里等);

1、moveTaskToBack(true);不判断当前activity是否在栈底

2、moveTaskToBack(false);先判断当前activity是否在栈底

再根据第一次安装,如果设为true,每次点击icon,都会重启app,如果设为false,则会找到栈内的activity,直接显示。

最终代码:

@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

if (keyCode == KeyEvent.KEYCODE_BACK) {

IntentWrapper.onBackPressed(this);

try {

moveTaskToBack(false);

} catch (Exception e) {

bugSync("返回键模拟HOME出错", e);

return super.onKeyDown(keyCode, event);

}

}

return super.onKeyDown(keyCode, event);

}

/**

* 防止华为机型未加入白名单时按返回键回到桌面再锁屏后几秒钟进程被杀

*/

public static void onBackPressed(Activity a) {

try {

Intent launcherIntent = new Intent(Intent.ACTION_MAIN);

launcherIntent.addCategory(Intent.CATEGORY_HOME);

a.startActivity(launcherIntent);

} catch (Throwable e) {

e.printStackTrace();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值