56

我在這裏遇到了從片段內的按鈕開始活動的問題。 這裏是我的代碼:從片段開始活動會導致NullPointerException

ViewPagerAdapter.java

import java.util.List; 

import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentPagerAdapter; 

public class ViewPagerAdapter extends FragmentPagerAdapter { 

    private List<Fragment> fragments; 

    public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments) { 
     super(fm); 
     this.fragments = fragments; 
    } 

    @Override 
    public int getCount() { 
     return this.fragments.size(); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return this.fragments.get(position); 
    } 

} 

ViewPagerActivity.java

import java.util.List; 
import java.util.Vector; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.view.ViewPager; 
import android.util.Log; 
import com.package.here.Class1Overview; 
import com.package.here.Class1Overview; 
import com.package.here.Class1Overview; 

public class ViewPagerActivity extends FragmentActivity{ 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     super.setContentView(R.layout.viewpager); 

     ViewPager pager = (ViewPager)super.findViewById(R.id.my_viewpager); 
     pager.setAdapter(initialisePaging()); 
    } 

    private ViewPagerAdapter initialisePaging() { 

     List<Fragment> fragments = new Vector<Fragment>(); 
     fragments.add(Fragment.instantiate(this, Class1Overview.class.getName())); 
     fragments.add(Fragment.instantiate(this, Class2Overview.class.getName())); 
     fragments.add(Fragment.instantiate(this, Class3Overview.class.getName())); 
     return new ViewPagerAdapter(super.getSupportFragmentManager(), fragments);   
    } 

} 

Class1Overview.java(這裏是按鈕)

import android.content.Intent; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewGroup; 
import android.widget.Button; 
import android.widget.LinearLayout; 
import com.package.here.R; 

public class FuelOverview extends Fragment { 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     if (container == null) { 
      return null; 
     } 
     View v = (LinearLayout)inflater.inflate(R.layout.class_one_layout, container, false); 
     View AddBtn = v.findViewById(R.id.btn_add); 
     ((Button) AddBtn).setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Intent intent = new Intent(); 
       intent.setClass(getActivity(), ActivityToStart.class); 
       startActivity(intent); 
      } 
     }); 

     return v; 
    } 
} 

這是我logcat的

01-05 19:39:00.913: E/AndroidRuntime(10557): Uncaught handler: thread main exiting due to uncaught exception 
01-05 19:39:01.034: E/AndroidRuntime(10557): java.lang.RuntimeException: Unable to pause activity {com.package.here/com.package.here.ViewPagerActivity}: java.lang.NullPointerException 
01-05 19:39:01.034: E/AndroidRuntime(10557): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3162) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3119) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3102) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at android.app.ActivityThread.access$2400(ActivityThread.java:119) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1870) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at android.os.Handler.dispatchMessage(Handler.java:99) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at android.os.Looper.loop(Looper.java:123) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at android.app.ActivityThread.main(ActivityThread.java:4363) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at java.lang.reflect.Method.invokeNative(Native Method) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at java.lang.reflect.Method.invoke(Method.java:521) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at dalvik.system.NativeStart.main(Native Method) 
01-05 19:39:01.034: E/AndroidRuntime(10557): Caused by: java.lang.NullPointerException 
01-05 19:39:01.034: E/AndroidRuntime(10557): at android.support.v4.app.FragmentManagerImpl.saveFragmentBasicState(FragmentManager.java:1576) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1617) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:481) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at android.app.Activity.performSaveInstanceState(Activity.java:1022) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1180) 
01-05 19:39:01.034: E/AndroidRuntime(10557): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3144) 
01-05 19:39:01.034: E/AndroidRuntime(10557): ... 12 more 
01-05 19:39:01.423: I/dalvikvm(10557): threadid=7: reacting to signal 3 

ViewPager本身是工作的罰款。這似乎是暫停FragmentActivity的錯誤,但我無法弄清楚。我發現的唯一的事情是這個職位上谷歌http://code.google.com/p/android/issues/detail?id=19917

我還通過谷歌的示例代碼必須確保我主要是使用相同的技術......

編輯:以確保ClickListener的作品,我試着onClick方法中的吐司 - 完美運作。

+1

只是想出了以下內容: FragmentActivity崩潰時: - 按home鍵 - 打開設備 的方向 - 開始Avtivity - 調用完成工作正常 因此,目前這適用於我: 覆蓋onSaveInstanceState方法,而無需調用超級方法,你很好。除了事實,實例狀態沒有保存:D所以這不是一個真正的解決方案,但可以確定問題。 – Juke 2012-01-05 21:07:35

+0

我剛剛遇到了同樣的問題 - 對於我來說,問題是由於我在項目中添加了一個空白布局的新片段而引起的。看起來在代碼的某個地方,如果在onSaveInstanceState期間沒有任何內容保存到bundle中,它必須導致一個空指針異常。在我的佈局中添加一些視圖修復了這個問題(花了幾個小時將我的頭撞到了牆上)。我正在使用Android支持庫v4修訂版10. – 2012-09-05 04:26:09

+0

@Juke是否有可能使用碎片來獲得TabViewActivity的相同行爲,我想在選擇任何選項卡的碎片區域中打開一個新的活動? – CoDe 2012-10-06 07:07:53

回答

48

這是一個已知的問題,我很震驚地發現沒有人爲此提出了一個公共bug跟蹤器的bug。

您的問題源於此:

if (f.mSavedViewState != null) { 
    if (result == null) { 
     result = new Bundle(); 
    } 
    result.putSparseParcelableArray(
      FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState); 
} 
if (!f.mUserVisibleHint) { 
    // Only add this if it's not the default value 
    result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint); 
} 

你應該注意到,如果resultnull進入這個代碼和第一if沒有被觸發,你會得到一個NullPointerException,如果我們進入第二if

它應該閱讀:

if (f.mSavedViewState != null) { 
    if (result == null) { 
     result = new Bundle(); 
    } 
    result.putSparseParcelableArray(
      FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState); 
} 
if (!f.mUserVisibleHint) { 
    if (result == null) { 
     result = new Bundle(); 
    } 
    // Only add this if it's not the default value 
    result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint); 
} 

我提交了一個補丁此一兩個星期前:https://android-review.googlesource.com/31261

+0

這個問題的解決方案是什麼?我應該使用另一個庫嗎?我有同樣的問題。 – 2012-02-14 12:20:03

+0

修補bug,自己重新編譯支持庫,直到下一個版本出來。它的源代碼在'SDK/extras/android/support/v4/src /'中。 – 2012-02-14 13:06:47

+0

你能發佈步驟來重新編譯嗎? – 2012-02-14 13:48:54

62

快速修復是

class MyFragment extends Fragment { 

    @Override 
    public void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     setUserVisibleHint(true); 
    } 

,並等待在安全模式下更新: )

+0

謝謝!工作像一個魅力 – David 2012-03-13 20:03:17

+3

順便說一句,問題是由去年3月 - 2012年更新SupportPackage – Vadim 2012-04-05 10:12:17

+1

更正我仍然有這個問題截至23/4/2012 ..但這個答案很好地修復它 – 2012-04-23 17:52:26

32

根據帖子here,你應該是使用FragmentStatePagerAdapter而不是FragmentPagerAdapter。我遇到了你所描述的同樣的問題,並且讓這個開關對我有用。

+3

這對我很好。 – Ben 2012-08-10 19:57:23

+2

解決了我的問題 – starkej2 2012-09-21 14:20:06

+0

同樣在這裏。任何想法爲什麼是這樣? – 2013-03-31 19:14:45

4

我剛剛有同樣的問題 - 我的問題是當我用一個空的佈局向我的項目添加一個新的片段時造成的。看起來,如果在Fragment.onSaveInstanceState(Bundle outState)期間沒有任何內容保存到該軟件包,它會在FragmentManagerImpl.saveFragmentBasicState中導致空指針異常。

添加一些視圖到我的佈局解決了這個問題(花了我的頭撞牆後花了數小時)。使用android支持庫v4修訂版10。

此外,當使用ListView作爲片段佈局的根目錄時,如果listview沒有元素,您也會遇到崩潰。在片段類,覆蓋onSaveInstanceState像這樣把一些數據的包:

@Override 
public void onSaveInstanceState(Bundle outState) 
{ 
    super.onSaveInstanceState(outState); 
    outState.putString("DO NOT CRASH", "OK"); 
} 
+0

你和Vadim的解決方案都適合我。我正在使用支持v13 FragmentStatePageAdapter。儘管如此,你更有趣。 – 2015-04-16 21:36:42