Reputation: 101
I'm making an android app using react native. The app uses java/native code for image processing.
The app has an image compononent which on click calls a java function that creates an image and saves it to the internal storage and returns the URI to it. (the result image may differ)
Sample code is:
FileOutputStream out = null;
try {
out = new FileOutputStream(imgPath);
resultMap.compress(Bitmap.CompressFormat.JPEG, 100, out);
} catch (Exception e) {
finishCallback.invoke(false);
Toast.makeText(getReactApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
return;
} finally {
try {
out.close();
} catch (IOException e) {
finishCallback.invoke(false);
Toast.makeText(getReactApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
return;
}
}
finishCallback.invoke(true,imgPath.toURI().toString());
The recieving side should update the image component to show the saved image.
When I run this for the first time it works fine but then when I run it again the component is not being updated even though the image in the storage has changed.
In order to update the view I need to close the app and restart it telling it to show what is saved in the storage and then it shows the change.
The recieving side looks like so:
(JniActivity.fillDoor is the java functiong responsible for updating the image in the storage)
onSelectFillImage = (source) => {
JniActivity.fillDoor(
this.state.doorImageSource.uri,
source.uri,
(isDone, picURI) => {
Alert.alert("is done: " + isDone);
if (isDone) {
const fixed = picURI
const source1 = { uri: fixed };
this.setState({
filledDoorImageSource: source1
});
}
}
);
Thank you for any help!
Upvotes: 7
Views: 3348
Reputation: 2382
You can ask react to render new image by adding random string in url as a param. If param changes, it will re render new image instead of cached one.
Here is how I did it,
file://${store.root.registerImagePath}/${member.userId}.jpg?time=${new Date()}
Upvotes: 0
Reputation: 101
After invastigating this issue turns out the problem was the componnent caches the image.
As long as you are using the same URI the component will not turn to the server to update the image and would rather use the cached information.
Althougth there are ways to tell the component to not cache the image from my understanding there is no way to gurantee for 100% that the component will not cache dispite your best afforts.
The quickest solution would be to add a large random number to the image name which would make sure the URI will never repeat (while making sure of course you delete all previous no longer needed data).
Example code:
String ImageName += Integer.toString(Math.round(Math.random()*1000000000);
Upvotes: 2
Reputation: 876
So like you said the problem is that the url is the same even though the image itself has changed. React native components and pure components have a low level check for updates. That means that they will check if the new prop has the same value as the old one and in your case since the url doesn't change it is getting the same value and will decide that it does not need to update. What you could do as a solution is that along with the url also have a flag in your state for whether or not the image should rerender ( something like shouldReload: boolean) and everytime your JAVA function returns a url toggle that flag to make your image rerender.
Upvotes: 0