Android Realm - 更新 RealmList 触发 IllegalArgumentException
Android Realm - Updating RealmList triggers IllegalArgumentException
我正在尝试更新现有的 RealmObject (IncidentCard),其中包含类型为 IncidentPhoto 的 RealmList。只要我不尝试更新 RealmList,该对象就会毫无问题地更新,当我包含该列表时,我会收到以下错误消息:
E/AndroidRuntime: FATAL EXCEPTION: main
E/AndroidRuntime: Process: com.trollvik.android.incidents247, PID: 31923
E/AndroidRuntime: java.lang.IllegalArgumentException: Each element of 'value' must be a valid managed object.
E/AndroidRuntime: at io.realm.IncidentCardRealmProxy.setPhotos(IncidentCardRealmProxy.java:218)
E/AndroidRuntime: at com.trollvik.android.incidents247.activities.EditCardActivity.saveIncidentCard(EditCardActivity.java:155)
E/AndroidRuntime: at com.trollvik.android.incidents247.activities.EditCardActivity.onClick(EditCardActivity.java:95)
E/AndroidRuntime: at android.view.View.performClick(View.java:5197)
E/AndroidRuntime: at android.view.View$PerformClick.run(View.java:20926)
E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime: at android.os.Looper.loop(Looper.java:145)
E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5944)
E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
这是事件卡片class:
public class IncidentCard extends RealmObject {
@PrimaryKey
private long id;
private String timestamp;
private String type;
private RealmList<IncidentPhoto> photos;
public IncidentCard() {
}
public IncidentCard(long id, String timestamp, String type){
this.id = id;
this.timestamp = timestamp;
this.type = type;
}
public IncidentCard(long id, String timestamp, String type, RealmList<IncidentPhoto> photos){
this.id = id;
this.timestamp = timestamp;
this.type = type;
this.photos = photos;
}
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
public String getTimestamp(){
return this.timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public String getType(){
return this.type;
}
public void setType(String type){
this.type = type;
}
public RealmList<IncidentPhoto> getPhotos() {
return this.photos;
}
public void setPhotos(RealmList<IncidentPhoto> photos) {
this.photos = photos;
}
}
这是事故照片class:
public class IncidentPhoto extends RealmObject {
private String photoPath;
public IncidentPhoto() {
}
public IncidentPhoto(String photoPath) {
this.photoPath = photoPath;
}
public String getPhotoPath(){
return this.photoPath;
}
public void setPhotoPath(String photoPath){
this.photoPath = photoPath;
}
}
为了查询领域数据库,我创建了这个助手 class:
public class IncidentDbHelper {
private Realm realm;
public IncidentDbHelper(Context context) {
realm = Realm.getInstance(context);
}
public void setObject(IncidentCard incidentCard) {
realm.beginTransaction();
IncidentCard incident = realm.copyToRealmOrUpdate(incidentCard);
realm.commitTransaction();
}
public IncidentCard getObject(Long id) {
return realm.where(IncidentCard.class).equalTo("id", id).findFirst();
}
public void close(){
if (realm != null) {
realm.close();
}
}
}
当我添加新的事件卡时,我将其称为 activity:
public class NewCardActivity extends AppCompatActivity {
private static final int REQUEST_IMAGE_CAPTURE = 1;
private static final String INSTANCE_STATE = "currentPhotoPath";
private static final String INSTANCE_STATE_LIST = "currentPhotoList";
private Context mContext;
private IncidentCard mIncidentCard;
private IncidentDbHelper mDbHelper;
private IncidentCardId mIncidentId;
private IncidentCardTimestamp mIncidentTimestamp;
private RealmConverter mRealmConverter;
private Resources mRes;
private PhotoPath mPath;
private String mCurrentPhotoPath;
private ArrayList<String> mCurrentPhotoList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
mDbHelper = new IncidentDbHelper(mContext);
mIncidentCard = new IncidentCard();
mRealmConverter = new RealmConverter();
mCurrentPhotoList = new ArrayList<String>();
mIncidentId = new IncidentCardId();
mIncidentTimestamp = new IncidentCardTimestamp();
mRes = getResources();
mPath = new PhotoPath();
// If savedInstanceState is empty, ignore this code.
if(savedInstanceState != null){
mCurrentPhotoPath = savedInstanceState.getString(INSTANCE_STATE);
mCurrentPhotoList = savedInstanceState.getStringArrayList(INSTANCE_STATE_LIST);
}
}
protected void saveIncidentCard(){
Realm realm = Realm.getInstance(this);
Spinner spinner = (Spinner) findViewById(R.id.content_new_card_type);
String incidentType = spinner.getSelectedItem().toString();
realm.beginTransaction();
mIncidentCard.setId(mIncidentId.getNewId());
mIncidentCard.setTimestamp(mIncidentTimestamp.getNewTimestamp());
mIncidentCard.setType(incidentType);
mIncidentCard.setPhotos(mRealmConverter.toRealmList(mCurrentPhotoList));
realm.commitTransaction();
mDbHelper.setObject(mIncidentCard);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_new_card, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_new_photo:
dispatchTakePictureIntent();
default:
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
return super.onOptionsItemSelected(item);
}
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File imageFile = null;
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
try {
imageFile = mPath.createImageFile();
mCurrentPhotoPath = imageFile.getAbsolutePath();
} catch (java.io.IOException e) {
Log.e(TAG, e.toString());
}
// Continue only if the File was successfully created
if (imageFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(imageFile.getAbsoluteFile()));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString(INSTANCE_STATE, mCurrentPhotoPath);
savedInstanceState.putStringArrayList(INSTANCE_STATE_LIST, mCurrentPhotoList);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
mCurrentPhotoList.add(mCurrentPhotoPath);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mDbHelper.close();
}
}
当我拍摄新照片时,我将以前拍摄的照片的路径保存在字符串类型的 ArrayList 中。在我将路径列表设置为 IncidentCard 对象之前,我将该列表转换为 RealmList。这部分似乎工作正常。
在我尝试在 EditCardActivity 中保存现有对象后出现问题:
public class EditCardActivity extends AppCompatActivity {
private static final String INTENT_EXTRA = "EXTRA_INCIDENT_ID";
private static final int REQUEST_IMAGE_CAPTURE = 2;
private static final String INSTANCE_STATE = "currentPhotoPath";
private static final String INSTANCE_STATE_LIST = "currentPhotoList";
private Context mContext;
private Long mIncidentId;
private IncidentCard mIncidentCard;
private IncidentDbHelper mDbHelper;
private IncidentCardTimestamp mIncidentTimestamp;
private RealmConverter mRealmConverter;
private Resources mRes;
private PhotoPath mPath;
Spinner mSpinnerType;
private String mCurrentPhotoPath;
private ArrayList<String> mCurrentPhotoList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRealmConverter = new RealmConverter();
mContext = this;
mDbHelper = new IncidentDbHelper(mContext);
mIncidentCard = new IncidentCard();
mCurrentPhotoList = new ArrayList<String>();
mIncidentTimestamp = new IncidentCardTimestamp();
mRes = getResources();
mPath = new PhotoPath();
// If savedInstanceState is empty, ignore this code.
if(savedInstanceState != null){
mCurrentPhotoPath = savedInstanceState.getString(INSTANCE_STATE);
mCurrentPhotoList = savedInstanceState.getStringArrayList(INSTANCE_STATE_LIST);
}
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
saveIncidentCard();
finish();
}
});
// Get Incident ID passed from Main Activity
Intent intent = getIntent();
mIncidentId = intent.getLongExtra(INTENT_EXTRA, 0);
mIncidentCard = mDbHelper.getObject(mIncidentId);
mTextViewId = (TextView) findViewById(R.id.content_edit_card_id);
mSpinnerType = (Spinner) findViewById(R.id.content_edit_card_type);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_dropdown_item, items);
mSpinnerType.setAdapter(adapter);
String compareValue = mIncidentCard.getType();
if (!compareValue.equals(null)) {
int spinnerPosition = adapter.getPosition(compareValue);
mSpinnerType.setSelection(spinnerPosition);
}
mCurrentPhotoList = mRealmConverter.toArrayList(mIncidentCard.getPhotos());
}
protected void saveIncidentCard(){
Realm realm = Realm.getInstance(this);
Spinner spinner = (Spinner) findViewById(R.id.content_edit_card_type);
String incidentType = spinner.getSelectedItem().toString();
realm.beginTransaction();
mIncidentCard.setTimestamp(mIncidentTimestamp.getNewTimestamp());
mIncidentCard.setType(incidentType);
mIncidentCard.setPhotos(mRealmConverter.toRealmList(mCurrentPhotoList));
realm.commitTransaction();
mDbHelper.setObject(mIncidentCard);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_edit_card, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_edit_photo:
dispatchTakePictureIntent();
default:
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
return super.onOptionsItemSelected(item);
}
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File imageFile = null;
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
try {
imageFile = mPath.createImageFile();
mCurrentPhotoPath = imageFile.getAbsolutePath();
} catch (java.io.IOException e) {
Log.e(TAG, e.toString());
}
// Continue only if the File was successfully created
if (imageFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(imageFile.getAbsoluteFile()));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString(INSTANCE_STATE, mCurrentPhotoPath);
savedInstanceState.putStringArrayList(INSTANCE_STATE_LIST, mCurrentPhotoList);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
mCurrentPhotoList.add(mCurrentPhotoPath);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mDbHelper.close();
}
}
因此,如果我注释掉 mIncidentCard.setPhotos(),一切似乎都正常,但是当我尝试将照片设置为 IncidentCard 对象时,会触发 IllegalArgumentException。
这是我创建的用于将 ArrayLists 转换为 RealmLists 的方法:
public RealmList<IncidentPhoto> toRealmList(ArrayList<String> arrayList){
mRealmList = new RealmList<IncidentPhoto>();
for (int i = 0; i < arrayList.size(); i++){
IncidentPhoto incidentPhoto = new IncidentPhoto();
incidentPhoto.setPhotoPath(arrayList.get(i));
mRealmList.add(incidentPhoto);
}
return mRealmList;
}
我已经为此苦苦挣扎了一段时间,但我不明白自己做错了什么,所以非常感谢您的帮助。
问题是,当调用 setter 来设置一个 RealmList
时,列表中的每个元素都必须由 Realm 管理。
这里有类似的问题
您可以修改toRealmList
如下:
public RealmList<IncidentPhoto> toRealmList(Realm realm, ArrayList<String> arrayList) {
mRealmList = new RealmList<IncidentPhoto>();
for (int i = 0; i < arrayList.size(); i++){
// Create a IncidentPhoto object which is managed by Realm.
IncidentPhoto incidentPhoto = realm.createObject(IncidentPhoto.class);
incidentPhoto.setPhotoPath(arrayList.get(i));
mRealmList.add(incidentPhoto);
}
return mRealmList;
}
或
public RealmList<IncidentPhoto> toRealmList(Realm realm, ArrayList<String> arrayList) {
mRealmList = new RealmList<IncidentPhoto>();
for (int i = 0; i < arrayList.size(); i++){
IncidentPhoto incidentPhoto = new IncidentPhoto();
incidentPhoto.setPhotoPath(arrayList.get(i));
// Copy the standalone object to Realm, and get the returned object which is managed by Realm.
incidentPhoto = realm.copyToRealm(incidentPhoto);
mRealmList.add(incidentPhoto);
}
return mRealmList;
}
我正在尝试更新现有的 RealmObject (IncidentCard),其中包含类型为 IncidentPhoto 的 RealmList。只要我不尝试更新 RealmList,该对象就会毫无问题地更新,当我包含该列表时,我会收到以下错误消息:
E/AndroidRuntime: FATAL EXCEPTION: main
E/AndroidRuntime: Process: com.trollvik.android.incidents247, PID: 31923
E/AndroidRuntime: java.lang.IllegalArgumentException: Each element of 'value' must be a valid managed object.
E/AndroidRuntime: at io.realm.IncidentCardRealmProxy.setPhotos(IncidentCardRealmProxy.java:218)
E/AndroidRuntime: at com.trollvik.android.incidents247.activities.EditCardActivity.saveIncidentCard(EditCardActivity.java:155)
E/AndroidRuntime: at com.trollvik.android.incidents247.activities.EditCardActivity.onClick(EditCardActivity.java:95)
E/AndroidRuntime: at android.view.View.performClick(View.java:5197)
E/AndroidRuntime: at android.view.View$PerformClick.run(View.java:20926)
E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime: at android.os.Looper.loop(Looper.java:145)
E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5944)
E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
这是事件卡片class:
public class IncidentCard extends RealmObject {
@PrimaryKey
private long id;
private String timestamp;
private String type;
private RealmList<IncidentPhoto> photos;
public IncidentCard() {
}
public IncidentCard(long id, String timestamp, String type){
this.id = id;
this.timestamp = timestamp;
this.type = type;
}
public IncidentCard(long id, String timestamp, String type, RealmList<IncidentPhoto> photos){
this.id = id;
this.timestamp = timestamp;
this.type = type;
this.photos = photos;
}
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
public String getTimestamp(){
return this.timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public String getType(){
return this.type;
}
public void setType(String type){
this.type = type;
}
public RealmList<IncidentPhoto> getPhotos() {
return this.photos;
}
public void setPhotos(RealmList<IncidentPhoto> photos) {
this.photos = photos;
}
}
这是事故照片class:
public class IncidentPhoto extends RealmObject {
private String photoPath;
public IncidentPhoto() {
}
public IncidentPhoto(String photoPath) {
this.photoPath = photoPath;
}
public String getPhotoPath(){
return this.photoPath;
}
public void setPhotoPath(String photoPath){
this.photoPath = photoPath;
}
}
为了查询领域数据库,我创建了这个助手 class:
public class IncidentDbHelper {
private Realm realm;
public IncidentDbHelper(Context context) {
realm = Realm.getInstance(context);
}
public void setObject(IncidentCard incidentCard) {
realm.beginTransaction();
IncidentCard incident = realm.copyToRealmOrUpdate(incidentCard);
realm.commitTransaction();
}
public IncidentCard getObject(Long id) {
return realm.where(IncidentCard.class).equalTo("id", id).findFirst();
}
public void close(){
if (realm != null) {
realm.close();
}
}
}
当我添加新的事件卡时,我将其称为 activity:
public class NewCardActivity extends AppCompatActivity {
private static final int REQUEST_IMAGE_CAPTURE = 1;
private static final String INSTANCE_STATE = "currentPhotoPath";
private static final String INSTANCE_STATE_LIST = "currentPhotoList";
private Context mContext;
private IncidentCard mIncidentCard;
private IncidentDbHelper mDbHelper;
private IncidentCardId mIncidentId;
private IncidentCardTimestamp mIncidentTimestamp;
private RealmConverter mRealmConverter;
private Resources mRes;
private PhotoPath mPath;
private String mCurrentPhotoPath;
private ArrayList<String> mCurrentPhotoList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
mDbHelper = new IncidentDbHelper(mContext);
mIncidentCard = new IncidentCard();
mRealmConverter = new RealmConverter();
mCurrentPhotoList = new ArrayList<String>();
mIncidentId = new IncidentCardId();
mIncidentTimestamp = new IncidentCardTimestamp();
mRes = getResources();
mPath = new PhotoPath();
// If savedInstanceState is empty, ignore this code.
if(savedInstanceState != null){
mCurrentPhotoPath = savedInstanceState.getString(INSTANCE_STATE);
mCurrentPhotoList = savedInstanceState.getStringArrayList(INSTANCE_STATE_LIST);
}
}
protected void saveIncidentCard(){
Realm realm = Realm.getInstance(this);
Spinner spinner = (Spinner) findViewById(R.id.content_new_card_type);
String incidentType = spinner.getSelectedItem().toString();
realm.beginTransaction();
mIncidentCard.setId(mIncidentId.getNewId());
mIncidentCard.setTimestamp(mIncidentTimestamp.getNewTimestamp());
mIncidentCard.setType(incidentType);
mIncidentCard.setPhotos(mRealmConverter.toRealmList(mCurrentPhotoList));
realm.commitTransaction();
mDbHelper.setObject(mIncidentCard);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_new_card, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_new_photo:
dispatchTakePictureIntent();
default:
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
return super.onOptionsItemSelected(item);
}
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File imageFile = null;
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
try {
imageFile = mPath.createImageFile();
mCurrentPhotoPath = imageFile.getAbsolutePath();
} catch (java.io.IOException e) {
Log.e(TAG, e.toString());
}
// Continue only if the File was successfully created
if (imageFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(imageFile.getAbsoluteFile()));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString(INSTANCE_STATE, mCurrentPhotoPath);
savedInstanceState.putStringArrayList(INSTANCE_STATE_LIST, mCurrentPhotoList);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
mCurrentPhotoList.add(mCurrentPhotoPath);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mDbHelper.close();
}
}
当我拍摄新照片时,我将以前拍摄的照片的路径保存在字符串类型的 ArrayList 中。在我将路径列表设置为 IncidentCard 对象之前,我将该列表转换为 RealmList。这部分似乎工作正常。
在我尝试在 EditCardActivity 中保存现有对象后出现问题:
public class EditCardActivity extends AppCompatActivity {
private static final String INTENT_EXTRA = "EXTRA_INCIDENT_ID";
private static final int REQUEST_IMAGE_CAPTURE = 2;
private static final String INSTANCE_STATE = "currentPhotoPath";
private static final String INSTANCE_STATE_LIST = "currentPhotoList";
private Context mContext;
private Long mIncidentId;
private IncidentCard mIncidentCard;
private IncidentDbHelper mDbHelper;
private IncidentCardTimestamp mIncidentTimestamp;
private RealmConverter mRealmConverter;
private Resources mRes;
private PhotoPath mPath;
Spinner mSpinnerType;
private String mCurrentPhotoPath;
private ArrayList<String> mCurrentPhotoList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRealmConverter = new RealmConverter();
mContext = this;
mDbHelper = new IncidentDbHelper(mContext);
mIncidentCard = new IncidentCard();
mCurrentPhotoList = new ArrayList<String>();
mIncidentTimestamp = new IncidentCardTimestamp();
mRes = getResources();
mPath = new PhotoPath();
// If savedInstanceState is empty, ignore this code.
if(savedInstanceState != null){
mCurrentPhotoPath = savedInstanceState.getString(INSTANCE_STATE);
mCurrentPhotoList = savedInstanceState.getStringArrayList(INSTANCE_STATE_LIST);
}
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
saveIncidentCard();
finish();
}
});
// Get Incident ID passed from Main Activity
Intent intent = getIntent();
mIncidentId = intent.getLongExtra(INTENT_EXTRA, 0);
mIncidentCard = mDbHelper.getObject(mIncidentId);
mTextViewId = (TextView) findViewById(R.id.content_edit_card_id);
mSpinnerType = (Spinner) findViewById(R.id.content_edit_card_type);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_dropdown_item, items);
mSpinnerType.setAdapter(adapter);
String compareValue = mIncidentCard.getType();
if (!compareValue.equals(null)) {
int spinnerPosition = adapter.getPosition(compareValue);
mSpinnerType.setSelection(spinnerPosition);
}
mCurrentPhotoList = mRealmConverter.toArrayList(mIncidentCard.getPhotos());
}
protected void saveIncidentCard(){
Realm realm = Realm.getInstance(this);
Spinner spinner = (Spinner) findViewById(R.id.content_edit_card_type);
String incidentType = spinner.getSelectedItem().toString();
realm.beginTransaction();
mIncidentCard.setTimestamp(mIncidentTimestamp.getNewTimestamp());
mIncidentCard.setType(incidentType);
mIncidentCard.setPhotos(mRealmConverter.toRealmList(mCurrentPhotoList));
realm.commitTransaction();
mDbHelper.setObject(mIncidentCard);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_edit_card, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_edit_photo:
dispatchTakePictureIntent();
default:
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
return super.onOptionsItemSelected(item);
}
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File imageFile = null;
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
try {
imageFile = mPath.createImageFile();
mCurrentPhotoPath = imageFile.getAbsolutePath();
} catch (java.io.IOException e) {
Log.e(TAG, e.toString());
}
// Continue only if the File was successfully created
if (imageFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(imageFile.getAbsoluteFile()));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString(INSTANCE_STATE, mCurrentPhotoPath);
savedInstanceState.putStringArrayList(INSTANCE_STATE_LIST, mCurrentPhotoList);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
mCurrentPhotoList.add(mCurrentPhotoPath);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mDbHelper.close();
}
}
因此,如果我注释掉 mIncidentCard.setPhotos(),一切似乎都正常,但是当我尝试将照片设置为 IncidentCard 对象时,会触发 IllegalArgumentException。
这是我创建的用于将 ArrayLists 转换为 RealmLists 的方法:
public RealmList<IncidentPhoto> toRealmList(ArrayList<String> arrayList){
mRealmList = new RealmList<IncidentPhoto>();
for (int i = 0; i < arrayList.size(); i++){
IncidentPhoto incidentPhoto = new IncidentPhoto();
incidentPhoto.setPhotoPath(arrayList.get(i));
mRealmList.add(incidentPhoto);
}
return mRealmList;
}
我已经为此苦苦挣扎了一段时间,但我不明白自己做错了什么,所以非常感谢您的帮助。
问题是,当调用 setter 来设置一个 RealmList
时,列表中的每个元素都必须由 Realm 管理。
这里有类似的问题
您可以修改toRealmList
如下:
public RealmList<IncidentPhoto> toRealmList(Realm realm, ArrayList<String> arrayList) {
mRealmList = new RealmList<IncidentPhoto>();
for (int i = 0; i < arrayList.size(); i++){
// Create a IncidentPhoto object which is managed by Realm.
IncidentPhoto incidentPhoto = realm.createObject(IncidentPhoto.class);
incidentPhoto.setPhotoPath(arrayList.get(i));
mRealmList.add(incidentPhoto);
}
return mRealmList;
}
或
public RealmList<IncidentPhoto> toRealmList(Realm realm, ArrayList<String> arrayList) {
mRealmList = new RealmList<IncidentPhoto>();
for (int i = 0; i < arrayList.size(); i++){
IncidentPhoto incidentPhoto = new IncidentPhoto();
incidentPhoto.setPhotoPath(arrayList.get(i));
// Copy the standalone object to Realm, and get the returned object which is managed by Realm.
incidentPhoto = realm.copyToRealm(incidentPhoto);
mRealmList.add(incidentPhoto);
}
return mRealmList;
}