GreenDao - 自定义数据的缓存无法正常工作

时间:2014-01-02 22:36:38

标签: java android caching greendao

我有一个具有3个一对多关系的实体

private List<Data1> Data1;
private List<Data2> Data2;
private List<Data3> Data3;

我希望在手动创建的列表中汇总这些数据(TotalData只结合了三个列表,以便于管理......)

private transient TotalData mTotalData;

public TotalData getTotalData()
{
    if (mTotalData == null)
        mTotalData = new TotalData(getData1(), getData2(), getData3());
    return mTotalData;
}

我使用DaoSession.get...Dao().load(id)加载我的实体...在第一次创建时,一切正常,在第二次创建时,我的mTotalData已经存在且包含空的子列表...为什么?

编辑:我的TotalData实施

TotalData类中的所有数据都是实体!

public class WWorkoutObjectList
{
    private ComparatorWWorkoutObject mComparator = new ComparatorWWorkoutObject();
    private List<WWorkoutObject> mObjects = new ArrayList<WWorkoutObject>();

    public WWorkoutObjectList(List<WExercise> wExercises, List<WCardio> wCardio, List<WPause> wPause)
    {
        init(wExercises, wCardio, wPause);
    }

    public void init(List<WExercise> wExercises, List<WCardio> wCardio, List<WPause> wPause)
    {
        synchronized (mObjects)
        {
            mObjects.clear();
            for (int i = 0; i < wExercises.size(); i++)
                mObjects.add(new WWorkoutObject(wExercises.get(i)));
            for (int i = 0; i < wCardio.size(); i++)
                mObjects.add(new WWorkoutObject(wCardio.get(i)));
            for (int i = 0; i < wPause.size(); i++)
                mObjects.add(new WWorkoutObject(wPause.get(i)));
            sort();
        }
    }

    public void add(WWorkoutObject wObject)
    {
        synchronized (mObjects)
        {
            mObjects.add(wObject);
            sort();
        }
    }

    public int size()
    {
        return mObjects.size();
    }

    public WWorkoutObject get(int index)
    {
        return mObjects.get(index);
    }

    public WWorkoutObject remove(int index)
    {
        return mObjects.remove(index);
    }

    // ----------------
    // Hilfsfunktionen
    // ----------------

    public WExercise getNextExercise(int currentIndex)
    {
        synchronized (mObjects)
        {
            for (int i = currentIndex + 1; i < mObjects.size(); i++)
            {
                if (mObjects.get(i).isWCardio())
                    return null;
                if (mObjects.get(i).isWExercise())
                    return mObjects.get(i).getWExercise();
            }
        }
        return null;
    }

    public int getFragmentCount()
    {
        int counter = 0;
        synchronized (mObjects)
        {
            for (int i = 0; i < mObjects.size(); i++)
            {
                if (mObjects.get(i).isFragmentObject())
                    counter++;
            }
        }
        return counter;
    }

    public WWorkoutObject getFragmentObject(int fragmentIndex)
    {
        if (fragmentIndex < 0 || fragmentIndex >= mObjects.size())
            return null;

        int counter = 0;
        synchronized (mObjects)
        {
            for (int i = 0; i < mObjects.size(); i++)
            {
                if (mObjects.get(i).isFragmentObject())
                {
                    if (counter == fragmentIndex)
                        return mObjects.get(i);
                    counter++;
                }
            }
        }
        return null;
    }

    public List<WWorkoutObject> getFragmentsObjectsList()
    {
        List<WWorkoutObject> list = new ArrayList<WWorkoutObject>();
        synchronized (mObjects)
        {
            for (int i = 0; i < mObjects.size(); i++)
            {
                if (mObjects.get(i).isFragmentObject())
                    list.add(mObjects.get(i));
            }
        }
        return list;
    }

    public List<WWorkoutObject> list()
    {
        return mObjects;
    }

    // ----------------
    // private Funktionen
    // ----------------

    private void sort()
    {
        Collections.sort(mObjects, mComparator);
    }
}

编辑2:流程示例

  • 我创建了一个活动,并加载了ID为1(DaoSession.load(1)
  • 的实体
  • 我致电getTotalData() =&gt; mTotalData是正确的
  • 我转动屏幕并重新加载ID为1(DaoSession.load(1)))=&gt;的现在的CACHED实体mTotalData != null但是它的所有字段都是空的...因为它不是null,如果我现在调用getTotalData(),我会得到一个TotalData对象,它没有更新它的值...它看起来像是用空构造函数创建的对象(甚至不存在)

如果我向isInitialised添加TotalData变量并在getTotalData()中检查此变量,我可以解决这个问题...但我仍然不知道缓存是如何工作的为什么它不能使用我的自定义字段......

EDIT3

我很感谢您的反馈意见,但我认为现在还不清楚究竟是什么问题。

// Activity onCreate
public void onCreate(Bundle savedInstanceState)
{
    WWorkout workout = DaoSession.load(1);
    WWorkoutObjectList sortedData = workout.getWWorkoutObjects();
}

// Dao Entity custom function
public WWorkoutObjectList getWWorkoutObjects()
{
    // I make sure, with calling the getter functions, that I load all sub entities before creating the list!!!
    if (wWorkoutObjectList == null)
        wWorkoutObjectList = new WWorkoutObjectList(getWExercise(), getWCardio(), getWPause());
    return wWorkoutObjectList;
}

我的所作所为:

  • 我调用getWWorkoutObjects()并获取所有正确的数据(WWorkout中的所有列表都已加载,sortedData正确且已填充
  • 我从不编辑数据!!!
  • 我重新创建活动(即转动屏幕)并获得一个正确的实体(WWorkout中的所有列表都是正确的),但sortedData中的mObjects为空,但它已经存在!为什么?

据我所知,mObjects应为null或者它应该包含来自实体的所有数据,但它不能有所不同,因为唯一存在的构造函数是您可以在上面看到的那个(隐式地加载实体的子列表。

顺便说一下,init函数之前是私有的,我只是公开了解决方法而且我没有编辑任何数据来获得这种行为。

1 个答案:

答案 0 :(得分:1)

问题可能不属于greendao的范围。

请记住,例如在方向更改时,实际活动会被销毁并重新创建。因此,您的活动的私人领域无法保证在方向变更时保持不变。你必须自己处理你的田地的正确状态。

你可以这样做:

  • 通过初始化onCreate()
  • 中的字段
  • 通过在onPause()中保存字段的状态并在onResume()中恢复

当然,您也可以阻止在方向更改时重新创建活动。关于如何做到这一点有很多帖子。

尝试在DaoSession.load(1) - 方法中移动onCreate并在其中调用getTotalData()。如果您已经这样做了,请发布您的onCreate方法。

除此之外,我建议您对班级进行以下微小更改。 特别是在方法上使用synchronized,因为如果在synchronized块中使用变量,但是在块外部定义的变量可能会有奇怪的行为。

public class WWorkoutObjectList
{
    private ComparatorWWorkoutObject mComparator = new ComparatorWWorkoutObject();
    private List<WWorkoutObject> mObjects = new ArrayList<WWorkoutObject>();

    public WWorkoutObjectList(List<WExercise> wExercises, List<WCardio> wCardio, List<WPause> wPause)
    {
        init(wExercises, wCardio, wPause);
    }

    public synchronized void init(List<WExercise> wExercises, List<WCardio> wCardio, List<WPause> wPause)
    {
        mObjects.clear();
        if (wExercises != null) {
            for (WExercise we : wExercises) {
                mObjects.add(new WWorkoutObject(we));
            }
        }
        if (wCardio != null) {
            for (WCardio wc : wCardio) {
                mObjects.add(new WWorkoutObject(wc));
            }
        }
        if (wPause != null) {
            for (WPause wp : wPause) {
                mObjects.add(new WWorkoutObject(wp));
            }
        }
        sort();
    }

    public synchronized void add(WWorkoutObject wObject)
    {
        mObjects.add(wObject);
        sort();
    }

    public int size()
    {
        return mObjects.size();
    }

    public WWorkoutObject get(int index)
    {
        return mObjects.get(index);
    }

    public synchronized WWorkoutObject remove(int index)
    {
        return mObjects.remove(index);
    }

    // ----------------
    // Hilfsfunktionen
    // ----------------

    public synchronized WExercise getNextExercise(int currentIndex)
    {
        for (int i = currentIndex + 1; i < mObjects.size(); i++)
        {
            if (mObjects.get(i).isWCardio())
                return null;
            if (mObjects.get(i).isWExercise())
                return mObjects.get(i).getWExercise();
        }
        return null;
    }

    public synchronized int getFragmentCount()
    {
        int counter = 0;
        for (WWorkoutObject wo : mObjects)
        {
            if (wo.isFragmentObject())
                counter++;
        }
        return counter;
    }

    public synchronized WWorkoutObject getFragmentObject(int fragmentIndex)
    {
        if (fragmentIndex < 0 || fragmentIndex >= mObjects.size())
            return null;
        int counter = 0;
        for (WWorkoutObject wo : mObjects)
        {
            if (wo.isFragmentObject())
            {
                if (counter == fragmentIndex)
                    return mObjects.get(i);
                counter++;
            }
        }
        return null;
    }

    public synchronized List<WWorkoutObject> getFragmentsObjectsList()
    {
        List<WWorkoutObject> list = new ArrayList<WWorkoutObject>();
        for (WWorkoutObject wo : mObjects)
        {
            if (wo.isFragmentObject())
                list.add(wo);
        }
        return list;
    }

    public synchronized List<WWorkoutObject> list()
    {
        ArrayList<WWorkoutObject> result = new ArrayList<WWorkoutObject>();
        for (WWorkoutObject wo : mObjects)
            result.add(wo);
        return result;
    }

    // ----------------
    // private Funktionen
    // ----------------

    private void sort()
    {
        Collections.sort(mObjects, mComparator);
    }
}