尝试将 OrmliteForeignCollection与以下类一起使用时遇到问题。我相信我的 Run & Waypoint 类已正确注释。(Run 有一组 WayPoints)。但是,当我尝试访问 WayPoints(请参阅第三个代码摘录)CloseableIterator时,当我调用hasNext(). 当我用模拟器测试它时,我首先为 Run 生成一些 WayPoints 并存储它们。然后我尝试通过 Run 实例访问这些 WayPoints。只是为了补全图,这里不转储太多代码,ForeignCollection<WayPoint>通过调用将对象传递给Contender构造函数
run.getWayPoints();
以下是我创建 WayPoint 并将其存储的方式:: - 当 GPSLocation.onLocationChanged() 触发且状态为 GPS_STATE_RUNNING 时,将调用 createWayPoint()。这将实例化一个 WayPoint,设置 lng/lat 值,并将句柄设置为关联的 Run 实例,此时尚未将其自身存储到数据库中。一个 Intent 被发送到另一个类,该类在 GPSLocation.updateWayPointWithElapsedTime() 上回调,其中 WayPoint 最终存储到数据库中。当运行完成时,外部类调用 storeRun() 来存储 Run 实例。我开始怀疑在关联的 Run 实例本身尚未存储时存储 WayPoint 是否是问题的一部分。
** 注意 :: 这些类将不会编译,因为它们被缩减以显示与问题相关的部分。
@DatabaseTable
public class Run {
    @DatabaseField(generatedId=true)
    private int id;
    @DatabaseField(foreign=true,foreignAutoRefresh=true)
    private Route route;
    @ForeignCollectionField
    private ForeignCollection<WayPoint> wayPoints; 
    @DatabaseField
    private Date date;
    @DatabaseField
    private long time;
    public ForeignCollection<WayPoint> getWayPoints() {
        return wayPoints;
    }
}
@DatabaseTable
public class WayPoint {
    @DatabaseField(generatedId=true)
    private int id;
    @DatabaseField
    private int latitude;
    @DatabaseField
    private int longitude;
    @DatabaseField
    private int time; // offset 
    @DatabaseField(foreign=true,foreignAutoRefresh=true) 
    private Run run;
}    
public class Contender implements Comparable<Contender> {
    private int accumulatedDistance;
    private int interpolatedDistance;
    private WayPoint startPoint;
    CloseableIterator itr;
    private int id;
    WayPoint previous;
    WayPoint next;
    public Contender(ForeignCollection<WayPoint> wayPoints, WayPoint startPoint, int id) {
        this.startPoint = startPoint;
        this.id = id;
        itr = wayPoints.closeableIterator();
        if(itr.hasNext()) { 
            next = (WayPoint)itr.next();
        }
        else {
            Log.e("@@@", "no way points");
        }
        Log.i("@@@", "wayPoints size is " + wayPoints.size()); 
    }
}
public class GPSLocation extends Service implements LocationListener {
    private Run run;
    private WayPoint  wayPoint;
    private int distanceTravelled;
    @Override
        public void onCreate() {
            locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
            Criteria criteria = new Criteria();
            provider = locationManager.getBestProvider(criteria, false);
            startLocationUpdates = new ArrayList<Location>();
            Log.i(LOGTAG, "GPSLocation Service Running...");
        }
        public void startRunning() {
            setState(GPS_STATE_RUNNING);
            startTime = System.currentTimeMillis();
            run = new Run();
            run.setRoute(route);
            run.setDate(new Date());
        }
        public void storeRun(long elapsedTime) {
            // if first run and end point not set then set end point
            run.setTime(elapsedTime);
            route.addToCumulativeDistance(distanceTravelled);
            DatabaseManager.getInstance().storeRun(run);
            DatabaseManager.getInstance().updateRoute(route);
            resetGlobalState();
        }
        public void onLocationChanged(Location location) {
            previousLocation = currentLocation;
            currentLocation = location;
            Intent i = null; 
            boolean startActivity = true;
            switch(state)
            {
                case GPS_STATE_SETTING_START_LOCATION:
                    startLocationUpdates.add(location);
                    if(startLocationAccepted())
                    {
                        i = new Intent(this, AddRoute.class);
                        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        i.setAction("acquired");
                    }
                    else
                    {
                        startActivity = false; // waiting for more location data
                    }
                    break;
                case GPS_STATE_READY:
                    if(!atLocation(ROUTE_START, location, ROUTE_DELIMITER_REQUIRED_PROXIMITY))
                    {
                        setState(GPS_STATE_AWAITING_ARRIVAL_AT_START_LOCATION);
                        i = new Intent(this, Running.class);
                        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        i.setAction("proximity_update");
                    }
                    break;
                case GPS_STATE_AWAITING_ARRIVAL_AT_START_LOCATION:
                    i = new Intent(this, Running.class);
                    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    if(atLocation(ROUTE_START, location, ROUTE_DELIMITER_REQUIRED_PROXIMITY))
                    {
                        setState(GPS_STATE_READY);
                        i.setAction("ready");
                    }
                    else
                    {
                        i.setAction("proximity_update");
                    }
                    break;
                case GPS_STATE_RUNNING:
                    createWayPoint(location);
                    i = new Intent(this, Running.class);
                    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    if(atLocation(ROUTE_END, location, ROUTE_DELIMITER_REQUIRED_PROXIMITY) 
                            && (distanceTravelled > ROUTE_DELIMITER_REQUIRED_PROXIMITY))
                    {
                        i.setAction("at_end");
                    }
                    else
                    {
                        i.setAction("update");
                    }
                    distanceTravelled += currentLocation.distanceTo(previousLocation);  
                    i.putExtra("distanceTravelled", distanceTravelled);
                    setState(GPS_STATE_RUNNING_UPDATE);
                    break;
                default:
                    // error
            }
        }
        private void createWayPoint(Location location) {
            wayPoint = new WayPoint();
            wayPoint.setLatitude(LocationMath.degreesToMicroDegrees(location.getLatitude()));
            wayPoint.setLongitude(LocationMath.degreesToMicroDegrees(location.getLongitude()));
            wayPoint.setRun(run);
        }
        /*
         * Now we have the elapsed time from the Running Activity, we can store this WayPoint
         */
        public void updateWayPointWithElapsedTime(long elapsedTime) {
            // TODO::check the time value is correct
            wayPoint.setTimeOffset((int)elapsedTime);
            DatabaseManager.getInstance().storeWayPoint(wayPoint);
            setState(GPS_STATE_RUNNING); 
        }
    }
来自数据库管理器的摘录 -->
public void storeWayPoint(WayPoint point) {
        try {
            getHelper().getWayPointDao().create(point);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
public void storeRun(Run run) {
    try {
        getHelper().getRunDao().create(run);
    } catch (SQLException e) {
        e.printStackTrace();
    }
}