我正在调试我的应用程序,并获得一个“奇怪的”异常。它不一致,因此很难解决。我将在下面发布一些代码。
提供异常的类:
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();
}
}
});
}
答案 0 :(得分:7)
我认为这可能有所帮助:
public void startChildActivity(String id, Intent intent) {
id+=System.currentTimeMillis();
//rest of your code.
}
编辑:需要一点阐述。
有Activity
A
,B
和C
A
"A"
B
"B"
C
"C"
B
的另一个ID为"B"
的实例(可能会
发生,因为B
可能是可能需要的ResultListScreen
多次加载更多类型按钮)问题是ArrayList<String> idList
从上次B
manager.destroyActivity( idList.get( index ), true );
调用行来销毁具有标识Activity
的{{1}},其中堆栈为2。
删除"B"
并推送B
。当您完成C
并且堆叠中没有C
但其ID可用时为B
,如果没有,则ArrayList<String> idList
为Activity
找到。
就是这样。
null
在这行代码中,每次使用系统的当前时间开始新的id+=System.currentTimeMillis();
时,都会分配一个唯一的ID。
答案 1 :(得分:0)
NullPointerException主要发生在你试图指向不存在的东西时....例如:你忘记在资源文件夹中添加图像,并说setBackground(图像)或者你忘了提及一个活动清单文件并尝试使用Intent访问该活动。确保您拥有res文件夹中的所有资源以及清单文件中提到的所有活动
答案 2 :(得分:0)
我在这里找到了更好的解决方案:
http://code.google.com/p/android/issues/detail?id=12359
如果你正在做id+System.currentTimeMillis()
,你可能会遇到下一个问题: