Android Question Random Crashes

ddahan

Member
Licensed User
Longtime User
Hi,
I'm working on a project with one activity, many classes , services and SQL databases. the app suppose to constantly running in the background and the user may get the GUI by demand.
The app is running well the most of the time but I'm facing random crashes related to SQL DBs (not always in the same DB).
I validated all objects were well declared and initialized in all sequences to the crash.
Crashes occurs mostly when GUI is not visible and the App is in background for a long time. I cannot recall crashes during interactive work with the app.
There is not difference if databases are in internal or external storage.
The following is a log of a typical crash:
** Activity (main) Resume **
android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14)
at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:845)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:144)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
at anywheresoftware.b4a.sql.SQL$CursorWrapper.getRowCount(SQL.java:313)
at com.Mindspot.Mindset.mabstract._getupperlinkedspecifictypeabstracts(mabstract.java:2284)
at com.Mindspot.Mindset.dbfunctions._gettoptags(dbfunctions.java:202)
at com.Mindspot.Mindset.main._finalizelowerobjectslist(main.java:4236)
at com.Mindspot.Mindset.main._setuplowerobjectslist(main.java:6920)
at com.Mindspot.Mindset.main._createobjectsmap(main.java:1780)
at com.Mindspot.Mindset.main._activity_resume(main.java:919)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:159)
at com.Mindspot.Mindset.main$ResumeMessage.run(main.java:273)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)


There is other type of crash the may be related. it seems that somehow variables/objects that were declared and recognized stopped to be recognized.
The following is a log of timer based triggered service crash case:
** Service (eventssync) Start **
java.lang.IllegalStateException: Interval must be larger than 0.
at anywheresoftware.b4a.objects.Timer.setEnabled(Timer.java:79)
at com.Mindspot.Mindset.eventssync._service_start(eventssync.java:192)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:159)
at com.Mindspot.Mindset.eventssync.handleStart(eventssync.java:68)
at com.Mindspot.Mindset.eventssync.onStartCommand(eventssync.java:53)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2726)
at android.app.ActivityThread.access$2100(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1302)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
at dalvik.system.NativeStart.main(Native Method)


Your help will be appreciated.

Thanks,
David.
 

yaz

New Member
Licensed User
Longtime User
1. First Error you need to put in a check to find out why the open database file is failing to open, maybe its blank file name.

2. Second Error you need to find out where in your code the Timer interval is being set to Zero
below would cause same error.

B4X:
Sub Process_Globals
Dim MyTimer as Timer
End Sub

Sub Activity_Create(FirstTime As Boolean)
dim n as Long

If FirstTime Then
  n=0
  MyTimer.Initialize("Mytimerfinished",n * 1000)  ' 1,000 ms = 1 Second

  'or
  n=0
  MyTimer.Interval(n * 1000)

End If
End Sub

Sub Mytimerfinished_tick
MyTimer.Enabled=False
Log("MyTimer ended  !")
End Sub
 
Upvote 0

ddahan

Member
Licensed User
Longtime User
Hi yaz,
Thanks for replying.
I already did the debugging steps you proposed.
1. No blank file name or any related things.
2. the timer is initialized one time at service creation stage :
B4X:
Sub Service_Create
    EventsSyncTimer.Initialize("EventsSyncTimer",iSetup.EventsSyncInterval)
End Sub

You are right, the service is created again but this time iSetup.EventsSyncInterval variable is not valid. this is the problem, variables the were well declared now are no longer valid.
I cannot understand why this happens .

thanks,
David.
 
Upvote 0

yaz

New Member
Licensed User
Longtime User
You need to find where the iSetup.EventsSyncInterval is set making sure its not getting set to zero.

This will be before the service is started with StartService(MyService)
 
Upvote 0

ddahan

Member
Licensed User
Longtime User
iSetup.EventsSyncInterval is defined at the app launch stage and no one touch him again.
 
Upvote 0

yaz

New Member
Licensed User
Longtime User
Try setting it to same value direct in Sub Service_Create , I have set it to 1000
B4X:
Sub Service_Create
    EventsSyncTimer.Initialize("EventsSyncTimer",1000)
End Sub

If this stops the error, could be a bug in B4A.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You are right, the service is created again but this time iSetup.EventsSyncInterval variable is not valid. this is the problem, variables the were well declared now are no longer valid.
I cannot understand why this happens .
My guess is that you assume that the process always starts from the main Activity. This is not the case with apps that run in the background. The process can be killed and later start from the service.
 
Upvote 0

ddahan

Member
Licensed User
Longtime User
Thanks Erel,
Please correct me if I'm wrong, Variables declared in main activity may not be valid to the background service since main could be killed.
What is the best/safe place to declare process variables ?
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Store it in a KeyValueStore and load the values in your service from the KVS at service_create
 
Upvote 0

ddahan

Member
Licensed User
Longtime User
This approach works, but in case of a repetitive loop a performance issue may be noticeable.
I tried to use variables declared in a code module (that supposed to be static) but they are note valid after a period of time.
Is there any alternative way to preserve static variables to be used by services when the app is in the background?
 
Upvote 0

ddahan

Member
Licensed User
Longtime User
Now I'm getting random crashes caused by inability to open KeyValueStore database:
=========== TP 3 ==============
android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14)
at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:845)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:144)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
at anywheresoftware.b4a.sql.SQL$CursorWrapper.getRowCount(SQL.java:313)
at b4a.example.keyvaluestore._getsimple(keyvaluestore.java:226)
at com.Mindspot.Mindset.utils._kvsgetboolean(utils.java:1276)
at com.Mindspot.Mindset.callslistener._callstates(callslistener.java:238)
at com.Mindspot.Mindset.callslistener._pe_phonestatechanged(callslistener.java:411)


at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:159)
at anywheresoftware.b4a.phone.PhoneEvents$ActionHandler.send(PhoneEvents.java:326)
at anywheresoftware.b4a.phone.PhoneEvents$15.handle(PhoneEvents.java:245)
at anywheresoftware.b4a.phone.PhoneEvents$16.onReceive(PhoneEvents.java:268)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:766)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
at dalvik.system.NativeStart.main(Native Method)
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } in anywheresoftware.b4a.phone.PhoneEvents$16@424134f0
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:776)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:201)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:159)
at anywheresoftware.b4a.phone.PhoneEvents$ActionHandler.send(PhoneEvents.java:326)
at anywheresoftware.b4a.phone.PhoneEvents$15.handle(PhoneEvents.java:245)
at anywheresoftware.b4a.phone.PhoneEvents$16.onReceive(PhoneEvents.java:268)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:766)


The following is the object that uses KeyValueStore :
B4X:
Sub KVSGetBoolean( Key As String, DbugMsg As String) As Object
    Dim IntegerToBoolean() As Boolean
    IntegerToBoolean=Array As Boolean(False, True)
    Dim KVSObject As KeyValueStore
    KVSObject.Initialize(File.DirDefaultExternal, "MindsetVariables")
    Dim SimpleValue As Object
    Dim Value As Object
    SimpleValue = KVSObject.GetSimple(Key)
    If SimpleValue <> "0" AND SimpleValue <> "1" Then
         Return False
    Else
        Value = IntegerToBoolean(SimpleValue)
        Return Value
    End If
End Sub
Cannot find the reason that makes the DB not accessible .
I will appreciate your advice.

Thanks,
David.
 
Last edited:
Upvote 0

ddahan

Member
Licensed User
Longtime User
KVSObject is created and activated by a service. I tried to do that but after awhile the app crashes with error message that SQL database has to be initialize.
I guess that this is the same problem as with variables, They are vanished when the process terminated.
 
Upvote 0
Top