アンダーBackPressed
を使用する際にいくつか問題があります。説明するために、まず、コードは次のようにレイヤーにドリルダウンされます。ActivityGroup
TabHost
TabGroupActivity クラス
以下TabGroupActivity.java
は、オンラインチュートリアルから参照されています。
public class TabGroupActivity extends ActivityGroup
{
private ArrayList<String> mIdList;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (mIdList == null) mIdList = new ArrayList<String>();
}
/**
* This is called when a child activity of this one calls its finish method.
* This implementation calls {@link LocalActivityManager#destroyActivity} on the child activity
* and starts the previous activity.
* If the last child activity just called finish(),this activity (the parent),
* calls finish to finish the entire group.
*/
@Override
public void finishFromChild(Activity child)
{
LocalActivityManager manager = getLocalActivityManager();
int index = mIdList.size()-1;
if (index < 1)
{
finish();
return;
}
manager.destroyActivity(mIdList.get(index), true);
mIdList.remove(index); index--;
String lastId = mIdList.get(index);
Activity a = manager.getActivity(lastId);
Intent lastIntent = a.getIntent(); // LINE 49
Window newWindow = manager.startActivity(lastId, lastIntent);
setContentView(newWindow.getDecorView());
}
/**
* Starts an Activity as a child Activity to this.
* @param Id Unique identifier of the activity to be started.
* @param intent The Intent describing the activity to be started.
* @throws android.content.ActivityNotFoundException.
*/
public void startChildActivity(String Id, Intent intent)
{
Window window = getLocalActivityManager().startActivity(Id,intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
if (window != null)
{
mIdList.add(Id);
setContentView(window.getDecorView());
}
}
/**
* The primary purpose is to prevent systems before android.os.Build.VERSION_CODES.ECLAIR
* from calling their default KeyEvent.KEYCODE_BACK during onKeyDown.
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK)
{
//preventing default implementation previous to android.os.Build.VERSION_CODES.ECLAIR
return true;
}
return super.onKeyDown(keyCode, event);
}
/**
* Overrides the default implementation for KeyEvent.KEYCODE_BACK
* so that all systems call onBackPressed().
*/
@Override
public boolean onKeyUp(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK)
{
onBackPressed(); //LINE 88
return true;
}
return super.onKeyUp(keyCode, event);
}
/**
* If a Child Activity handles KeyEvent.KEYCODE_BACK.
* Simply override and add this method.
*/
@Override
public void onBackPressed ()
{
int length = mIdList.size();
if ( length > 1)
{
Activity current = getLocalActivityManager().getActivity(mIdList.get(length-1));
current.finish(); //LINE 103
}
}
}
Tools_GroupActivity クラス
public class Tools_GroupActivity extends TabGroupActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
startChildActivity("Tools_index", new Intent(this, Tools_index.class));
}
}
Tools_index.class
これは 9 つのボタンがあるページです。たとえば、ボタン 1 を押すと、次のクラスがTools_1_diamond
呼び出されます。
public void tools_button1_click (View view)
{
Intent edit = new Intent(getParent(), Tools_1_Diamond.class);
TabGroupActivity parentActivity = (TabGroupActivity)getParent();
parentActivity.startChildActivity("Tools_1_Diamond", edit);
}
Tools_1_diamond
クラス内
Tools_index
レイアウトには、次のようにページに戻ることができるボタンがあります。
public void button_tools_subpage_back_click (View view)
{
Intent edit = new Intent(getParent(), Tools_index.class);
TabGroupActivity parentActivity = (TabGroupActivity)getParent();
parentActivity.startChildActivity("Tools_index", edit);
}
@Override
public void onBackPressed()
{
Intent edit = new Intent(getParent(), Tools_index.class);
TabGroupActivity parentActivity = (TabGroupActivity)getParent();
parentActivity.startChildActivity("Tools_index", edit);
}
問題の再現:
ケース A:
1. クラスで自作のボタンを押すとTools_1_Diamond
、(バックプレスの代わりに) アプリは適切にページに戻ることができTools_index
ます。
次に、ページ内で、この時点でユーザーが BackPressed ボタンを押すと、アプリはページに
Tools_index
戻り、Tools_1_Diamond
さらにBackPressボタンを押すとエラー
FATAL EXCEPTION: main java.lang.NullPointerException
になります。
ケース B: 自作の戻るボタンに触れずに BackPress だけをずっと使用すると、すべてがスムーズに実行されます。
質問/意図:
問題は、自己設計されたボタンが BackPress メソッドと同様に ArrayList を削減しないことだと思います...しかし...
これはどのように解決できますか?自己設計の戻るボタンまたは BackPress メソッドのいずれかを押すとページに戻り、Tools_index
ページで BackPress をさらに押すと反応がないか、ユーザーに尋ねるTools_index
ポップアップが表示されることをユーザーに提供したいと思います。alertDialog
アプリを終了したい。
ログキャット:
06-19 22:40:03.570: D/webviewglue(23395): nativeDestroy view: 0x51909960
06-19 22:40:06.585: D/AndroidRuntime(23395): Shutting down VM
06-19 22:40:06.585: W/dalvikvm(23395): threadid=1: thread exiting with uncaught exception (group=0x40fe72a0)
06-19 22:40:06.670: E/AndroidRuntime(23395): FATAL EXCEPTION: main
06-19 22:40:06.670: E/AndroidRuntime(23395): java.lang.NullPointerException
06-19 22:40:06.670: E/AndroidRuntime(23395): at com.abc.abc_v1.TabGroupActivity.finishFromChild(TabGroupActivity.java:49)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.app.Activity.finish(Activity.java:4215)
06-19 22:40:06.670: E/AndroidRuntime(23395): at com.abc.abc_v1.TabGroupActivity.onBackPressed(TabGroupActivity.java:103)
06-19 22:40:06.670: E/AndroidRuntime(23395): at com.abc.abc_v1.TabGroupActivity.onKeyUp(TabGroupActivity.java:88)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.view.KeyEvent.dispatch(KeyEvent.java:2729)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.app.Activity.dispatchKeyEvent(Activity.java:2431)
06-19 22:40:06.670: E/AndroidRuntime(23395): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2033)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1363)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1363)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1363)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.widget.TabHost.dispatchKeyEvent(TabHost.java:309)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1363)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1363)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1363)
06-19 22:40:06.670: E/AndroidRuntime(23395): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:2106)
06-19 22:40:06.670: E/AndroidRuntime(23395): at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1466)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.app.Activity.dispatchKeyEvent(Activity.java:2426)
06-19 22:40:06.670: E/AndroidRuntime(23395): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2033)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3852)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.view.ViewRootImpl.handleImeFinishedEvent(ViewRootImpl.java:3800)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:2935)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.os.Handler.dispatchMessage(Handler.java:99)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.os.Looper.loop(Looper.java:137)
06-19 22:40:06.670: E/AndroidRuntime(23395): at android.app.ActivityThread.main(ActivityThread.java:4921)
06-19 22:40:06.670: E/AndroidRuntime(23395): at java.lang.reflect.Method.invokeNative(Native Method)
06-19 22:40:06.670: E/AndroidRuntime(23395): at java.lang.reflect.Method.invoke(Method.java:511)
06-19 22:40:06.670: E/AndroidRuntime(23395): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
06-19 22:40:06.670: E/AndroidRuntime(23395): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
06-19 22:40:06.670: E/AndroidRuntime(23395): at dalvik.system.NativeStart.main(Native Method)