2012-05-07 11 views
0

Ormlite ForeignCollectionを次のクラスで使用しようとすると問題が発生しました。私はRun &ウェイポイントクラスに正しく注釈が付いていると信じています。 (RunにはWayPointのコレクションがあります)。しかし、私がhasNext()を呼び出すと、WayPointにアクセスしようとしたとき(第3コード抽出を参照)、私のCloseableIteratorがnullを返します。私がエミュレータでこれをテストするとき、私は最初にRunのためにいくつかのWayPointを生成して保存します。私はその後、Runのインスタンスを通じてWayPointにアクセスしようとします。ただ、ここであまりにも多くのコードをダンプすることなく、絵を完成させ、ForeignCollection<WayPoint>オブジェクトはORMLiteによる外部コレクションの繰り返しに関する問題

run.getWayPoints(); 

を呼び出すことにより、コンテンダーのコンストラクタに渡され、ここで私はウェイポイントを作成し、それを格納しています方法です:: - ときGPSLocation.onLocationChanged()火災状態がGPS_STATE_RUNNINGの場合、createWayPoint()の呼び出しが行われます。これによりWayPointがインスタンス化され、lng/lat値が設定され、関連付けられたRunインスタンスへのハンドルが設定されます。この時点では、まだdbに格納されていません。 WayPointが最終的にdbに格納されるGPSLocation.updateWayPointWithElapsedTime()を呼び出す別のクラスにインテントが送信されます。実行が完了すると、外部クラスはRunインスタンスを格納するstoreRun()を呼び出します。私はそれが関連付けられているときにWayPointを格納するかどうか疑問に思うようになっています。Runインスタンス自体はまだ格納されていません。

**注:セクションに表示されるように、クラスはコンパイルされません。

@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); 
     } 
    } 

のDatabaseManagerからの抜粋は - >

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(); 
    } 
} 

答えて

1

私はあなたがクリスを掲載しましたコードに問題が表示されません。したがって、私はあなたがあなただと思うようにWayPointを挿入していないと思われます。それらがデータベースにあることを確認しましたか? WayPoint DAOを使用して直接クエリを試しましたか?

// what does this return? 
List<WayPoint> wayPoints = wayPointDao.queryForAll(); 

私はあなたがRunテーブルにRunフィールドが挿入されていることを確認し、各WayPoint前にそれを設定し、最初の実行のためのウェイポイントの番号を生成し、またそれらに

を保存しますWayPointの作成を行います。あなたの質問を編集して、私たちにWayPoint秒を挿入するために使用されるコードを表示する場合は

// create a foreign collection we can add to 
run.wayPoints = runDao.getEmptyForeignCollection("wayPoints"); 
// now if you add something to the collection, it gets created in the DAO as well 
run.wayPoints.add(wayPoint1); 

:あなたが挿入できるもう一つの方法は、外国コレクション自体を使用することです

Run run1 = new Run(...); 
runDao.create(run1); 
... 
WayPoint wayPoint1 = new WayPoint(...); 
wayPoint1.setRun(run1); 
wayPointDao.create(wayPoint1); 
... 

:あなたのような何かをしなければなりませんデータベースに、私は答えを編集してより多くの情報を提供します。

+0

提案のおかげでグレー。まもなくそれを試してみるだろう。 relaventコードの残りの部分を投稿しました。私は外国のコレクション自体に追加する考えが好きです。個々のウェイポイントを追加するのと比較してパフォーマンスの違いはありますか? –

+0

パフォーマンスの違いはありません@Chris。 – Gray

+0

だから、WayPointsをデータベースからフェッチすると、実行フィールドから離れたすべてのフィールドに値があることがわかります。私がWayPointを保存するとき、私はRunの有効なインスタンスを持っていて、それをWayPointに設定しましたが、Runのインスタンスはそれ自体がdbに格納されていません。 WayPointを保存する前にRunインスタンスを保存してみて、違いがあるかどうか確認します。 Greyに感謝します。後で更新されます。 –

関連する問題