Closed Popolechien closed 1 month ago
@Popolechien Thanks for the log file, there is enough information in the log file to fix the problem.
@MohitMaliFtechiz For this issue, il would request:
@kelson42 The issue is related to the file system. We are using the ContextCompat.getExternalFilesDirs() function to retrieve the file directories for our application's storage. However, this function can return null when the file system (e.g., an SD card) is unavailable.
This issue occurred when we tried to access ZIM files from the application’s folder in the zimFiles() method. In this method, we add directories to a non-null list of files. However, when attempting to retrieve the list of files from the application directory, the SD card path was null due to the SD card being unmounted, which caused the application to crash.
java.lang.NullPointerException: dir must not be null
at org.kiwix.kiwixmobile.custom.main.CustomFileValidator.zimFiles(CustomFileValidator.kt:46)
at org.kiwix.kiwixmobile.custom.main.CustomReaderFragment.openObbOrZim(CustomReaderFragment.kt:30)
at org.kiwix.kiwixmobile.custom.main.CustomReaderFragment.onViewCreated(CustomReaderFragment.kt:204)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:254)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:146)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:58)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:34)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:259)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:146)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:58)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:34)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:32)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:1)
at org.kiwix.kiwixmobile.core.main.CoreMainActivity.onStart(CoreMainActivity.kt:1)
at org.kiwix.kiwixmobile.custom.main.CustomMainActivity.onStart(CustomMainActivity.kt:1)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1510)
at android.app.Activity.performStart(Activity.java:8616)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:4204)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2574)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8762)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
Quantitative impact estimation over all our apps
This is a specific edge case that only occurs when an SD card is unmounted while the application is running. It will not affect all users; only those who unmount their SD card while the application is trying to access the directory will experience this issue.
Automated test to avoid late detection in the future
Sure, i am writing test cases for this.
@MohitMaliFtechiz Thank you for the explanation. Before we talk about appropriate error handling. Can you please tell me how the user can save an app on their SD card?
@MohitMaliFtechiz Thank you for the explanation. Before we talk about appropriate error handling. Can you please tell me how the user can save an app on their SD card?
@kelson42 The application itself is not saved on the SD card. In custom apps, we store ZIM files as expansion files in the OBB folder. We have a fallback system in place: if the ZIM file is not present, the user can download it via the custom app's download page. The ZIM file is then downloaded to the storage location with the most available space, as per our logic. If the SD card has more available space than internal storage, the ZIM file will be downloaded to the SD card. To account for this, we scan both internal and external storage using methods like obbFiles, and zimFiles
In this crash scenario, the application crashed while scanning the SD card.
@MohitMaliFtechiz Thank you again for the explanation. To me - as it is - it seems to be too much of hack. Do you remember exactly or could investigate which issue justified the implementation of this feature?
@kelson42 This feature was introduced here https://github.com/kiwix/kiwix-android/pull/1580 for this issue https://github.com/kiwix/kiwix-android/issues/64, and the fallback method was proposed here https://github.com/kiwix/kiwix-android/issues/64#issuecomment-548325163.
OK, Inbelieve all of this is pretty complex but I'm not bold enough to just remove it (for the moment).
At least this time the user provided a log. Should I ask for more info?
logs1726851491827.txt