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