Skip to content
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

Server down after the app is killed in the background #245

Closed
mickael-menu opened this issue Mar 5, 2020 · 7 comments · Fixed by readium/r2-testapp-kotlin#298
Closed
Labels
bug Something isn't working

Comments

@mickael-menu
Copy link
Member

If the app is killed by Android while it's in the background and on the Reader activity, the server is broken when the app is restarted. This can happen in case of memory pressure.

To reproduce, open an EPUB from the testapp, then put the app in the background.
Run adb shell am kill org.readium.r2reader, then restart the app. You will see this error:

Screenshot_1583430240

@mickael-menu mickael-menu added the bug Something isn't working label Mar 5, 2020
@twaddington
Copy link
Contributor

twaddington commented Mar 5, 2020

Ah, I suspected this may be an issue.

Another thing to be aware of is that the local web server makes all the content accessible to any application running on the device.

This would be a longer term project but, it should be possible to replace the local web server with a custom WebViewAssetLoader and WebViewClient without much difficulty.

This would sandbox all the content to the running app and you wouldn't have to worry about the system killing the web server due to memory pressure.

@mickael-menu
Copy link
Member Author

I didn't check yet but a good lead would be that the server port changes, but the navigator may be restored with the former base URL for the publication.

This would be a longer term project but, it should be possible to replace the local web server with a custom WebViewAssetLoader and WebViewClient without much difficulty.

It's a subject that comes back frequently, on iOS we can't do that because it doesn't work with byte-range requests, but I don't know the state for Android. Maybe @aferditamuriqi or @danielweck know more about this.

@twaddington
Copy link
Contributor

twaddington commented Mar 5, 2020

You should be able to handle range requests on Android as of Lollipop (API 21).

public WebResourceResponse shouldInterceptRequest (WebView view, 
                WebResourceRequest request)

The WebResourceRequest includes the request headers which should allow you to determine what range is being requested and return the appropriate content. Previously this method only indicated what URL was being requested (not very helpful).

@mickael-menu
Copy link
Member Author

You should be able to handle range requests on Android as of Lollipop (API 21).

Sounds promising 👍

@mickael-menu
Copy link
Member Author

I didn't find any easy way to fix this issue... :/

The problem is that the server is initialized in LibraryActivity.onCreate, and the publications are parsed and added to the server in LibraryActivity as well. But when the app is killed while the navigator activity is at the top of the stack, Android will only restore the navigator, so the server is out of reach.

Now the trouble is that the navigator activity doesn't have what it needs to reparse the Publication and add it to the server. We would need to extract all the library logic into shared services exposed by the Application object for that, not a small refactoring.

Considering that we'll probably replace the navigator activities with fragments, I'm not sure it's worth tackling this issue right now. Because with fragments and a single activity, we'll have everything we need to reopen the Publication properly.

I did find a workaround to alleviate the issue. Setting android:clearTaskOnLaunch to true for the LibraryActivity will make sure that the navigator is discarded when the app is killed and restarted from the launcher, so we'll always start from the bookshelf. Unfortunately, this doesn't work when the app is relaunched from the Recents screen, for some reason...

@twaddington Maybe you know a way to make sure that the navigator activity is always discarded when the app is killed?

@mickael-menu
Copy link
Member Author

I made a quick fix here: readium/r2-testapp-kotlin#298

It's not great because the publication is not restored when app is killed, but at least we won't get an error message from the webview. It should be enough until the architecture is fixed.

@twaddington
Copy link
Contributor

@mickael-menu I think you've got all the right ideas. I don't have any other suggestions at the moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants