summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Weghorn <m.weghorn@posteo.de>2021-04-09 13:59:43 +0200
committerMichael Weghorn <m.weghorn@posteo.de>2021-04-12 07:34:57 +0200
commit5b83ba53dcdc8c92691685a318f1e5929ae67995 (patch)
tree5e795553bb5d80415dbdf9abddab68fc30811c09
parente96853b5b1965d5c006bc2f819f3331b4bdc93f4 (diff)
tdf#95517 android: Rework app/doc lifecycle handling
Previously, the document was always closed in LibreOfficeMainActivity's 'onStop' and loaded anew in its 'onStart' method. In order to not lose user changes, there was also a caching mechanism in LOKitTileProvider, also triggered in 'LibreOfficeMainActivity#onStop'. This means that e.g. each time a switch to another Activity/app happened, a cache document with the user modifications in it should have been created for restoration. That did not really seem to work particularly well in a few tests, as also described in tdf#95517 ("changes reset after show Settings"). The documentation aboue Activity lifecycle says [1] > The entire lifetime of an activity happens between the first call to > onCreate(Bundle) through to a single final call to onDestroy(). An > activity will do all setup of "global" state in onCreate(), and release > all remaining resources in onDestroy(). For example, if it has a thread > running in the background to download data from the network, it may > create that thread in onCreate() and then stop the thread in > onDestroy(). This changes the handling to load the document in the 'onCreate' method and clos it only in 'onDestroy', i.e. the document remains open while e.g. switching to another Activity or app, thus making it unnecessary to try to restore state as good as possible in 'onStart'. An invalidation of the view (via 'LOEvent.REFRESH') generally seems to be enough. (Well, sometimes there is an issue with invalidation/repaint and single tiles remain black, but that happened previously - when the whole doc was loaded anew - just the same way). This allows dropping some extra handling needed to try to restore the previous state, along with the caching mechanism in LOKitTileProvider (that had some other issues, e.g. it didn't reliably create the cache file, since the file extension was not always set, and 'LOKitTileProvider#cacheDocument' was relying on that to derive the document type). I am not sure whether I missed any aspect that the previous implementation was trying to solve, but at least these scenarios I found and tested worked as expected with the change in place: * user changes still present after switching between apps (s. tdf#106648 "Android: save current work when onSaveInstanceState is called") * for the Calc case, the sheet that was selected before switching apps is still selected (s. tdf#101689 "Android Viewer calc returns to first sheet") * user changes no longer get lost when selecting a menu item (s. tdf#95517 "changes reset after show Settings") * case where the user leaves the app by pressing Home, and starts it again (as described in commit 83386129f5be002f2649db81bba4c468c7f6e4de "android: Fix the application lifecycle.") [1] https://developer.android.com/reference/android/app/Activity#activity-lifecycle Change-Id: If59734cbfd62673884786066c94e2c2a1d6a916e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113883 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> (cherry picked from commit 1bc42472200c32c9a0a10dd1c3cd6c6a8a5d47d2)
-rw-r--r--android/source/src/java/org/libreoffice/LOEvent.java8
-rw-r--r--android/source/src/java/org/libreoffice/LOKitShell.java4
-rw-r--r--android/source/src/java/org/libreoffice/LOKitThread.java23
-rw-r--r--android/source/src/java/org/libreoffice/LOKitTileProvider.java54
-rw-r--r--android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java21
5 files changed, 7 insertions, 103 deletions
diff --git a/android/source/src/java/org/libreoffice/LOEvent.java b/android/source/src/java/org/libreoffice/LOEvent.java
index 74a09c92cc1d..d1170eee12ad 100644
--- a/android/source/src/java/org/libreoffice/LOEvent.java
+++ b/android/source/src/java/org/libreoffice/LOEvent.java
@@ -33,7 +33,6 @@ public class LOEvent implements Comparable<LOEvent> {
public static final int SWIPE_LEFT = 12;
public static final int NAVIGATION_CLICK = 13;
public static final int UNO_COMMAND = 14;
- public static final int RESUME = 15;
public static final int LOAD_NEW = 16;
public static final int SAVE_AS = 17;
public static final int UPDATE_PART_PAGE_RECT = 18;
@@ -105,13 +104,6 @@ public class LOEvent implements Comparable<LOEvent> {
mValue = value;
}
- public LOEvent(int type, String key, int value) {
- mType = type;
- mTypeString = "Resume partIndex";
- mString = key;
- mPartIndex = value;
- }
-
public LOEvent(String filePath, int type) {
mType = type;
mTypeString = "Load";
diff --git a/android/source/src/java/org/libreoffice/LOKitShell.java b/android/source/src/java/org/libreoffice/LOKitShell.java
index 75b2fb09b260..43dd30a69847 100644
--- a/android/source/src/java/org/libreoffice/LOKitShell.java
+++ b/android/source/src/java/org/libreoffice/LOKitShell.java
@@ -123,10 +123,6 @@ public class LOKitShell {
LOKitShell.sendEvent(new LOEvent(filePath, fileFormat, LOEvent.SAVE_COPY_AS));
}
- public static void sendResumeEvent(String inputFile, int partIndex) {
- LOKitShell.sendEvent(new LOEvent(LOEvent.RESUME, inputFile, partIndex));
- }
-
public static void sendCloseEvent() {
LOKitShell.sendEvent(new LOEvent(LOEvent.CLOSE));
}
diff --git a/android/source/src/java/org/libreoffice/LOKitThread.java b/android/source/src/java/org/libreoffice/LOKitThread.java
index a3c6733ad81f..1bca3cd13b5c 100644
--- a/android/source/src/java/org/libreoffice/LOKitThread.java
+++ b/android/source/src/java/org/libreoffice/LOKitThread.java
@@ -188,26 +188,6 @@ class LOKitThread extends Thread {
mLayerClient.setZoomConstraints(new ZoomConstraints(true, 1f, minZoom, 0f));
}
-
- /**
- * Resume the document with the current part
- */
-
- private void resumeDocument(String filename, int partIndex){
-
- mLayerClient = mContext.getLayerClient();
-
- mInvalidationHandler = new InvalidationHandler(mContext);
- mTileProvider = TileProviderFactory.create(mContext, mInvalidationHandler, filename);
-
- if (mTileProvider.isReady()) {
- updateZoomConstraints();
- changePart(partIndex);
- } else {
- closeDocument();
- }
- }
-
/**
* Change part of the document.
*/
@@ -310,9 +290,6 @@ class LOKitThread extends Thread {
case LOEvent.SAVE_COPY_AS:
saveDocumentAs(event.filePath, event.fileType, false);
break;
- case LOEvent.RESUME:
- resumeDocument(event.mString, event.mPartIndex);
- break;
case LOEvent.CLOSE:
closeDocument();
break;
diff --git a/android/source/src/java/org/libreoffice/LOKitTileProvider.java b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
index aafdbff311c1..e9fc2d52a154 100644
--- a/android/source/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
@@ -74,31 +74,16 @@ class LOKitTileProvider implements TileProvider {
mContext.setTileProvider(this);
mInputFile = input;
File f = new File(mInputFile);
- final String cacheFile = mContext.getExternalCacheDir().getAbsolutePath() + "/lo_cached_" + f.getName();
-
- if(mContext.firstStart){
- File cacheFileObj = new File(cacheFile);
- if(cacheFileObj.exists()) {
- cacheFileObj.delete();
- }
- mContext.firstStart=false;
- }
Log.i(LOGTAG, "====> Loading file '" + input + "'");
- File fileToBeEncoded;
- if(isDocumentCached()){
- fileToBeEncoded = new File(cacheFile);
- }else{
- fileToBeEncoded = new File(input);
- }
+ File fileToBeEncoded = new File(input);
String encodedFileName = android.net.Uri.encode(fileToBeEncoded.getName());
mDocument = mOffice.documentLoad(
(new File(fileToBeEncoded.getParent(),encodedFileName)).getPath()
);
-
if (mDocument == null && !mContext.isPasswordProtected()) {
Log.i(LOGTAG, "====> mOffice.documentLoad() returned null, trying to restart 'Office' and loading again");
mOffice.destroy();
@@ -401,45 +386,10 @@ class LOKitTileProvider implements TileProvider {
}
}
- public boolean isDocumentCached(){
- File input = new File(mInputFile);
- final String cacheFile = mContext.getExternalCacheDir().getAbsolutePath() + "/lo_cached_" + input.getName();
- File cacheFileObj = new File(cacheFile);
- if(cacheFileObj.exists())
- return true;
-
- return false;
- }
-
- public void cacheDocument() {
- String cacheDir = mContext.getExternalCacheDir().getAbsolutePath();
- File input = new File(mInputFile);
- final String cacheFile = cacheDir + "/lo_cached_" + input.getName();
- Log.i(LOGTAG, "cacheDocument: " + cacheFile);
- if(isDocumentCached()){
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Save"));
- }else if(mDocument != null){
- mDocument.saveAs("file://"+cacheFile, FileUtilities.getExtension(input.getPath()).substring(1),"");
- }else{
- Log.w(LOGTAG, "mDocument was null when trying to save cacheDocument: " + cacheFile);
- }
- }
-
public void saveDocument(){
- if(isDocumentCached()){
- String format = FileUtilities.getExtension(mInputFile).substring(1);
- String cacheDir = mContext.getExternalCacheDir().getAbsolutePath();
- File input = new File(mInputFile);
- final String cacheFile = cacheDir + "/lo_cached_" + input.getName();
- String path = input.getAbsolutePath();
- saveDocumentAs(path, format, true);
- (new File(cacheFile)).delete();
- }else{
- mContext.saveDocument();
- }
+ mContext.saveDocument();
}
-
private void setupDocumentFonts() {
String values = mDocument.getCommandValues(".uno:CharFontName");
if (values == null || values.isEmpty())
diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 950a063e8d94..a1fab7dbde49 100644
--- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -8,7 +8,6 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.graphics.RectF;
import android.net.Uri;
@@ -79,14 +78,12 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
private ListView mDrawerList;
private List<DocumentPartView> mDocumentPartView = new ArrayList<DocumentPartView>();
private DocumentPartViewListAdapter mDocumentPartViewListAdapter;
- private int partIndex=-1;
private DocumentOverlay mDocumentOverlay;
/** URI of the actual document. */
private Uri mDocumentUri;
/** Temporary local copy of the document. */
private File mTempFile = null;
private File mTempSlideShowFile = null;
- public boolean firstStart = true;
BottomSheetBehavior bottomToolbarSheetBehavior;
BottomSheetBehavior toolbarColorPickerBottomSheetBehavior;
@@ -120,7 +117,6 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
private boolean isSearchToolbarOpen = false;
private static boolean isDocumentChanged = false;
private boolean isUNOCommandsToolbarOpen = false;
- private boolean isNewDocument = false;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -171,6 +167,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
mDocumentOverlay = new DocumentOverlay(this, layerView);
mbISReadOnlyMode = !isExperimentalMode();
+ boolean isNewDocument = false;
mDocumentUri = getIntent().getData();
if (mDocumentUri != null) {
@@ -182,6 +179,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
String newDocumentType = getIntent().getStringExtra(LibreOfficeUIActivity.NEW_DOC_TYPE_KEY);
// create a temporary local file, will be copied to the actual URI when saving
loadNewDocument(newDocumentType);
+ isNewDocument = true;
isReadOnlyDoc = false;
} else {
isReadOnlyDoc = (getIntent().getFlags() & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
@@ -211,6 +209,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
Log.e(LOGTAG, "couldn't create temporary file from " + mDocumentUri);
return;
}
+ LOKitShell.sendLoadEvent(mTempFile.getPath());
}
mDrawerLayout = findViewById(R.id.drawer_layout);
@@ -277,7 +276,6 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
String tempFileName = "LibreOffice_" + UUID.randomUUID().toString();
mTempFile = new File(this.getCacheDir(), tempFileName);
LOKitShell.sendNewDocumentLoadEvent(mTempFile.getPath(), newDocumentType);
- isNewDocument = true;
}
public RectF getCurrentCursorPosition() {
@@ -397,28 +395,20 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
protected void onStart() {
Log.i(LOGTAG, "onStart..");
super.onStart();
- if (!isNewDocument){
- if (partIndex == -1)
- LOKitShell.sendLoadEvent(mTempFile.getPath());
- else
- LOKitShell.sendResumeEvent(mTempFile.getPath(), partIndex);
- }
+ LOKitShell.sendEvent(new LOEvent(LOEvent.REFRESH));
}
@Override
protected void onStop() {
Log.i(LOGTAG, "onStop..");
- //save document to cache
- if (mTileProvider != null)
- mTileProvider.cacheDocument();
hideSoftKeyboardDirect();
- LOKitShell.sendCloseEvent();
super.onStop();
}
@Override
protected void onDestroy() {
Log.i(LOGTAG, "onDestroy..");
+ LOKitShell.sendCloseEvent();
mLayerClient.destroy();
super.onDestroy();
@@ -845,7 +835,6 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DocumentPartView partView = mDocumentPartViewListAdapter.getItem(position);
- partIndex = partView.partIndex;
LOKitShell.sendChangePartEvent(partView.partIndex);
mDrawerLayout.closeDrawer(mDrawerList);
}