我在ViewPager遇到了一个奇怪的事情。我用谷歌搜索,但没有找到任何有用的东西
所以我发布了我在这里遇到的内容,也许以后有人会遇到同样的问题,或者幸运的是一些天才家伙可以解决它。
情况如下:
演示应用程序中有两个页面。
但是当崩溃时,那么事情很糟糕。应用程序再次崩溃 这真让我烦恼 在HomeActivity中,viewpager有一个ViewPager.OnPageChangeListener 当页面改变时,将在onPageSelected方法中调用特定位置片段的方法 该方法将设置片段mValueTv的值。在正常情况下,它工作正常,但是当崩溃时,该方法抛出java.lang.NullPointerException异常。
05-06 21:37:24.392 17120-17120/com.rxread.viewpagerissue E/MessageQueue-JNI﹕ java.lang.NullPointerException
at com.rxread.viewpagerissue.PlusOneFragment.onPageSeleted(PlusOneFragment.java:49)
at com.rxread.viewpagerissue.HomeActivity$1.onPageSelected(HomeActivity.java:33)
at android.support.v4.view.ViewPager.scrollToItem(ViewPager.java:571)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:555)
at android.support.v4.view.ViewPager.onTouchEvent(ViewPager.java:2022)
at android.view.View.dispatchTouchEvent(View.java:7725)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2212)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1945)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2242)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1536)
at android.app.Activity.dispatchTouchEvent(Activity.java:2458)
at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:59)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2190)
at android.view.View.dispatchPointerEvent(View.java:7905)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4009)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3888)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3499)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3575)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3632)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3499)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5657)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5637)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5608)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5815)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:138)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:5081)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
at dalvik.system.NativeStart.main(Native Method)
因为代码太多,所以我打包了。 The demo link is 。
我真的希望有人可以帮助我。
非常感谢。
HomeActivity
public class HomeActivity extends ActionBarActivity {
ViewPager mViewpager;
BaseTabHostPagerAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mViewpager= (ViewPager) this.findViewById(R.id.home_ivp);
mViewpager.setOnPageChangeListener(new ViewPager.OnPageChangeListener(){
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
Object object=mAdapter.getItem(i);
if(object instanceof PlusOneFragment){
((PlusOneFragment)object).onPageSeleted(i);
}
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
mAdapter=new BaseTabHostPagerAdapter(getSupportFragmentManager());
mViewpager.setAdapter(mAdapter);
mAdapter.addPager("new 1", PlusOneFragment.newInstance("new 1"));
mAdapter.addPager("new 2",PlusOneFragment.newInstance("new 2"));
mAdapter.addPager("new 3",PlusOneFragment.newInstance("new 3"));
mAdapter.addPager("new 4", PlusOneFragment.newInstance("new 4"));
mAdapter.addPager("new 5", PlusOneFragment.newInstance("new 5"));
mAdapter.notifyDataSetChanged();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_home, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
AboutActivity.actionTo(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}
AboutActivity
public class AboutActivity extends ActionBarActivity {
public static void actionTo(Context context){
Intent intent=new Intent(context,AboutActivity.class);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
TextView mClickToCrash= (TextView) findViewById(R.id.about_to_crash_tv);
mClickToCrash.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int exception=2-2;
int a=3/exception;
Toast.makeText(AboutActivity.this, "GO EXCEPTION" + a, Toast.LENGTH_SHORT).show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_about, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
PlusOneFragment
public class PlusOneFragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private String mParam1;
private TextView mValueTv;
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @return A new instance of fragment PlusOneFragment.
*/
// TODO: Rename and change types and number of parameters
public static PlusOneFragment newInstance(String name) {
PlusOneFragment fragment = new PlusOneFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, name);
fragment.setArguments(args);
return fragment;
}
public PlusOneFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
}
}
public void onPageSeleted(int position){
mValueTv.setText("onPageSeleted-Value:" +position+"--"+ SystemClock.currentThreadTimeMillis());
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_plus_one, container, false);
TextView textView= (TextView) view.findViewById(R.id.fragment_name);
textView.setText(mParam1);
mValueTv= (TextView) view.findViewById(R.id.fragment_value);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mValueTv.setText("Value:"+ SystemClock.currentThreadTimeMillis());
Toast.makeText(v.getContext(),"Toast",Toast.LENGTH_SHORT).show();
}
});
return view;
}
@Override
public void onResume() {
super.onResume();
}
ViewPagerIssueApplication
public class ViewPagerIssueApplication extends Application{
@Override
public void onCreate() {
super.onCreate();
CrashHandler handler = CrashHandler.getInstance();
handler.init(getApplicationContext());
Thread.setDefaultUncaughtExceptionHandler(handler);
}
}
CrashHandler
public class CrashHandler implements UncaughtExceptionHandler {
private static CrashHandler myCrashHandler;
private Context mContext;
private CrashHandler() {
}
public static synchronized CrashHandler getInstance() {
if (myCrashHandler != null) {
return myCrashHandler;
} else {
myCrashHandler = new CrashHandler();
return myCrashHandler;
}
}
public void init(Context context) {
mContext = context;
}
@Override
public void uncaughtException(Thread arg0, Throwable exception) {
StringWriter stackTrace = new StringWriter();
exception.printStackTrace(new PrintWriter(stackTrace));
System.err.println(stackTrace);
System.exit(1);
}
}
BaseTabHostPagerAdapter
public class BaseTabHostPagerAdapter extends FragmentPagerAdapter {
private List<String> names = new ArrayList<String>();
private List<Fragment> fragments = new ArrayList<Fragment>();
public BaseTabHostPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
if(position > fragments.size()){
return null;
}
return fragments.get(position);
}
public List<Fragment> getFragmentsList(){
return fragments;
}
@Override
public int getCount() {
return fragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
if(position > names.size()){
return null;
}
return names.get(position);
}
public void addPager(String tabStr,Fragment fragment) {
if (fragment != null) {
fragments.add(fragment);
names.add(tabStr);
}
}
public void setTab(int location, String tab){
if(location<0||location>names.size()){
return;
}
if(null!=tab){
names.remove(location);
names.add(location, tab);
}
}
}
答案 0 :(得分:0)
最后,在我的团队负责人的帮助下,我发现当HomeActivity崩溃回HomeActivity时,一些片段没有附加到HomeActivity上。
在onCreateView方法之前调用onPageSelected方法
解决方案是在PlusOneFragment的onPageSeleted方法中进行getActivity null检查。
public void onPageSeleted(int position) {
if (getActivity() == null) {
return;
}
mValueTv.setText("onPageSeleted-Value:" + position + "--" + SystemClock.currentThreadTimeMillis());
}