-
Notifications
You must be signed in to change notification settings - Fork 716
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
Simultaneous access JAVA / CordovaJS errors #309
Comments
It _should_ be possible to get concurrent access working from both Java and
Cordova Javascript but it would need adjustments on both sides, and some
testing on our part. I will describe what needs to be done sometime next
week.
|
I mean concurrent access to the same sqlite database from both Java and |
Ok, thank you for your quick response!! I eagerly await your advice! In my app, the service side (java) write in some tables, and the cordova js in other tables. Just for information, in terms of adjustments I've done: => Cordova JS Side: See you soon! |
It would help me if I can understand your problem a little better. You write about an app, which is using Cordova, and a background service, which is using Java. Is the app acting as the background service, or are they two different things? Are you using Java and Javascript from the same process, two different processes, or both? If I understand your description correctly, you problem has two parts:
Am I correct or am I missing something? How do you plan to make the iOS version? So far, I can think of the following alternative solutions:
Solution 1 will work, but needs an additional Solution 2 needs a Java API enhancement to allow the Java code to lookup the database handle that is opened for your database file. Also, Android-sqlite-native-driver (which is used by the Android-sqlite-connector library) has to be rebuilt with the I think solution 3 is self-explanatory. Solution 4 should work (if you do it right). In general, in solution 1, sqlite is acting as a better version of solution 4, assuming we don't encounter locking issues. If the Java and Javascript are in the same process, solution 3 would be the best solution since it is completely safe from any possible issues with file access and multi-threading. I am very reluctant to provide either solution 2 or solution 3 for free, primarily due to the possible maintenance issues that can result. Also, solution 2 requires you to use the Android-sqlite-connector API to access the database from Java and will not work if you use the |
Hello and thank you for your answer! My application consists of a backgroung service launched at phone boot, as well as a user interface that is triggered when the user wants, or when it receives notification from the service and click on it on the notification bar. For now the app works good. But periodically the app crash... Service side: GUI side: I don't know if Java and Javascript are running in the same process... Because the service is starting at boot, and the GUI launched by the user... You are right with this:
The two ways on the same database. For the IOS version, i plan to do the same. But for IOS the service will not start at boot-time, but when specific system events occurs and launch it. For the solution 2 i already have implement the androidDatabaseImplementation: 2 option in window.sqlitePlugin.openDatabase() and the androidLockWorkaround: 1 option. I can very well understand that implement options 2 and 3 take a long time and you do not want to! no problemo! For you, there would be no easy way to solve my problem? If the information I have given you can better direct you, I'd be delighted! |
UPDATED: For the Android app to get its own pid: int id = android.os.Process.myPid(); as described in http://stackoverflow.com/questions/25963677/android-determinine-my-apps-process-id and documented at: http://developer.android.com/reference/android/os/Process.html#myPid%28%29 For the Cordova process to get its own PID: this can be done through a new For the Cordova app to get the pid of the Java process: let the Java
I suspect it should be possible to get solution 1 to work for you, if I
Solution 4 might be the easiest, at least for now. Commonly done and One thing: I would not rely on the file system (or a database file) for change notifications. But I suspect you have thought of this issue along with a solution already. |
I've just extend a cordova plugin to get Cordova app PID, and on the other side i've extend the service to get the PID.
If service is launched by the app, the PID is the same for Cordova javascript and the JAVA service.
Until you possibly put up the read-only option (Option 1), I'll maybe use the Solution 4. I'm always taking if you have other ideas or tips! :-) See you' PS: I also read about the content-provider to check a database, what do you think? |
I just read about Android content provider's and it sounds like a great idea if it can solve your problem. I just found an Android content provider plugin at: https://github.com/phearme/cordova-ContentProviderPlugin Its plugin.xml specifies Apache 2.0 license, I just asked for an explicit license statement in r-cohen/cordova-ContentProviderPlugin#2. FYI additional resource: http://www.vogella.com/tutorials/AndroidSQLite/article.html - Android SQLite database and content provider tutorial |
Thank's :-) The only problem is for the IOS version with the "content-provider" mode. I'm wrong? If it will be the best choise for me, i will find an other way for the ios version ;-) |
Unfortunately the content provider solution is Android-specific. So is the background service, if I am not mistaken. Do you want to describe, in very general terms, what you are using the background for and how you are thinking to achieve something similar for iOS? FWIW, I also found https://github.com/Red-Folder/Cordova-Plugin-BackgroundService which is now split into two parts: |
Sorry for the response time! For background services I use a class that I created that extends the class service. From what I read, it is also possible to have a back-up on IOS services, but for a limited duration (minutes), and can not start at boot the phone. The way I've found to achieve what interests me is to start my service in IOS when GPS coordinates change (IOS allows it apparently). One of my source (obviously reliable ^^): |
I have thie error when my app is freezing:
It occurs typically when i call the getWritableDatabase() on my SQLiteOpenHelper db. Perhaps an answer here What do you think of this? But with this method i have to access to the database only using DatabaseManager from javascrip (plugin) and Service side, right? |
That sounds right, though I really have to investigate it to be sure. I may Sent from my mobile |
Thank's! I think I will test this solution also after testing an intermediate solution: have a database on the background service side, and flat files generated for the javascriptside (by the service or the javascript side). Have a good weekend! |
Finaly i set up a bypass to this problem. I just added a try catch around the getWritableDatabase (). The whole being in a loop with a maximum number of executions set to 10, and a sleep set at 0.5 seconds. If getWritableDatabase () works, it exits the loop, and if no, it retries up to 10 times. I know it is not nice at all, but I put this "patch" to continue to develop the app without incessant bugs ... I promise I'll do something cleaner later (with your help? :-) )! PS: is it possible to call your classes (to open DB, copy it from assets to the cache, insert/update/select) directly from my Service with a java code? It seems that your plugin (side javascript) crash unless the java service side! |
Do you put getWritableDatabase() in the loop only the first time you open the database, or do you have to use getWritableDatabase() for every transaction? If you only have to use getWritableDatabase() in the beginning, it should not give you any performance issues and we can fix this at our leisure. If you have to do this for every transaction, it will probably hurt your performance and we should look for a better solution. Note that if you use the For the future, I am thinking to change the Java structure to make it easier for the user to plug in his/her own database implementation class. |
In fact, I use getWritableDatabase () for each transaction on the java side to close as soon as possible the base so that other transaction (from your cordova plugin for example) can take place without collision and be sure that the base is writable and not locked for a long time. Maybe in my case, if I want to use only one database, I would have to use it with the same classes on both sides (Cordova / JS & Java). Maybe this solution (mentioned two days ago) turned into specific plugin cordova for my needs with classes directly accessible in java might be the best solution? Whith this i do not have to call multiple getWritableDatabase (), and use only one connexion for both sides (from what I understand). |
Hi @thierrybx I may need a few weeks to implement a better solution for you. In addition, I am thinking to implement this in an enterprise version that will be available under GPL or purchased commercial licensing terms which I would offer to you for a discount (or maybe for free if you help me test it). Thanks for your patience so far. |
Excellent! |
Hi! After hours of coding, I managed to ensure that everything works from both sides without conflict! By cons I no longer passes through your plugin but by a specific plugin to my needs that plugs directly into Java classes that I created to check and update the database. No bugs since a long time! Here are some excerpts of my code
Database Helper:
And the class to execute stuff:
An finaly a class with static calls from cordova.exec OR JAVA service for exemple:
The call in cordova side ( cordova.exec(onsuccess,onerror, "Launcher", "getSuperStuff", []); ) :
|
Thanks for sharing! You have now found a simpler solution to fulfill the needs of your problem and I think you have learned a lot from working on it. Sometimes it makes sense to build the custom components exactly as you need them for your application, and sometimes it is the things that you don't share that give you the competitive edge, at least for a period. This project aims to be very general purpose with a standardized transaction API, which unfortunately has led to its level of complexity. I am planning to make a simpler API to help reduce the complexity when I get a chance. It would be cool to find a way to provide your solution in a more general purpose manner, and I can think of several alternatives. Of course, it would be possible to enhance the Android version of this project to support the Database Manager & Database Helper functionality, and I may do something like this for a "pro" version. But it only helps developers on the Android platform and further increases the complexity. A second alternative would be to build an Android-specific plugin that provides the database manager/helper functionality. Or a plugin such as @phearme/cordova-ContentProviderPlugin that does a query on a custom content provider. I am closing this for now, may revisit this later. |
Thanks for all! Discuss with you allowed me to mature my reflection. PS: I will upgrade my plugin to do the same on the iphone platform, with dual access! |
Hi @thierrybx, I did not see your PS question until now. Did you make the solution for iPhone? If so, do you want to share it? |
Hi @brodybits ! For the iPhone platform i finally use only json files. Easyer... |
Hello,
I am trying to make an app (Android to begin, and then IOS) that one side (JAVA) executes SQL statements on a database stored on the phone (imported once from the www folder and using SQLiteOpenHelper ..) in java from a background service starting at the boot. No worries on that side.
On the other hand (CordovaJS) I check / update the same database from the same application, but in the GUI (webview) via the cordova Cordova-storage-sqlite plugin. No worries either on that side ...
But when JAVA and CordovaJS try to use the database at the same time, the app crash sometimes...
How can I do to access to the base of both sides simultaneously?
Otherwise what would be the best solution:
I'd rather largely retain only one database ...
Thank you in advance for review
PS: Sorry for my English, I'm French :(
The text was updated successfully, but these errors were encountered: