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();
}
}
提案のおかげでグレー。まもなくそれを試してみるだろう。 relaventコードの残りの部分を投稿しました。私は外国のコレクション自体に追加する考えが好きです。個々のウェイポイントを追加するのと比較してパフォーマンスの違いはありますか? –
パフォーマンスの違いはありません@Chris。 – Gray
だから、WayPointsをデータベースからフェッチすると、実行フィールドから離れたすべてのフィールドに値があることがわかります。私がWayPointを保存するとき、私はRunの有効なインスタンスを持っていて、それをWayPointに設定しましたが、Runのインスタンスはそれ自体がdbに格納されていません。 WayPointを保存する前にRunインスタンスを保存してみて、違いがあるかどうか確認します。 Greyに感謝します。後で更新されます。 –