无法暂停 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。
当我使用主页按钮或切换到横向时,我捕获了运行时异常:无法暂停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。