更改片段和使用回调时的NullPointerException

时间:2014-10-01 11:36:14

标签: java android android-fragments nullpointerexception callback

我有一个更改碎片的问题,我在操作栏中使用微调器来执行此操作,有时在alertdiaolog中按钮。当我按下按钮时,我有NullPointerException。 这是我的接口回调代码:

public interface Callback {
    public void load(String name);
}

这是我的第一个片段的代码,我在onCreateOptiontMenu中使用了微调器:

private Callback callback;

@Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        Log.d("TAG", "onAttach");
        try {
        callback = (Callback) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement interface");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        callback = null;
    }

public void onCreateOptionsMenu(Menu menu, MenuInflater inflate) {
        menu.clear();
        inflate.inflate(R.menu.kfu, menu);
        spinner = (Spinner) menu.findItem(R.id.action_spinner).getActionView()
                .findViewById(R.id.actionbar_spinner_change_map);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity()
                .getBaseContext(),
                android.R.layout.simple_spinner_dropdown_item, actions);
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view,
                    int position, long id) {
                Log.d("POSITION", "Position is = "+position);
                switch (position) {
                case 1: 
                    if (parent.getItemAtPosition(position).equals("VKNews")) {
                //      Log.d("Tag", callback.toString()+" "+ (callback == null) + " " + parent.getItemAtPosition(position));
                        callback.load("VKNews"); //305 line
                    }   
                }   
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                // TODO Auto-generated method stub

            }
        });
    }

在第二个片段中,我使用微调器,有时按钮来改变片段:

private Callback callback;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        Log.d("TAG", "onAttach");
        try {
        callback = (Callback) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement interface");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        callback = null;
    }

public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
...
if ((firstrun) || (account.access_token == null)) {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle("Авторизация")
                    .setMessage(
                            "для просмотра новостей необходимо авторизоваться.")
                    .setCancelable(false)
                    .setPositiveButton("Авторизоваться",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,
                                        int id) {
                                    editor1.putInt("isVk", 1).commit();
                                    editor1.apply();
                                    startLoginActivity();
                                }
                            })
                    .setNegativeButton("Отмена",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,
                                        int id) {           
                                    editor1.putInt("isVk", 0).commit();
                                    editor1.apply();
                                    Log.d("TAG", callback.toString());
                                    callback.load("KFUNews");
                                    Log.d("CHANGE", "change working");
                                    dialog.cancel();
                                }
                            });
            AlertDialog alert = builder.create();
            alert.show();
            // Save the state
            getActivity()
                    .getSharedPreferences("PREFERENCE",
                            getActivity().MODE_PRIVATE).edit()
                    .putBoolean("firstrun", false).commit();
        }
...
}


public void onCreateOptionsMenu(Menu menu, MenuInflater inflate) {
        if (account.access_token != null || isChangedStat) {
            inflate.inflate(R.menu.vk, menu);
            spinner = (Spinner) menu.findItem(R.id.action_spinner1).getActionView()
                    .findViewById(R.id.actionbar_spinner_change_map);
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity()
                    .getBaseContext(),
                    android.R.layout.simple_spinner_dropdown_item, actions);
            spinner.setAdapter(adapter);
            spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

                @Override
                public void onItemSelected(AdapterView<?> parent, View view,
                        int position, long id) {
                    Log.d("POSITION", "" + parent.getItemAtPosition(position));
                    switch (position) {
                    case 1:
                        if (parent.getItemAtPosition(position).equals("KFUNews")) {
                            callback.load("KFUNews");
                        }
                    }
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                    // TODO Auto-generated method stub

                }
            });

        } else {
            inflate.inflate(R.menu.vk1, menu);
            spinner = (Spinner) menu.findItem(R.id.action_spinner1).getActionView()
                    .findViewById(R.id.actionbar_spinner_change_map);
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity()
                    .getBaseContext(),
                    android.R.layout.simple_spinner_dropdown_item, actions);
            spinner.setAdapter(adapter);
            spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

                @Override
                public void onItemSelected(AdapterView<?> parent, View view,
                        int position, long id) {
                    Log.d("POSITION", "" + parent.getItemAtPosition(position));
                    switch (position) {
                    case 1:
                        if (parent.getItemAtPosition(position).equals("KFUNews")) {
                            callback.load("KFUNews");
                        }
                    }
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                    // TODO Auto-generated method stub

                }
            });
    }
        super.onCreateOptionsMenu(menu, inflate);
    }

我在305行的第一个片段有nullpointer这个callback.load(“VKNews”);

这是我的日志:

10-01 15:34:58.532: E/AndroidRuntime(2519): FATAL EXCEPTION: main
10-01 15:34:58.532: E/AndroidRuntime(2519): java.lang.NullPointerException
10-01 15:34:58.532: E/AndroidRuntime(2519):     at ru.fosslabs.mobilestudent.fragment.KFUFragment$3.onItemSelected(KFUFragment.java:305)
10-01 15:34:58.532: E/AndroidRuntime(2519):     at android.widget.AdapterView.fireOnSelected(AdapterView.java:892)
10-01 15:34:58.532: E/AndroidRuntime(2519):     at android.widget.AdapterView.access$200(AdapterView.java:49)
10-01 15:34:58.532: E/AndroidRuntime(2519):     at android.widget.AdapterView$SelectionNotifier.run(AdapterView.java:860)
10-01 15:34:58.532: E/AndroidRuntime(2519):     at android.os.Handler.handleCallback(Handler.java:730)
10-01 15:34:58.532: E/AndroidRuntime(2519):     at android.os.Handler.dispatchMessage(Handler.java:92)
10-01 15:34:58.532: E/AndroidRuntime(2519):     at android.os.Looper.loop(Looper.java:137)
10-01 15:34:58.532: E/AndroidRuntime(2519):     at android.app.ActivityThread.main(ActivityThread.java:5103)
10-01 15:34:58.532: E/AndroidRuntime(2519):     at java.lang.reflect.Method.invokeNative(Native Method)
10-01 15:34:58.532: E/AndroidRuntime(2519):     at java.lang.reflect.Method.invoke(Method.java:525)
10-01 15:34:58.532: E/AndroidRuntime(2519):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
10-01 15:34:58.532: E/AndroidRuntime(2519):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-01 15:34:58.532: E/AndroidRuntime(2519):     at dalvik.system.NativeStart.main(Native Method)

我的活动:

public class GeneralActivity extends Activity implements Callback {
...
    @Override
    public void load(String name) {
        FragmentTransaction transaction = getFragmentManager()
                .beginTransaction();
        Log.d("TAG", "transaction = " + transaction + " "
                + (transaction == null));
        if (name.equals("KFUNews")) {
            transaction.replace(R.id.general_fragment, kfu);
            transaction.commit();
            invalidateOptionsMenu();
        } else {
            transaction.replace(R.id.general_fragment, vkfrag);
            transaction.commit();
            invalidateOptionsMenu();
        }
    }
}

更新:它不适用于Android 4.2.2和4.3,4.8

2 个答案:

答案 0 :(得分:0)

活动可能正在实施错误的界面。回调是众多接口的名称。确保为界面使用唯一名称或更改GeneralActivity extends Activity implements Callback

GeneralActivity extends Activity implements ru.fosslabs.mobilestudent.fragment.KFUFragment.Callback

答案 1 :(得分:-1)

三种可能性:

  1. 在事件触发前未调用onAttach(),并且永远不会设置callback
  2. onAttach()被调用,但activity
  3. 的值为空
  4. 在事件之前的某个时刻调用detach()