无法在Java中初始化静态成员 - Android

时间:2016-04-19 06:58:02

标签: java android

我帮助class命名为Prefs,其中我class member interface的{​​{1}}静态SyncFinishedListener。这是他们:

public interface SyncFinishedListener {
    void onSyncFinished();
}

这是我的Prefs助手类

public class Prefs {
    public static final String TAG = Prefs.class.getSimpleName();
    private static final String PrefsName = Prefs.class.getSimpleName();

    SharedPreferences mPrefs;

    public Prefs(Context context) {
        super();
        mPrefs = context.getSharedPreferences(PrefsName, Context.MODE_PRIVATE);
    }

    private static SyncFinishedListener listener;

    public Prefs(Context context, SyncFinishedListener listener) {
        this(context);
        Prefs.listener = listener;
        SyncUtils.get(context).requestSync(HrEmployee.AUTHORITY);
    }

    private boolean isSyncFinished() {
        boolean isSyncFinished = (isHrEmployeeSyncFinished()
                && isHrAttendanceSyncFinished()
                && isAttReportSyncFinished()
                && isSchoolSchoolSyncFinished()
        );
        Log.e(TAG, "isSyncFinished is :" + isSyncFinished);
        if (isSyncFinished) {
            try {
                setHrEmployeeSyncFinished(false);
                setHrAttendanceSyncFinished(false);
                setAttReportSyncFinished(false);
                setSchoolSchoolSyncFinished(false);
                // Here's NullPointerException
                Prefs.listener.onSyncFinished();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return isSyncFinished;
    }

    private static final String HrEmployeeSyncFinished = "hrEmployeeSyncFinished";
    private static final String HrAttendanceSyncFinished = "hrAttendanceSyncFinished";
    private static final String AttReportSyncFinished = "attReportSyncFinished";
    private static final String SchoolSchoolSyncFinished = "schoolSchoolSyncFinished";

    private boolean isHrEmployeeSyncFinished() {
        return mPrefs.getBoolean(HrEmployeeSyncFinished, false);
    }

    public Prefs setHrEmployeeSyncFinished(boolean hrEmployeeSyncFinished) {
        mPrefs.edit().putBoolean(HrEmployeeSyncFinished, hrEmployeeSyncFinished).apply();
        if (hrEmployeeSyncFinished) {
            isSyncFinished();
        }
        return this;
    }

    private boolean isHrAttendanceSyncFinished() {
        return mPrefs.getBoolean(HrAttendanceSyncFinished, false);
    }

    public Prefs setHrAttendanceSyncFinished(boolean hrAttendanceSyncFinished) {
        mPrefs.edit().putBoolean(HrAttendanceSyncFinished, hrAttendanceSyncFinished).apply();
        if (hrAttendanceSyncFinished) {
            isSyncFinished();
        }
        return this;
    }

    private boolean isAttReportSyncFinished() {
        return mPrefs.getBoolean(AttReportSyncFinished, false);
    }

    public Prefs setAttReportSyncFinished(boolean attReportSyncFinished) {
        mPrefs.edit().putBoolean(AttReportSyncFinished, attReportSyncFinished).apply();
        if (attReportSyncFinished) {
            isSyncFinished();
        }
        return this;
    }

    private boolean isSchoolSchoolSyncFinished() {
        return mPrefs.getBoolean(SchoolSchoolSyncFinished, false);
    }

    public Prefs setSchoolSchoolSyncFinished(boolean schoolSchoolSyncFinished) {
        mPrefs.edit().putBoolean(SchoolSchoolSyncFinished, schoolSchoolSyncFinished).apply();
        if (schoolSchoolSyncFinished) {
            isSyncFinished();
        }
        return this;
    }
}    

这就是我如何从Fragment

中调用它
public class Employees extends BaseFragment {

    private static final String TAG = Employees.class.getSimpleName();
    private Prefs mPrefs;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        mPrefs = new Prefs(getContext());
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_employee, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_sync) {
            return onSync();
        }
        return super.onOptionsItemSelected(item);
    }

    private boolean onSync() {
        try {
            final ProgressDialog dialog = new ProgressDialog(getContext(), R.style.AppDialogTheme);
            dialog.setTitle("Please Wait");
            dialog.setMessage("Syncing Data");
            dialog.setCancelable(false);
            dialog.show();

            new Prefs(getContext(), new SyncFinishedListener() {
                @Override
                public void onSyncFinished() {
                    // Not getting called
                    dialog.dismiss();
                    getActivity().finish();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }
}

我的代码运行正常。但是,我无法弄清楚为什么我会NullPointerException。 这里有一些Log用于调试。

E/HrEmployee: onSyncStarted
E/HrAttendance: onSyncStarted
E/SchoolSchool: onSyncStarted
E/SchoolSchool: onSyncFinished
E/Prefs: isSyncFinished is :false
E/HrEmployee: onSyncFinished
E/Prefs: isSyncFinished is :false
E/AttReport: onSyncStarted
E/HrEmployee: onSyncStarted
E/HrEmployee: onSyncFinished
E/Prefs: isSyncFinished is :false
E/HrAttendance: onSyncStarted
E/HrAttendance: onSyncFinished
E/Prefs: isSyncFinished is :false
E/SchoolSchool: onSyncStarted
E/SchoolSchool: onSyncFinished
E/Prefs: isSyncFinished is :false
E/AttReport: onSyncStarted
E/HrEmployee: onSyncStarted
E/HrEmployee: onSyncStarted
E/HrEmployee: onSyncFinished
E/Prefs: isSyncFinished is :false
E/HrAttendance: onSyncStarted
E/HrEmployee: onSyncFinished
E/Prefs: isSyncFinished is :false
E/AttReport: onSyncStarted
E/AttReport: onSyncFinished
E/Prefs: isSyncFinished is :false
E/HrAttendance: onSyncFinished
E/Prefs: isSyncFinished is :false
E/HrAttendance: onSyncStarted
E/HrAttendance: onSyncFinished
E/Prefs: isSyncFinished is :false
E/SchoolSchool: onSyncStarted
E/SchoolSchool: onSyncFinished
E/Prefs: isSyncFinished is :false
E/HrAttendance: onSyncFinished
E/Prefs: isSyncFinished is :false
E/AttReport: onSyncFinished
E/Prefs: isSyncFinished is :true
W/System.err: java.lang.NullPointerException: Attempt to invoke interface method 'void com.odoo.addons.employees.utils.SyncFinishedListener.onSyncFinished()' on a null object reference
W/System.err:     at com.odoo.addons.employees.utils.Prefs.isSyncFinished(Prefs.java:145)
W/System.err:     at com.odoo.addons.employees.utils.Prefs.setAttReportSyncFinished(Prefs.java:115)
W/System.err:     at com.odoo.addons.employees.models.AttReport.onSyncFinished(AttReport.java:58)
W/System.err:     at com.odoo.core.service.OSyncAdapter.syncData(OSyncAdapter.java:291)
W/System.err:     at com.odoo.core.service.OSyncAdapter.onPerformSync(OSyncAdapter.java:204)
W/System.err:     at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:272)

2 个答案:

答案 0 :(得分:0)

尝试将错误追溯到其根目录:您正在获取NPE,因为当您在Prefs.listener上调用onSyncFinished()时,isSyncFinished() var为空。此变量在构造函数中分配,该构造函数将第二个参数作为侦听器。但是还有一个构造函数只接受上下文作为参数,如果使用了这个,Prefs.listener仍然为空。在您的片段中,您正在onCreate()中使用此构造函数构建Prefs-Object。这是我可以看到Prefs.listener为空的唯一原因。由于Prefs.listener是静态的,因此必须确保在调用其他Prefs对象的isSyncFinished()之前调用具有侦听器赋值的构造函数。

希望我能提供帮助。

PS:但是要在构造函数中分配一个静态变量,并希望为没有调用此构造函数的对象初始化此var,这不是实现所需内容的好方法。听众是否需要保持静止?

答案 1 :(得分:0)

首先,你没有理由在第一个构造函数中调用super(),因为你没有扩展任何类。

第二,至少在此代码中没有理由listener应该是静态的。如果您从此代码外部调用Prefs.listener,则应通过删除静态调用来重新考虑整个体系结构。这是一种几乎总能避免的坏习惯。如果类只有在您的应用程序中使用的静态变量,那么您应该考虑使用单例设计模式。一旦你习惯了,它就会轻松安全地使用。