Android领域-更新RealmList会触发IllegalArgumentException
我正在尝试更新现有的RealmObject(IncidentCard),其中包含IncidentPhoto类型的RealmList。只要我不尝试更新RealmList,对象更新时不会出现任何问题,当我包括列表时,我会收到以下错误消息:Android领域-更新RealmList会触发IllegalArgumentException,android,realm,illegalargumentexception,realm-list,Android,Realm,Illegalargumentexception,Realm List,我正在尝试更新现有的RealmObject(IncidentCard),其中包含IncidentPhoto类型的RealmList。只要我不尝试更新RealmList,对象更新时不会出现任何问题,当我包括列表时,我会收到以下错误消息: E/AndroidRuntime: FATAL EXCEPTION: main E/AndroidRuntime: Process: com.trollvik.android.incidents247, PID: 31923 E/AndroidRuntime: j
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$1.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)
这是IncidentCard类:
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;
}
}
要查询我创建的域数据库,请执行以下操作:
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();
}
}
}
当我添加新事件卡时,我将此活动称为:
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();
}
}
公共类NewCardActivity扩展了AppCompatActivity{
私有静态最终整数请求\图像\捕获=1;
私有静态最终字符串实例_STATE=“currentPhotoPath”;
私有静态最终字符串实例\u STATE\u LIST=“currentPhotoList”;
私有上下文;
私人意外事故卡;
私人意外帮助者;
私人意外事件;
私人意外事件卡时间戳最小意外事件时间戳;
私有RealmConverter mRealmConverter;
私人资源;
专用光路mPath;
私有字符串mCurrentPhotoPath;
私有ArrayList McCurrentPhotoList;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mContext=这个;
mDbHelper=新的IncidentDbHelper(mContext);
mIncidentCard=新的IncidentCard();
mRealmConverter=新的RealmConverter();
mCurrentPhotoList=新的ArrayList();
mIncidentId=新的incidentcard();
mIncidentTimestamp=新的IncidentCardTimestamp();
mRes=getResources();
mPath=新光路();
//如果savedInstanceState为空,则忽略此代码。
如果(savedInstanceState!=null){
mCurrentPhotoPath=savedInstanceState.getString(实例状态);
mCurrentPhotoList=savedInstanceState.getStringArrayList(实例状态列表);
}
}
受保护的无效saveIncidentCard(){
Realm Realm=Realm.getInstance(this);
微调器微调器=(微调器)findViewById(R.id.content\u new\u card\u type);
String incidentType=spinner.getSelectedItem().toString();
realm.beginTransaction();
mIncidentCard.setId(mincidenId.getNewId());
setTimestamp(mIncidentTimestamp.getNewTimestamp());
mIncidentCard.setType(incidentType);
mIncidentCard.setPhotos(mRealmConverter.toRealmList(mCurrentPhotoList));
realm.commitTransaction();
mDbHelper.setObject(mIncidentCard);
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
//为菜单充气;这会将项目添加到操作栏(如果存在)。
getMenuInflater().充气(R.menu.menu\U新卡,menu);
返回true;
}
@凌驾
公共布尔值onOptionsItemSelected(菜单项项){
开关(item.getItemId()){
案例R.id.菜单\新\照片:
DispatchTakePictureContent();
违约:
//如果我们到了这里,用户的行为就不会被识别。
//调用超类来处理它。
返回super.onOptionsItemSelected(项目);
}
}
私有无效DispatchTakePictureContent(){
Intent takePictureIntent=新的意图(MediaStore.ACTION\u IMAGE\u CAPTURE);
File imageFile=null;
//确保有摄像头活动来处理意图
if(takePictureContent.resolveActivity(getPackageManager())!=null){
//创建照片应该放在哪里的文件
试一试{
imageFile=mPath.createImageFile();
mCurrentPhotoPath=imageFile.getAbsolutePath();
}捕获(java.io.ioe异常){
Log.e(标记,e.toString());
}
//仅当成功创建文件时才继续
if(imageFile!=null){
takePictureContent.putExtra(MediaStore.EXTRA_输出,
Uri.fromFile(imageFile.getAbsoluteFile());
startActivityForResult(获取图片内容、请求图像捕获);
}
}
}
@凌驾
SaveInstanceState上的公共无效(Bundle savedInstanceState){
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString(实例状态,mCurrentPhotoPath);
savedInstanceState.putStringArrayList(实例状态列表,mCurrentPhotoList);
}
@凌驾
受保护的void onActivityResult(int请求代码、int结果代码、意图数据){
if(requestCode==REQUEST\u IMAGE\u CAPTURE&&resultCode==RESULT\u OK){
添加(mCurrentPhotoPath);
}
}
@凌驾
受保护的空onDestroy(){
super.ondestory();
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();
}
}
公共类EditCardActivity扩展了AppCompatActivity{
私有静态最终字符串意图\u EXTRA=“EXTRA\u事件\u ID”;
私有静态最终整数请求\图像\捕获=2;
私有静态最终字符串实例_STATE=“currentPhotoPath”;
私有静态最终字符串实例\u STATE\u LIST=“currentPhotoList”;
私有上下文;
私人长毛象;
私人意外事故卡;
私人意外帮助者;
私人意外事件卡时间戳最小意外事件时间戳;
私有RealmConverter mRealmConverter;
私人资源;
专用光路mPath;
微调器mSpinnerType;
私有字符串mCurrentPhotoPath;
私有ArrayList McCurrentPhotoList;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mRealmConverter=新的RealmConverter();
mContext=这个;
mDbHelper=新的IncidentDbHelper(mContext);
mIncidentCard=新的IncidentCard();
mCurrentPhotoList=新的ArrayList();
mIncidentTimestamp=新的IncidentCardTimestamp();
mRes=getResources();
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();
}
}
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;
}
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;
}