私は最初の Android アプリケーションを作成しており、db4o データベースを使用しようとしています。
一般に、それは次のように構成されています: 「Person」クラスがあります (「ボス」、「従業員」、「インターン」を区別するための継承があります... しかし、それはここではあまり重要ではないと思います)。
「タスク」クラスもあります。「タスク」オブジェクトには、(他の属性の中でも) 人物を含む ArrayList があります。タスクは担当者が割り当てられていなくても存在でき、その逆も同様です。
私が抱えている問題は、db4o がオブジェクトを追跡していないように見えることです。そのため、(クエリを使用してデータベースからロードされた) Person を Task にアタッチしようとすると、Person が複製されます。したがって、今のところ、Person オブジェクトに対して QBE を実行し、返されたオブジェクトを Task に追加することで、これを解決しました。しかし、これは非常に間違っているようですか?
そのため、どこかでオブジェクトへの参照が失われます...データベース接続を常に開いたままにしています(onDestroyで閉じるだけです)。
これはサンプル アクションです。Task のいくつかの属性を入力するアクティビティがあり、ListView から (インテントを通じて) Person オブジェクトを選択 (および返す) する ActivityForResult を使用します。次に、リンクして保存したい最初のアクティビティに戻ります。
インテントで渡すオブジェクトは、Parcelable ではなく Serializable です。「パフォーマンス ヒット」以外にそれが重要かどうかはわかりません。
コードを投稿したいと思っていますが、コードのどの部分が問題を特定するのに役立つかわかりません。
関連すると思われるコード:
AddTask アクティビティ:
(これは onCreate にあります)
Db4oHelper db4oHelper = new Db4oHelper(context);
db=db4oHelper.db();
(...)
Button AddButton = (Button) findViewById(R.id.Addbutton);
AddButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent pickUserIntent = new Intent(context,PickUser.class);
startActivityForResult(pickUserIntent,1);
}
});
と:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
ArrayList<Person> personList_local = (ArrayList<Person>)
data.getSerializableExtra("PERSONS");
ArrayList<Person> personList_db=new ArrayList<Person>();
for (Person p:personList_local){
personList_db.add((Person)helper.listResultToArray(db.queryByExample(po)).get(0));
}
Task t = new Task("Description",personList_db);
db.store(t);
db.commit();
}
}
listResultToArray を持つヘルパー クラスは、データベースから返された ObjectSet の項目を、リストビューに必要な ArrayList に入れる単純な反復 for ループです。
PickUser アクティビティ:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
persons_sel=new ArrayList<Person>();
Db4oHelper db4oHelper = new Db4oHelper(context);
db=db4oHelper.db();
persons_all=helper.listResultToArray(db.query(Person.class));
list = (ListView) findViewById(android.R.id.list);
this.adapter = new PersonAdapter(this, R.layout.row_checkbox, persons_all);
setListAdapter(this.adapter);
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Person p = (Person) parent.getItemAtPosition(position);
CheckBox check = (CheckBox) view.findViewById(R.id.check);
if (!person_sel.remove(p)) {
person_sel.add(p);
check.setChecked(true);
}else{
check.setChecked(false);
}
}
});
Button SubmitButton = (Button) findViewById(R.id.SubmitButton);
SubmitButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (persons_sel.size()>0){
Intent returnIntent = new Intent();
returnIntent.putExtra("PERSONS", persons_sel);
setResult(RESULT_OK,returnIntent);
finish();
}else{
Toast.makeText(getApplicationContext(),
"You must select at least something!",
Toast.LENGTH_SHORT).show();
}
}
});
}
private class PersonAdapter extends ArrayAdapter<Person> {
private ArrayList<Person> items;
public PersonAdapter(Context context, int textViewResourceId,
ArrayList<Person> items) {
super(context, textViewResourceId, items);
this.items = items;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row_checkbox, null);
}
Person p = items.get(position);
if (p != null) {
TextView tt = (TextView) v.findViewById(R.id.toptext);
if (tt != null) {
tt.setText(p.toString());
}
}
return v;
}
}