无法暂停 activity。 NPE

Unable to pause activity. NPE

当我使用主页按钮或切换到横向时,我捕获了运行时异常:无法暂停activity。 NullPointerException。 请帮助。

01-14 09:23:49.435: E/AndroidRuntime(331): FATAL EXCEPTION: main 01-14 09:23:49.435: E/AndroidRuntime(331): java.lang.RuntimeException: Unable to pause activity {com.example.actiontest/com.example.actiontest.MainActivity}: java.lang.NullPointerException 01-14 09:23:49.435: E/AndroidRuntime(331): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2354) 01-14 09:23:49.435: E/AndroidRuntime(331): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2311) 01-14 09:23:49.435: E/AndroidRuntime(331): at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2291) 01-14 09:23:49.435: E/AndroidRuntime(331): at android.app.ActivityThread.access00(ActivityThread.java:117) 01-14 09:23:49.435: E/AndroidRuntime(331): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:938) 01-14 09:23:49.435: E/AndroidRuntime(331): at android.os.Handler.dispatchMessage(Handler.java:99) 01-14 09:23:49.435: E/AndroidRuntime(331): at android.os.Looper.loop(Looper.java:123) 01-14 09:23:49.435: E/AndroidRuntime(331): at android.app.ActivityThread.main(ActivityThread.java:3683) 01-14 09:23:49.435: E/AndroidRuntime(331): at java.lang.reflect.Method.invokeNative(Native Method) 01-14 09:23:49.435: E/AndroidRuntime(331): at java.lang.reflect.Method.invoke(Method.java:507) 01-14 09:23:49.435: E/AndroidRuntime(331): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 01-14 09:23:49.435: E/AndroidRuntime(331): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 01-14 09:23:49.435: E/AndroidRuntime(331): at dalvik.system.NativeStart.main(Native Method) 01-14 09:23:49.435: E/AndroidRuntime(331): Caused by: java.lang.NullPointerException 01-14 09:23:49.435: E/AndroidRuntime(331): at android.support.v4.app.FragmentManagerImpl.saveFragmentBasicState(FragmentManager.java:1576) 01-14 09:23:49.435: E/AndroidRuntime(331): at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1617) 01-14 09:23:49.435: E/AndroidRuntime(331): at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:481) 01-14 09:23:49.435: E/AndroidRuntime(331): at com.actionbarsherlock.app.SherlockFragmentActivity.onSaveInstanceState(SherlockFragmentActivity.java:126) 01-14 09:23:49.435: E/AndroidRuntime(331): at android.app.Activity.performSaveInstanceState(Activity.java:1037) 01-14 09:23:49.435: E/AndroidRuntime(331): at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1181) 01-14 09:23:49.435: E/AndroidRuntime(331): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2336) 01-14 09:23:49.435: E/AndroidRuntime(331): ... 12 more

MainActivity.java

package com.example.actiontest;

import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.SherlockFragmentActivity;

public class MainActivity extends    SherlockFragmentActivity 
                          implements ActionBar.TabListener {

    private ViewPager viewPager;
    private TabsPagerAdapter mAdapter;
    private ActionBar actionBar;
    // Tab titles
    private String[] tabs = { "Top Rated", "Games", "Movies" };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Initilization
        actionBar = getSupportActionBar();
        viewPager = (ViewPager) findViewById(R.id.pager);

        mAdapter = new TabsPagerAdapter(getSupportFragmentManager());

        viewPager.setAdapter(mAdapter);
        //actionBar.setHomeButtonEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);  

        // Adding Tabs
        for (String tab_name : tabs) {
            actionBar.addTab(actionBar.newTab().setText(tab_name)
                    .setTabListener(this));
        }

        /**
         * on swiping the viewpager make respective tab selected
         * */
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                // on changing the page
                // make respected tab selected
                actionBar.setSelectedNavigationItem(position);
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
            }
        });
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction transaction) {
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction transaction) {
        //mSelected.setText("Selected: " + tab.getText());
        viewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction transaction) {
    }
}

TabsPagerAdapter.java

package com.example.actiontest;

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

public class TabsPagerAdapter extends FragmentPagerAdapter {

    public TabsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int index) {

        switch (index) {
        case 0:
            // Top Rated fragment activity
            return new TopRatedFragment();
        case 1:
             // Top Rated fragment activity
            return new TopRatedFragment();
        case 2:
            // Top Rated fragment activity
            return new TopRatedFragment();
        }

        return null;
    }

    @Override
    public int getCount() {
        // get item count - equal to number of tabs
        return 3;
    }

}

TopRatedFragment.java

package com.example.actiontest;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.actionbarsherlock.app.SherlockFragment;

public class TopRatedFragment extends SherlockFragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_top_rated, container, false);

        return rootView;
    }
}

让你的 TabsPagerAdapter 扩展 FragmentStatePagerAdapter 而不是 FragmentPagerAdapter 就可以了。

切换到 FragmentStatePagerAdapter 不是正确的解决方案。 Android docs 明确表示

FragmentStatePagerAdapter is more useful when there are a large number of pages, working more like a list view. When pages are not visible to the user, their entire fragment may be destroyed, only keeping the saved state of that fragment. This allows the pager to hold on to much less memory associated with each visited page as compared to FragmentPagerAdapter at the cost of potentially more overhead when switching between pages.

因为,你只有三个页面使用 FragmentPagerAdapter 是正确的。

您的问题很可能源于使用旧版本的 v4 支持库。要测试是否是这种情况,只需将 TopRatedFragment#onSaveInstanceState() 方法重写为

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

如果这解决了您的问题,那么您的 v4 支持库版本在 FragmentManagerImpl#saveFragmentBasicState()

处存在以下错误
if (!f.mUserVisibleHint) {
    /*
    if (result == null) {
        result = new Bundle(); MISSING!
    }*/
    // Only add this if it's not the default value
    result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint);
}

result 未初始化但仍调用 putBoolean() 时抛出 NPE。