繁体   English   中英

Gson和方向改变的问题

[英]Problems with Gson and orientation changes

我正在尝试使用Gson保存序列化/反序列化POJOS列表。 虽然通常这不是什么特别的任务,但我遇到了一个我从未见过的异常​​:

01-11 14:17:22.556: E/AndroidRuntime(15941): java.lang.RuntimeException: 
Unable to start activity ComponentInfo{com.timkranen.playpalproject/com.timkranen.playpalproject.HomeActivity}: 
java.lang.RuntimeException: Unable to invoke no-args constructor for interface java.util.concurrent.locks.Lock. 
Register an InstanceCreator with Gson for this type may fix this problem.

我怀疑这与List项正在AsyncTask中加载有关。 任何人都有这个问题的经验吗?

我尝试将执行的逻辑放在onSaveInstanceState(用于保存)中的同步方法中,但这无济于事。

编辑

这是我的一些代码,试图使其更加清晰。 我有一个名为friendsList的列表。 该列表填充在此AsyncTask中,并在onCreateView()中执行

private class RetrieveFriends extends AsyncTask<Void, Integer, String> {

    @Override
    protected String doInBackground(Void... params) {
        // get friends
        if (friendProfiles == null || friendProfiles.size() == 0) {
            friendProfiles = new ArrayList<Profile>();
            if (currentProfile.getFriendUids() != null
                    && currentProfile.getFriendUids().size() > 0)
                for (String fUid : currentProfile.getFriendUids()) {
                    Profile friend = ProfileDataManager
                            .getProfileFromId(fUid);
                    friendProfiles.add(friend);
                }

            if (friendProfiles.size() == 0) {
                return "null";
            }
        }

        return "notnull";

    }

    @Override
    protected void onPostExecute(String result) {
        if (!result.equals("null")) {
            loadingFriendsBar.setVisibility(View.INVISIBLE);
            friendsList.setVisibility(View.VISIBLE);
            FriendListAdapter adapter = new FriendListAdapter(
                    containedActivity, R.layout.friendslist_row,
                    friendProfiles);
            friendsList.setAdapter(adapter);
        } else {
            loadingFriendsBar.setVisibility(View.INVISIBLE);
            friendMsg.setVisibility(View.VISIBLE);
        }
    }

}

现在,在onSaveInstanceState中,我将该列表序列化为JSON,如下所示:

private synchronized void saveToState(Bundle state) {
    Gson gson = new Gson();
    Type listOfProfiles = new TypeToken<List<Profile>>() {
    }.getType();
    String json = gson.toJson(friendProfiles, listOfProfiles);
    state.putString("json_friendProfiles", json);
}

该方法直接在onSaveInstanceState()中调用。 检索相同:

private synchronized void retrieveFromState(String json) {
    Type listOfProfiles = new TypeToken<List<Profile>>() {
    }.getType();
    Gson gson = new Gson();
    friendProfiles = (List<Profile>) gson.fromJson(json,
            listOfProfiles);
}

奇怪的是,导航到另一个Fragment时状态已正确保存。 仅当我更改方向时才会发生错误。

编辑:根据要求,这里是Profile类

public class Profile {

private String mEmail;
private String mPassword;
private String uid;

// optional properties
private String name;
private String location;
private String about;
private ParseFile image; // not certain of data type

private List<String> friendUids;

public String getName() {
    if (name == null || name.equals("")) {
        return "Name unknown";
    }
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getLocation() {
    if (location == null || location.equals("")) {
        return "Location unknown";
    }
    return location;
}

public void setLocation(String location) {
    this.location = location;
}

public String getAbout() {
    if (about == null || about.equals("")) {
        return "About unknown";
    }
    return about;
}

public void setAbout(String about) {
    this.about = about;
}

public void setUid(String Uid) {
    this.uid = Uid;
}

public String getUid() {
    return this.uid;
}

public String getPassword() {
    return mPassword;
}

public String getEmail() {
    return mEmail;
}

public Profile(String email, String password) {
    this.mEmail = email;
    this.mPassword = password;
}

/*
 * Saves a Profile and returns the profiles UID This is ONLY APPLICABLE for
 * NEW profiles use the update method to update existing profile data
 */
public void saveToParse(SaveCallback saveCallBack) {
    if (ProfileDataManager.IsRegistered(this) != true) {
        ParseObject pObject = new ParseObject("Profiles");
        pObject.put("email", this.mEmail);
        pObject.put("password", this.mPassword);
        pObject.saveInBackground(saveCallBack);
    } else {
        saveCallBack.done(new ParseException(ErrorCodes.ALREADY_REGISTERED,
                "AlreadyRegistered"));
    }
}

public void update() {
    ParseQuery<ParseObject> query = ParseQuery.getQuery("Profiles");
    query.getInBackground(this.uid, new GetCallback<ParseObject>() {

        @Override
        public void done(ParseObject object, ParseException e) {
            if (e == null) {
                // update the object
                object.put("email", Profile.this.mEmail);
                object.put("password", Profile.this.mPassword);
                if (Profile.this.name != null) {
                    object.put("name", Profile.this.name);
                }
                if (Profile.this.location != null) {
                    object.put("location", Profile.this.location);
                }
                if (Profile.this.about != null) {
                    object.put("about", Profile.this.about);
                }
                if (Profile.this.image != null) {
                    object.put("profileImage", Profile.this.image);
                }
                if (Profile.this.friendUids != null
                        && Profile.this.friendUids.size() != 0) {
                    object.put("friends", Profile.this.friendUids);
                }

                object.saveInBackground();
            }
        }
    });
}

/*
 * Use updateWithCallBack when you want to update an object but want to show
 * the updated data immediatly using a callback, when calling this method
 * make sure that currentProfile in HomeActivity is set to the new Profile!
 */
public void updateWithCallBack(final SaveCallback callBack) {
    ParseQuery<ParseObject> query = ParseQuery.getQuery("Profiles");
    query.getInBackground(this.uid, new GetCallback<ParseObject>() {

        @Override
        public void done(ParseObject object, ParseException e) {
            if (e == null) {
                // update the object
                object.put("email", Profile.this.mEmail);
                object.put("password", Profile.this.mPassword);
                if (Profile.this.name != null) {
                    object.put("name", Profile.this.name);
                }
                if (Profile.this.location != null) {
                    object.put("location", Profile.this.location);
                }
                if (Profile.this.about != null) {
                    object.put("about", Profile.this.about);
                }
                if (Profile.this.image != null) {
                    object.put("profileImage", Profile.this.image);
                }
                if (Profile.this.friendUids != null
                        && Profile.this.friendUids.size() != 0) {
                    object.put("friends", Profile.this.friendUids);
                }
                object.saveInBackground(callBack);
            }
        }
    });
}

// retrieves the image, when done calls callback
public void retrieveProfileImage(GetDataCallback callBack) {
    this.image.getDataInBackground(callBack);
}

public ParseFile getProfileImage() {
    return this.image;
}

public void setProfileImage(ParseFile image) {
    this.image = image;
}

public void saveProfileImage(Bitmap image) {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    image.compress(Bitmap.CompressFormat.JPEG, 50, stream);
    byte[] byteArray = stream.toByteArray();
    String imgid = this.getUid() + "_profile_image.jpeg";
    String fileNameForImage = this.getUid() + "_profile_image.jpeg";
    this.image = new ParseFile(fileNameForImage, byteArray);
}

public List<String> getFriendUids() {
    return this.friendUids;
}

public void addFriend(String uid) {
    if (this.friendUids != null) {
        friendUids.add(uid);
    } else {
        friendUids = new ArrayList<String>();
        friendUids.add(uid);
    }
}

public void setFriends(Object friends) {
    ArrayList<String> f = (ArrayList<String>) friends;
    this.friendUids = f;
}

}

Gson对象

private Gson gson = new GsonBuilder().
        setExclusionStrategies(new ParseExclusion()).
        create();

排除类

private class ParseExclusion implements ExclusionStrategy {

    public boolean shouldSkipClass(Class<?> arg0) {
        return false;
    }

    public boolean shouldSkipField(FieldAttributes f) {
        return (f.getDeclaredClass() == Lock.class);
    }

}

最后:

Type type = new TypeToken<List<Profile>>() {}.getType();
List<Profile>) friendProfiles = new ArrayList<Profile>();
friendProfiles = gson.fromJson(json,type);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM