我正在调试我的应用程序,并获得一个“奇怪的”异常.它不一致,因此很难解决.我将在下面发布一些代码. 给出我的异常的类: private ArrayListString idList;@Overridepublic void onCreate( Bundle saved
给出我的异常的类:
private ArrayList<String> idList; @Override public void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); if ( idList == null ) { idList = new ArrayList<String>(); } } @Override public void finishFromChild( Activity child ) { LocalActivityManager manager = getLocalActivityManager(); int index = idList.size()-1; if ( index < 1 ) { finish(); return; } manager.destroyActivity( idList.get( index ), true ); idList.remove( index ); index--; String lastId = idList.get( index ); Activity lastActivity = manager.getActivity( lastId ); Intent lastIntent = lastActivity.getIntent(); Window newWindow = manager.startActivity( lastId, lastIntent ); setContentView( newWindow.getDecorView() ); } public void startChildActivity( String id, Intent intent ) { if ( "restart".equalsIgnoreCase( id ) ) { idList.clear(); } Window window = getLocalActivityManager().startActivity( id, intent.addFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP ) ); if ( window != null ) { idList.add( id ); setContentView( window.getDecorView() ); } } public Activity getCurrentActivity() { int length = idList.size(); if ( idList.isEmpty() ) { return null; } else { return getLocalActivityManager().getActivity( idList.get( length-1 ) ); } } @Override public boolean onKeyDown( int keyCode, KeyEvent event ) { if ( keyCode == KeyEvent.KEYCODE_BACK ) { return true; } return super.onKeyDown( keyCode, event ); } @Override public boolean onKeyUp( int keyCode, KeyEvent event ) { if ( keyCode == KeyEvent.KEYCODE_BACK ) { onBackPressed(); return true; } return super.onKeyUp( keyCode, event ); } @Override public void onBackPressed() { int length = idList.size(); if ( length > 1 ) { Activity current = getLocalActivityManager().getActivity( idList.get( length-1 ) ); current.finish(); } }
例外本身:
09-30 08:44:12.571: ERROR/AndroidRuntime(10557): FATAL EXCEPTION: main 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): java.lang.NullPointerException 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at com.dezide.android.troubleshooter.view.TabGroupActivity.finishFromChild(TabGroupActivity.java:46) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.app.Activity.finish(Activity.java:3290) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at com.dezide.android.troubleshooter.view.TabGroupActivity.onBackPressed(TabGroupActivity.java:106) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at com.dezide.android.troubleshooter.view.TabGroupActivity.onKeyUp(TabGroupActivity.java:93) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.view.KeyEvent.dispatch(KeyEvent.java:1281) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.app.Activity.dispatchKeyEvent(Activity.java:2075) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1673) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:796) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:796) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:796) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.widget.TabHost.dispatchKeyEvent(TabHost.java:275) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:796) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:796) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1697) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1111) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.app.Activity.dispatchKeyEvent(Activity.java:2070) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1673) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2493) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2463) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.view.ViewRoot.handleMessage(ViewRoot.java:1752) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.os.Handler.dispatchMessage(Handler.java:99) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.os.Looper.loop(Looper.java:144) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at android.app.ActivityThread.main(ActivityThread.java:4937) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at java.lang.reflect.Method.invokeNative(Native Method) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at java.lang.reflect.Method.invoke(Method.java:521) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 09-30 08:44:12.571: ERROR/AndroidRuntime(10557): at dalvik.system.NativeStart.main(Native Method)
问题是它并不总是在同一个地方失败.有时我会在异常发生之前按下20次,有时只有5次.
编辑:添加更多代码.
我的GuideActivity,您可以在其中创建步骤,并将每个步骤作为新活动启动:
public void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); if ( "startguide".equalsIgnoreCase( getIntent().getStringExtra( "action" ) ) ) { try { startGuide( getIntent().getStringExtra( "guide" ) ); } catch( Exception e ) { e.printStackTrace(); } } else if ( "nextstep".equalsIgnoreCase( getIntent().getStringExtra( "action" ) ) ) { String session = getIntent().getStringExtra( "session" ); String step = getIntent().getStringExtra( "step" ); String response = getIntent().getStringExtra( "response" ); try { nextGuideStep( session, step, response ); } catch( Exception e ) { e.printStackTrace(); } } } public GuideStep getCurrentStep() { return currentStep; } public void setCurrentStep( GuideStep currentStep ) { this.currentStep = currentStep; } public void startGuide( String name ) throws Exception { GuideStep guideStep = model.startGuide( name ); currentStep = guideStep; setContentView ( R.layout.main ); LinearLayout linearLayout = ( LinearLayout ) findViewById( R.id.linearLayout ); TextView stepTitle = ( TextView ) findViewById( R.id.stepTitle ); TextView explanation = ( TextView ) findViewById( R.id.explanation ); stepTitle.setText( guideStep.getStepTitle() ); if ( guideStep.getExplanation() != "" ) { explanation.setText( Html.fromHtml( guideStep.getExplanation() ) ); } responses = guideStep.getResponses(); ListView listView = new ListView( this ); linearLayout.addView( listView ); listView.setAdapter( new CustomAdapter( this, R.layout.list_item, responses ) ); listView.setTextFilterEnabled( true ); listView.setOnItemClickListener( new OnItemClickListener() { public void onItemClick( AdapterView<?> parent, View view, int position, long id ) { try { Intent i = new Intent().setClass( getParent(), GuideActivity.class ); i.putExtra( "action", "nextstep" ); i.putExtra( "session", currentStep.getSession() ); i.putExtra( "step", currentStep.getStep() ); i.putExtra( "response", currentStep.getResponse( position ).getId() ); TabGroupActivity parentActivity = ( TabGroupActivity )getParent(); parentActivity.startChildActivity( currentStep.getStepTitle(), i ); } catch( Exception e ) { e.printStackTrace(); } } }); } public void nextGuideStep( String session, String step, String responseId ) throws Exception { GuideStep guideStep = model.nextGuideStep( session, step, responseId ); currentStep = guideStep; setContentView ( R.layout.main ); LinearLayout linearLayout = ( LinearLayout ) findViewById( R.id.linearLayout ); TextView stepTitle = ( TextView ) findViewById( R.id.stepTitle ); TextView explanation = ( TextView ) findViewById( R.id.explanation ); TextView didThisAnswerYourQuestion = ( TextView ) findViewById( R.id.didThisAnswerYourQuestion ); ScrollView scrollView = ( ScrollView ) findViewById( R.id.scrollView ); stepTitle.setText( guideStep.getStepTitle() ); if ( guideStep.getExplanation() != "" ) { explanation.setText( Html.fromHtml( guideStep.getExplanation() ) ); } responses = guideStep.getResponses(); if ( guideStep.getStepTitle() != "" ) { ListView listView = new ListView( this ); linearLayout.addView( listView ); listView.setAdapter( new CustomAdapter( this, R.layout.list_item, responses ) ); listView.setTextFilterEnabled( true ); listView.setOnItemClickListener( new OnItemClickListener() { public void onItemClick( AdapterView<?> parent, View view, int position, long id ) { try { Intent i = new Intent().setClass( getParent(), GuideActivity.class ); i.putExtra( "action", "nextstep" ); i.putExtra( "session", currentStep.getSession() ); i.putExtra( "step", currentStep.getStep() ); i.putExtra( "response", currentStep.getResponse( position ).getId() ); TabGroupActivity parentActivity = ( TabGroupActivity )getParent(); parentActivity.startChildActivity( currentStep.getStepTitle(), i ); } catch( Exception e ) { e.printStackTrace(); } } }); } else { stepTitle.setVisibility( View.GONE ); didThisAnswerYourQuestion.setVisibility( View.GONE ); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT ); params.addRule( RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE ); params.height = 350; scrollView.setLayoutParams( params ); } } public boolean availableForFeedback() { return currentStep != null; }
}
我的开始活动:
public void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); try { populateSections(); } catch( Exception e ) { e.printStackTrace(); } } private void populateSections() throws Exception { setContentView( R.layout.sections ); ArrayList<XmlSection> sections = new ArrayList<XmlSection>(); Portal portal = model.getPortal(); sections = portal.getSections(); final ArrayList<XmlSection> tempSections = sections; ListView listView = ( ListView ) findViewById( R.id.sectionList ); listView.setAdapter( new CustomAdapter( this, R.layout.list_item, sections ) ); listView.setTextFilterEnabled( true ); listView.setOnItemClickListener( new OnItemClickListener() { public void onItemClick( AdapterView<?> parent, View view, int position, long id ) { try { Intent i = new Intent().setClass( SectionActivity.this, JAndroidTroubleshooterActivity.class ); i.putExtra( "name", tempSections.get( position ).getName() ); startActivity( i ); } catch( Exception e ) { e.printStackTrace(); } } }); }
我的主要活动启动的活动:
@Override public void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); Resources res = getResources(); TabHost tabHost = getTabHost(); TabHost.TabSpec spec; Intent intent; intent = new Intent().setClass( this, TabGroupGuideActivity.class ); intent.putExtra( "name", getIntent().getStringExtra( "name" ) ); spec = tabHost.newTabSpec( "guides" ).setIndicator( "Guides", res.getDrawable( R.drawable.guides ) ) .setContent( intent ); tabHost.addTab( spec ); intent = new Intent().setClass( this, TabGroupFaqActivity.class ); intent.putExtra( "name", getIntent().getStringExtra( "name" ) ); spec = tabHost.newTabSpec( "faqs" ).setIndicator( "FAQs", res.getDrawable( R.drawable.faq ) ) .setContent( intent ); tabHost.addTab( spec ); } private Activity getCurrentTab() { Activity activity = getLocalActivityManager().getActivity( getTabHost().getCurrentTabTag() ); return activity; } private void optionRestart() { if ( getCurrentTab() instanceof TabGroupFaqActivity ) { Intent i = new Intent().setClass( this, FaqActivity.class ); TabGroupFaqActivity activity = ( TabGroupFaqActivity ) getCurrentActivity(); i.putExtra( "name", activity.getCurrentSection() ); activity.startChildActivity( "restart", i ); } if ( getCurrentTab() instanceof TabGroupGuideActivity ) { Intent i = new Intent().setClass( this, GuideListActivity.class ); TabGroupGuideActivity activity = ( TabGroupGuideActivity ) getCurrentActivity(); i.putExtra( "name", activity.getCurrentSection() ); activity.startChildActivity( "restart", i ); } } private void optionFeedback() { if ( getCurrentTab() instanceof TabGroupFaqActivity ) { Activity currentTab = ( ( TabGroupFaqActivity ) getCurrentTab() ).getCurrentActivity(); Article currentArticle = ( ( FaqActivity ) currentTab ).getCurrentArticle(); if ( currentArticle != null ) { Intent i = new Intent().setClass( this, FeedbackActivity.class ); i.putExtra( "perform", "feedbackfaq" ); i.putExtra( "title", currentArticle.getTitle() ); startActivity( i ); } else { Toast toast = Toast.makeText( getApplicationContext(), "You have to select an article to submit feedback", 500 ); toast.show(); } } if ( getCurrentTab() instanceof TabGroupGuideActivity ) { Activity currentTab = ( ( TabGroupGuideActivity ) getCurrentTab() ).getCurrentActivity(); GuideStep currentStep = ( ( GuideActivity ) currentTab ).getCurrentStep(); if ( currentStep != null && "false".equalsIgnoreCase( currentStep.getTerminalStep() ) ) { Intent i = new Intent().setClass( this, FeedbackActivity.class ); i.putExtra( "perform", "feedbackguide" ); i.putExtra( "session", currentStep.getSession() ); i.putExtra( "action", currentStep.getStepTitle() ); i.putExtra( "title", currentStep.getGuideTitle() ); startActivity( i ); } else { Toast toast = Toast.makeText( getApplicationContext(), "You cannot submit feedback for the last step of a guide", 500 ); toast.show(); } } } private void optionHome() { Intent i = new Intent().setClass( this, SectionActivity.class ); i.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP ); startActivity( i ); } @Override public void onConfigurationChanged( Configuration newConfig ) { super.onConfigurationChanged( newConfig ); } @Override public boolean onCreateOptionsMenu( Menu menu ) { MenuInflater inflater = getMenuInflater(); inflater.inflate( R.menu.menu, menu ); return true; } @Override public boolean onOptionsItemSelected( MenuItem item ) { switch ( item.getItemId() ) { case R.id.menuRestart: optionRestart(); return true; case R.id.menuHome: optionHome(); return true; case R.id.menuFeedback: optionFeedback(); return true; default: return super.onOptionsItemSelected( item ); } }
我的标签组活动:
@Override public void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); currentSection = getIntent().getStringExtra( "name" ); startChildActivity( "GuideListActivity", new Intent( this, GuideListActivity.class ).putExtra( "name", getIntent().getStringExtra( "name" ) ) ); } public String getCurrentSection() { return currentSection; }
最后,我列出的活动指南:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
try { populateGuideList( getIntent().getStringExtra( "name" ) ); } catch( Exception e ) { e.printStackTrace(); } } public void populateGuideList( String name ) throws Exception { setContentView( R.layout.guides ); Section section = model.getSection( name ); guides = section.getGuides(); ListView listView = ( ListView ) findViewById( R.id.guideList ); listView.setAdapter( new CustomAdapter( this, R.layout.list_item, guides ) ); listView.setTextFilterEnabled( true ); listView.setOnItemClickListener( new OnItemClickListener() { public void onItemClick( AdapterView<?> parent, View view, int position, long id ) { try { XmlGuide guide = guides.get( position ); Intent i = new Intent().setClass( getParent(), GuideActivity.class ); i.putExtra( "guide", guide.getName() ); i.putExtra( "action", "startguide" ); TabGroupActivity parentActivity = ( TabGroupActivity )getParent(); parentActivity.startChildActivity( guide.getName(), i ); } catch( Exception e ) { e.printStackTrace(); } } }); }我认为这可能会有所帮助:
public void startChildActivity(String id, Intent intent) { id+=System.currentTimeMillis(); //rest of your code. }
编辑:需要一点阐述.
有活动A,B和C.
>你用Id“A”开始A
>然后你用Id“B”开始B
>然后你用Id“C”开始C
>并且从C开始,你再次启动另一个B的id为“B”的实例(它可以
发生,因为B可能是一个可能需要的ResultListScreen
多次加载更多类型按钮)
问题是在ArrayList< String>中从上一个B完成后的idList
manager.destroyActivity( idList.get( index ), true );
调用line来销毁具有id“B”的Activity,它在堆栈中是2.
B被删除,C被推.当你完成C并且堆栈中没有B但它的Id可用时是ArrayList< String> idList,你得到它的Activity,如果没有找到它是null.
就这样.
id+=System.currentTimeMillis();
在这行代码中,每次使用System的当前时间启动新Activity时,都会分配一个唯一的ID.