2011-09-30 62 views
3

我正在調試我的應用程序,並得到一個'奇怪'的異常。這是不一致的,因此很難解決。我會在下面發佈一些代碼。NullPointerException返回時通過活動

,讓我異常類:

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; 
} 

而在去年,我的活動,列出指南:

公共無效的onCreate(捆綁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

你應該包括整個代碼,但如果沒有。 TabGroupActivity.java中的第46行是什麼? –

+0

第46行是Intent lastIntent = lastActivity.getIntent(); 我會繼續前進,並添加一些代碼:) –

回答

7

我想提到的所有活動,它可以幫助:

public void startChildActivity(String id, Intent intent) { 
    id+=System.currentTimeMillis(); 
    //rest of your code. 
} 

編輯:它需要一點點彈性通貨膨脹。

ActivityABC

  • 你開始A與標識"A"
  • 然後你開始B與標識"B"
  • 然後你開始C與編號"C"
  • 和由C您再次啓動另一個B w實例第i個ID "B"(它可能 發生,因爲B可能是ResultListScreen這可能要求 幾個時間載入更多類型的按鈕)

的問題是,在ArrayList<String> idList當你從去年B

manager.destroyActivity(idList.get(index), true); 
完成

行被稱爲破壞Activity ID爲"B",這是2堆棧。 兩個B都被刪除,並推送C。並且當您完成C並且堆棧中沒有B但其ID是可用的是ArrayList<String> idList並且您將得到它的Activity如果找不到null

就是這樣。

id+=System.currentTimeMillis(); 
在這行代碼

您每次使用系統的當前時間開始新Activity時間分配一個唯一的ID。

+0

這似乎解決了這個問題。這是什麼讓你認爲這解決了這個問題? –

+0

看到我編輯的答案 –

+0

我認爲這是問題所在。我沒有任何想法,因爲我真的不知道它可能會發生兩次。但謝謝你的幫助:)標記爲解決的答案。 –

0

NullPointerException異常主要發生:你忘了在資源文件夾添加圖像,並且說的setBackground(圖)也許你忘了提在清單文件和活動試圖訪問使用Intent.Make確保您擁有所有的資源在你的資源文件夾中的活性和清單文件

+0

正如我所提到的那樣。它在碰撞前可能運行20次,這導致我相信還有別的東西。它並不總是以同樣的步驟崩潰。 –

+0

你似乎使用putExtra傳遞一些參數。請檢查你是否使用Bundle在相應的活動 –

+0

中收到它們我正在這麼做:) 問題似乎是,如果第一次使用「未知」回答它,同一步驟可能會發生兩次。使我獨特的身份證不再那麼獨特。然後,當您按回並銷燬具有給定ID的活動時,您將銷燬這兩個活動,從而在到達同一活動時無法使用該活動。 –

0

我找到了更好的解決方案在這裏:

http://code.google.com/p/android/issues/detail?id=12359

如果你正在做id+System.currentTimeMillis()你可以得到在接下來的問題:

  1. A + B = C +有時D,所以有小您仍然可以獲得NPE的可能性
  2. 您需要將ID存儲在某處以便能夠關閉它