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統(tǒng)計上出現(xiàn)很多異常:
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這個方法中出現(xiàn)的異常,看源碼:
/**
* 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 時,當(dāng)前activity必須為棧底,也就是最底層的activity,如果其他activity沒有及時finish掉,就會出現(xiàn)異常,導(dǎo)致崩潰;nonRoot 為 true 時,不需要考慮當(dāng)前activity是否在棧底。看完源碼瞬間柳暗花明又一村,nice。
在這記錄一下,出現(xiàn)的手機機型:android 5.1.1 (22),OPPO:OPPO R7sm:arm64-v8a 特別注意!!!
補充說明:
經(jīng)過反復(fù)測試,如果設(shè)置為true,簽名打包之后會失效:
在第一次安裝后,activity管理棧似乎對進(jìn)入的activity不做任何判斷與標(biāo)記(是否是棧頂?shù)腶ctivity),每次都會入棧,在將棧清空后又回復(fù)正常(就是Task對activity做記錄了,哪個處于棧頂,是否在棧里等);
1、moveTaskToBack(true);不判斷當(dāng)前activity是否在棧底
2、moveTaskToBack(false);先判斷當(dāng)前activity是否在棧底
再根據(jù)第一次安裝,如果設(shè)為true,每次點擊icon,都會重啟app,如果設(shè)為false,則會找到棧內(nèi)的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);
}
/**
* 防止華為機型未加入白名單時按返回鍵回到桌面再鎖屏后幾秒鐘進(jìn)程被殺
*/
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();
}
}
總結(jié)
以上是生活随笔為你收集整理的android模拟器 后退键,MainActivity返回键模拟home效果,容易出现的问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android sqlitejian监听
- 下一篇: html 桌面截图,如何使用javasc