按下后退按钮在片段中给出 NullPointerException

Back button pressed gives NullPointerException in fragment

在我的应用程序中,我使用 activity MainActivity 并使用这个 activity 我开始 FragmentTransaction 这让我需要片段屏幕名称 WelcomescreenWelcomescreen 片段中,我使用处理程序以固定时间间隔移动到下一个片段。

问题是当我按下 Welcomescreen 片段上的后退按钮退出应用程序时,它给我 java.lang.NullPointerException.



那么为什么它在拖曳 java.lang.NullPointerException 以及如何消除这个错误?

MainActivity.java

    package com.example.gk;

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

    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.FrameLayout;

    public class MainActivity extends AppCompatActivity {

        //private static final int CONTENT_VIEW_ID = 10101010;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
             FrameLayout frame = new FrameLayout(this);

                frame.setId(R.id.listcontainer);
                setContentView(frame, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));


                if (savedInstanceState == null) {
                    FragmentManager fragmentManager = getSupportFragmentManager();
                    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                    Welcomescreen welcome = new Welcomescreen();
                    fragmentTransaction.add(R.id.listcontainer, welcome);
                    fragmentTransaction.commit();
                }
            }



        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, 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();
            if (id == R.id.action_settings) {
                return true;
            }
            return super.onOptionsItemSelected(item);
        }

    }

Welcomescreen.java

package com.example.gk;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class Welcomescreen extends android.support.v4.app.Fragment implements OnClickListener {
    Handler handler;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View view = inflater.inflate(R.layout.activity_main, container,false);
        ImageView welcomeimage = (ImageView)view.findViewById(R.id.welome_image);
        welcomeimage.setOnClickListener(this);
        handler = new Handler();

        final Runnable r = new Runnable() {
            public void run() {

                    FragmentManager fragmentManager = getFragmentManager();
                    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                    MainMenu menu = new MainMenu();
                    fragmentTransaction.replace(R.id.listcontainer, menu );
                    fragmentTransaction.addToBackStack(null);
                    fragmentTransaction.commit();


            }
        };

        handler.postDelayed(r, 7000);
        return view;
    }




    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()){
        case R.id.welome_image:
            FragmentManager fragmentManager = getFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            MainMenu menu = new MainMenu();
            fragmentTransaction.replace(R.id.listcontainer, menu );
            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.commit();

        }
    }



}

Logcat:

10-08 14:26:51.195: W/dalvikvm(10252): threadid=1: calling UncaughtExceptionHandler
10-08 14:26:51.197: E/AndroidRuntime(10252): FATAL EXCEPTION: main
10-08 14:26:51.197: E/AndroidRuntime(10252): Process: com.example.gk, PID: 10252
10-08 14:26:51.197: E/AndroidRuntime(10252): java.lang.NullPointerException
10-08 14:26:51.197: E/AndroidRuntime(10252):    at com.example.gk.Welcomescreen.run(Welcomescreen.java:31)
10-08 14:26:51.197: E/AndroidRuntime(10252):    at android.os.Handler.handleCallback(Handler.java:808)
10-08 14:26:51.197: E/AndroidRuntime(10252):    at android.os.Handler.dispatchMessage(Handler.java:103)
10-08 14:26:51.197: E/AndroidRuntime(10252):    at android.os.Looper.loop(Looper.java:193)
10-08 14:26:51.197: E/AndroidRuntime(10252):    at android.app.ActivityThread.main(ActivityThread.java:5299)
10-08 14:26:51.197: E/AndroidRuntime(10252):    at java.lang.reflect.Method.invokeNative(Native Method)
10-08 14:26:51.197: E/AndroidRuntime(10252):    at java.lang.reflect.Method.invoke(Method.java:515)
10-08 14:26:51.197: E/AndroidRuntime(10252):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:825)
10-08 14:26:51.197: E/AndroidRuntime(10252):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641)
10-08 14:26:51.197: E/AndroidRuntime(10252):    at dalvik.system.NativeStart.main(Native Method)

当您按下后退按钮时 activity 获取(暂停|停止|销毁)并且 activity 的对象引用然后引用空指针。 Welcomescreen 片段中的线程 运行 需要 activity 引用,但它是空的。

检查以下代码中的注释:

final Runnable r = new Runnable() {
        public void run() { 

                FragmentManager fragmentManager = getFragmentManager(); // This line will throw exception as getFragmentManager() method uses activity reference.
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                MainMenu menu = new MainMenu();
                fragmentTransaction.replace(R.id.listcontainer, menu );
                fragmentTransaction.addToBackStack(null);
                fragmentTransaction.commit();


        } 
    };

强烈建议片段之间的所有交互都通过容器activity。

  1. 在欢迎片段的附件中保存对欢迎 activity 的引用。
  2. 在 activity 中创建一个 public 方法来改变当前 片段,然后在片段中调用此方法(取决于 click\time间隔)。
  3. 在这个方法中调用片段管理器的逻辑来改变当前片段。

您还可以通过实现一个接口来实现此行为,该接口更改片段并将连接与欢迎 activity 分离。

能否在 Welcomescreen Fragment 中添加以下代码?

@Override
public void onStop() {
    if (handler != null) {
        handler.removeCallbacks(r);
    }
    super.onStop();
}

希望对您有所帮助。