-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pass post id instead of post model within intents and extras #5856
Conversation
We already have a check for the existence of the post model after this one, so removing this one to avoid double check.
@@ -153,7 +153,7 @@ | |||
public class EditPostActivity extends AppCompatActivity implements EditorFragmentListener, EditorDragAndDropListener, | |||
ActivityCompat.OnRequestPermissionsResultCallback, EditorWebViewCompatibility.ReflectionFailureListener, | |||
PhotoPickerFragment.PhotoPickerListener { | |||
public static final String EXTRA_POST = "postModel"; | |||
public static final String EXTRA_POST_LOCAL_ID = "postModelLocalId"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for the explicit naming EXTRA_POST_LOCAL_ID
@@ -32,7 +37,7 @@ public static EditPostPreviewFragment newInstance(SiteModel site, PostModel post | |||
EditPostPreviewFragment fragment = new EditPostPreviewFragment(); | |||
Bundle bundle = new Bundle(); | |||
bundle.putSerializable(WordPress.SITE, site); | |||
bundle.putSerializable(EditPostActivity.EXTRA_POST, post); | |||
bundle.putInt(EditPostActivity.EXTRA_POST_LOCAL_ID, post.getId()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add a comment to explain why we switched from putSerializable
to putInt
(and why we're still doing it for the site).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, after this PR what I was going to suggest is we remove the putSerializable
s as much as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree and I disagree. We use putSerializable
because we want to avoid passing ids, especially we want to avoid confusion with remote and local ids.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because we want to avoid passing ids
Can you elaborate on this? I am just curious about it. Because, we can avoid the confusion about the remote & local ids issue by just explicitly naming them like EXTRA_POST_LOCAL_ID
or EXTRA_POST_REMOTE_ID
. It's no more confusing than having the remote and local id versions of getters in our stores.
In general I thought it was better to pass the ids, especially to avoid crashes like this. I can't see what we get out of passing the serializable
except for maybe convenience.
Please note that I am not against it, I just want to better understand it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's no more confusing than having the remote and local id versions of getters in our stores.
In the stores, we don't really have the choice because remote ids can't be unique. So we make that distinction (remoteId vs localId) to avoid any ambiguity.
But here in the app, we want to hide this and make it easier for developers. If we can avoid any id, that's even better. But in some cases (like here) we don't really have the choice.
Also note: when FluxC is complete, we will never see any remote id in the app - we currently have some because we still have REST calls not going through FluxC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, once that's done we can actually start using the ids instead? That's good news!
Do you mind either committing that comment you mentioned or writing it here? I am still unsure what to write there. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since
PostModel
objects can be quite large, in order to avoid issues likeTransactionTooLargeException
it's better to pass the id of the post. However, we still want to keep passing theSiteModel
to avoid confusion around local & remote ids.
@maxme Would a comment like the above one work for what you had in mind?
public class EditPostPreviewFragment extends Fragment { | ||
@Inject PostStore mPostStore; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going to need to inject this fragment into the AppComponent
, otherwise mPostStore
will always be null
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot the add a note about this in the original description, but the reason I am not reverting the changes in #5698 is because this crash might be occurring in multiple places in our app and until we know all crashes are gone, I'd like to keep the changes for it. Once it's resolved, I think we should attempt to revert that change and maybe others in the future to keep the code clean. |
Note: if we want this in 7.4, we have to change the targeted branch. |
@maxme I'd feel better if we still merged it into
|
Ok, I removed the milestone. |
…too-large-exception
Just a reminder that this PR is still ready to be reviewed/merged! I just merged I'd suggest us to merge this in as soon as possible, since it's hopefully fixing a crash. |
updateSiteOrFinishActivity(savedInstanceState); | ||
} | ||
|
||
private void updateSiteOrFinishActivity(Bundle savedInstanceState) { | ||
if (savedInstanceState == null) { | ||
if (getArguments() != null) { | ||
mSite = (SiteModel) getArguments().getSerializable(WordPress.SITE); | ||
mPost = (PostModel) getArguments().getSerializable(EditPostActivity.EXTRA_POST); | ||
mPost = mPostStore.getPostByLocalPostId(getArguments().getInt(EditPostActivity.EXTRA_POST_LOCAL_ID)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Serializing and de-serializing the post as this used to do keeps the same reference to the post. Doing it this way creates a new object, which is not updated as mPost
is updated in the EditPostActivity
. As a result the preview will always show the post as it was when opened (for new posts, the preview is always blank). The loadPost()
method will have to account for this.
@oguzkocer we should probably do the same thing for |
@aforcier The reason I didn't do the same thing in So, what I propose to do is, when post is passed to these fragments, we should use the id and get the post from the |
I'm not sure I fully grasp the underlying issue, but it seems like the crash can happen whenever 'too much' data is passed in a Binder transaction, and my understanding is that that would also apply to the bundle usage in |
@@ -60,15 +58,11 @@ private void updateSiteOrFinishActivity(Bundle savedInstanceState) { | |||
if (savedInstanceState == null) { | |||
if (getArguments() != null) { | |||
mSite = (SiteModel) getArguments().getSerializable(WordPress.SITE); | |||
mPost = mPostStore.getPostByLocalPostId(getArguments().getInt(EditPostActivity.EXTRA_POST_LOCAL_ID)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this change this fragment no longer needs PostStore
- we can drop that injection and remove EditPostPreviewFragment
from the AppComponent.
14ea3c8
to
b963513
Compare
b963513
to
5adf5dc
Compare
Looks good to me - but perhaps we should still add a comment like this one to explain why we're passing by ID in this case? Maybe in |
Fixes #5456. This is a possible fix to our
TransactionTooLargeException
crash. Unfortunately we do not have enough details about the crashes to make sure we have the right fix for it, so we have to keep trying until we figure it out. Having said that I think this is a step in the right direction. I think, unless it's mandatory, we should always try to pass ids instead of whole objects between activities. It makes the code more robust as well as prevent issues like this one.Originally, I was working on the
release/7.3
branch for this, so we could fix it asap. However, I believe this fix looks deceptively simple yet can cause some unseen issues, so I think it's just safer to targetdevelop
. We don't want to introduce more crashes while trying to fix one.The changes are straightforward, however I got a little worried about the config changes (re-creating fragments and activities) since we don't pass the cached version of the post anymore and a new version from the DB is retrieved. As far as I can tell from the code, we do snyc the changes before this happens and my tests didn't result in anything lost, but it'd be good if we can test it out further.
To test:
@aforcier Since this is posts related, do you mind reviewing this one, I'd feel more comfortable if I got the from you!
/cc @mzorz @maxme @theck13 (since you were all interested in this issue)