为什么getActivity在ViewPager的Fragment中返回null?

时间:2016-08-11 09:05:26

标签: android android-fragments nullpointerexception android-viewpager null-pointer

我有一个MainActivity,从那里我有ViewPager有两个片段。我想从FragmentTwo更改FragmentOne视图的属性。所以我所拥有的是从FragmentTwo到MainActivity的回调方法。回调方法如下所示:

@Override
public void newMessage(String message) {

    CalculatorFragment calculatorFragment = (CalculatorFragment) fragmentPagerAdapter.getItem(CALCULATOR_FRAGMENT);

    switch (message){
        case SettingsFragment.CHANGE_COLOR:
           //((TextView)view.findViewById(R.id.textViewSum)).setTextColor(Color.RED);
            break;
        case SettingsFragment.NEW_PICTURE:
            calculatorFragment.setBackground();
            break;
        default:
            break;
    }
}

这一切都很好。当用户在FragmentTwo中选择一个新图片时,我调用FragmentOne(CalculatorFragment)方法setBackground来设置新图片。以下是setBackground方法的样子:

public void setBackground(){
    final Bitmap bitmap = new ImageSaver(getActivity()).load();

    if(bitmap != null){
        imageViewBackground.setImageBitmap(bitmap);

    }
}

这里通过加载图片得到一个nullpointer异常,因为getActivity()返回null。

修改 以下是我创建ViewPager的代码:

public static final int CALCULATOR_FRAGMENT = 0;
public static final int SETTINGS_FRAGMENT = 1;
public static final int FRAGMENTS = 2;

private FragmentPagerAdapter fragmentPagerAdapter;

private ViewPager viewPager;

private List<Fragment> fragments = new ArrayList<Fragment>();

private void initializeFragments(){
    fragments.add(CALCULATOR_FRAGMENT, new CalculatorFragment());
    fragments.add(SETTINGS_FRAGMENT, new SettingsFragment());

    fragmentPagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()){
        @Override
        public int getCount() {
            return FRAGMENTS;
        }
        @Override
        public Fragment getItem(final int position) {
            return fragments.get(position);
        }
    };

    viewPager = (ViewPager) findViewById(R.id.pager);

    viewPager.setAdapter(fragmentPagerAdapter);
}

编辑 Logcat:

08-11 11:38:38.189 21996-21996/com.tomhogenkamp.personalcalc E/AndroidRuntime: FATAL EXCEPTION: main
                                                                           Process: com.tomhogenkamp.personalcalc, PID: 21996
                                                                           java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65537, result=-1, data=Intent { dat=content: flg=0x1 }} to activity {com.tomhogenkamp.personalcalc/com.tomhogenkamp.personalcalc.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.support.v4.app.FragmentActivity.getApplicationContext()' on a null object reference
                                                                               at android.app.ActivityThread.deliverResults(ActivityThread.java:4013)
                                                                               at android.app.ActivityThread.handleSendResult(ActivityThread.java:4063)
                                                                               at android.app.ActivityThread.access$1400(ActivityThread.java:150)
                                                                               at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                               at android.os.Looper.loop(Looper.java:168)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5885)
                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
                                                                            Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.support.v4.app.FragmentActivity.getApplicationContext()' on a null object reference
                                                                               at com.tomhogenkamp.personalcalc.CalculatorFragment.setBackground(CalculatorFragment.java:558)
                                                                               at com.tomhogenkamp.personalcalc.MainActivity.newMessage(MainActivity.java:69)
                                                                               at com.tomhogenkamp.personalcalc.SettingsFragment.onActivityResult(SettingsFragment.java:118)
                                                                               at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:165)
                                                                               at android.app.Activity.dispatchActivityResult(Activity.java:6467)
                                                                               at android.app.ActivityThread.deliverResults(ActivityThread.java:4009)
                                                                               at android.app.ActivityThread.handleSendResult(ActivityThread.java:4063) 
                                                                               at android.app.ActivityThread.access$1400(ActivityThread.java:150) 
                                                                               at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448) 
                                                                               at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                               at android.os.Looper.loop(Looper.java:168) 
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5885) 
                                                                               at java.lang.reflect.Method.invoke(Native Method) 
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) 
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) 

nullpointer异常仅在应用程序有时在背景上然后重新打开时才会发生。所以它似乎与杀死进程的Android系统有关?

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

问题可能是FragmentOne在您看到FragmentTwo时未附加到您的活动中,因此没有(或null)引用它。请尝试以下代码;把它放在FragmentOne

里面
private Activity activity;

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof Activity) {
        activity = (Activity) context;
    }
}

public void setBackground(){
    final Bitmap bitmap = new ImageSaver(activity).load();

    if(bitmap != null){
        imageViewBackground.setImageBitmap(bitmap);
    }
}

如果这不起作用,请向我们展示ViewPager的适配器,如果它不包含在ViewPager中,则显示您创建片段的代码。

答案 1 :(得分:0)

好的,我知道这个帖子已经有一年了,你现在可能有更好的解决方案了。但我现在遇到了和你一样的问题,我刚刚采用了一个简单的(但也许不是最优雅的)解决方案,似乎效果很好。 首先,我在我的FragmentOne上添加了一个MainActivity字段,如下所示

private MainActivity dad;

然后我插入了一个这样的构造函数:

public FragmentOne(MainActivity ctx){
    this();
    this.dad = ctx;
}

另外,我还为api安全插入了一个空构造:

public FragmentOne(){
    super();
}

然后,在我通常会插入FragmentOne的Main活动中,我使用了带有MainActivity构造函数的构造函数。

new FragmentOne(this)

现在,您可以使用活动实例而不是getActivity()方法。

我把它测试,它完美地工作。

编辑:虽然这解决了我使用getActivity()方法的问题,但我仍然在onCreate()方法的ListView上设置了一些Null指针(有时它被正常调用,有时也会给我NPE问题。 所以,经过深思熟虑之后,我决定改变我的

@Override
public Fragment getItem(int pos) {
    if (pos == 0){
        return new FragmentOne();
    } else if (pos == 1) {
        return new FragmentTwo();
    }
}

List<Fragment>,因为你已经DID并且正在调用

@Override
public Fragment getItem(int pos) {
    return my_frags_list.get(pos);
}
像你一样。 在每个getItem调用中调用一个新的Fragment实例似乎很奇怪。在执行此List方式后,我的片段字段停止给我NPE。到现在为止还挺好。所以现在我唯一的想法是为什么ViewPagers上的Android示例建议在new FragmentInstance()解决方案的每个getItem(int pos)调用intead上使用List<Fragment>?谁知道呢。