Start a new topic

Data Saved Offline is not synced when back to Online

## Please read first my comment "ISSUE MORE CLEAR" ----

Took me a long time to discover that to use the Offline feature I need to include the kinvey.properties file in assets. Will be good to make it clear in the documentation.

Now I can save offline but when go back to online the data saved offline is NOT transmitted (sync) to the kinvey backend. Follows the test sequence:

1 Online: Login

2 Online: Save a entity and check if it is in Kinvey backend

3 Go to Offline by manually enter in airplane mode.

4 Offline: save a entity

5 Make a get to verify if the entity was saved locally.

6 Change to online (airplane mode = off)

7 Check if the backend was updated : Answer NO

What I have to do to make sync to be done when go back to Online??

Thanks.

Follows my very simple test code based in the Kinvey Testdrive example:

( Login is in onCreate and save is in onBlocanteClick )





private Client kinveyClient;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_test_drive);

bar = (ProgressBar) findViewById(R.id.refresh_progress);

bar.setIndeterminate(true);



kinveyClient = new Client.Builder(this.getApplicationContext()).build();

kinveyClient.user().logout().execute();

if (!kinveyClient.user().isUserLoggedIn()) {

bar.setVisibility(View.VISIBLE);



kinveyClient.user().login("xxxxx","yyyyy", new KinveyUserCallback() {

@Override

public void onSuccess(User result) {

bar.setVisibility(View.GONE);

Log.i(TAG,"Logged in successfully as " + result.getId() + kinveyClient.user().get("username"));

Toast.makeText(TestDrive.this, "user logged as " + result.getId() + kinveyClient.user().get("username") ,

Toast.LENGTH_LONG).show();

}



@Override

public void onFailure(Throwable error) {

bar.setVisibility(View.GONE);

Log.e(TAG, "Login Failure", error);

Toast.makeText(TestDrive.this, "Login error: " + error.getMessage(), Toast.LENGTH_LONG).show();

}

});

} else {

Toast.makeText(this, "Using user " + kinveyClient.user().get("username"), Toast.LENGTH_LONG).show();

}

}



public void onBlocanteClick(View view) {

final Context context = this; //.getActivity();

Elemento ele = new Elemento("velocidade", ">", "19 11:04",3.2); // para teste

AsyncAppData apdb = kinveyClient.appData(Elemento.COL_ELEMENTOS, Elemento.class);

apdb.setOffline(OfflinePolicy.ONLINE_FIRST, new SqlLiteOfflineStore(context));

Elemento elemento = null;

try {

elemento = apdb.saveBlocking(ele).execute();

} catch (IOException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

}

Hey,



It seems like this might be a device specific issue, especially considering things seem to be working on the emulator.



Can you open `settings` on these devices, goto `about phone`, and take some screenshots of the values these devices have? Such as `Android Version`, `Kernel Version`, `CPU`, etc.?



That might help me figure out what is going on with these two Samsung devices.
## OK, results from the last tests:

1) testing in Eclipse (ADT) DEBUG mode. Results => exception inside the get method. See the print from the ADT variable window and ADT SQLiteCursor.class window on the end of this comment. When I click in the resume button the program resumes and go to onSuccess return from the get method!! -----

2) testing in Eclipse (ADT) RUN mode. Results => The program works normally and do not crash!!!! -----##

3) An other test: insert back the "android:process=":background sync"" in the manifest file and test in RUN mode instead in DEBUG mode. Result => The issue from background communication continues to happen even in RUN mode, the data was NOT saved in kinvey backend.



**************************

## Exception in ADT Variable window:



this SQLiteCursor (id=830008375544)

DBG false

mClosed true

mColumnNameMap null

mColumns String[1] (id=830008036280)

mContentObservable ContentObservable (id=830008478200)

mContentResolver null

mCount 0

mCurrentRowID null

mCursorState 0

mDatabase SQLiteDatabase (id=830008486496)

mDataSetObservable DataSetObservable (id=830008393728)

mDriver SQLiteDirectCursorDriver (id=830008485944)

mEditTable "query_Elementos" (id=830008000256)

mInitialRead 2147483647

mLock null

mMaxRead 2147483647

mNotificationHandler null

mNotifyUri null

mPendingData false

mPos 0

mQuery SQLiteQuery (id=830008478240)

mRowIdColumnIndex 0

mSelfObserver null

mSelfObserverLock Object (id=830008218120)

mSelfObserverRegistered false

mStackTrace DatabaseObjectNotClosedException (id=830008376448)

mStackTraceElements null

mUpdatedRows HashMap (id=830008375696)

mWindow null

*****************************************************************************************





## in ADT open a SQLiteCursor.class with Source not found message



copy from this ADT window:



// Compiled from SQLiteCursor.java (version 1.5 : 49.0, super bit)

public class android.database.sqlite.SQLiteCursor extends android.database.AbstractWindowedCursor {



// Method descriptor #8 (Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteCursorDriver;Ljava/lang/String;Landroid/database/sqlite/SQLiteQuery;)V (deprecated)

// Stack: 3, Locals: 5

@java.lang.Deprecated

public SQLiteCursor(android.database.sqlite.SQLiteDatabase db, android.database.sqlite.SQLiteCursorDriver driver, java.lang.String editTable, android.database.sqlite.SQLiteQuery query);

0 aload_0 [this]

1 invokespecial android.database.AbstractWindowedCursor() [1]

4 new java.lang.RuntimeException [2]

7 dup

8 ldc [3]

10 invokespecial java.lang.RuntimeException(java.lang.String) [4]

13 athrow

Line numbers:

[pc: 0, line: 6]

Local variable table:

[pc: 0, pc: 14] local: this index: 0 type: android.database.sqlite.SQLiteCursor

[pc: 0, pc: 14] local: db index: 1 type: android.database.sqlite.SQLiteDatabase

[pc: 0, pc: 14] local: driver index: 2 type: android.database.sqlite.SQLiteCursorDriver

[pc: 0, pc: 14] local: editTable index: 3 type: java.lang.String

[pc: 0, pc: 14] local: query index: 4 type: android.database.sqlite.SQLiteQuery



// Method descriptor #25 (Landroid/database/sqlite/SQLiteCursorDriver;Ljava/lang/String;Landroid/database/sqlite/SQLiteQuery;)V

// Stack: 3, Locals: 4

public SQLiteCursor(android.database.sqlite.SQLiteCursorDriver driver, java.lang.String editTable, android.database.sqlite.SQLiteQuery query);

0 aload_0 [this]

1 invokespecial android.database.AbstractWindowedCursor() [1]

4 new java.lang.RuntimeException [2]

7 dup

8 ldc [3]

10 invokespecial java.lang.RuntimeException(java.lang.String) [4]

13 athrow

Line numbers:

[pc: 0, line: 7]

Local variable table:

[pc: 0, pc: 14] local: this index: 0 type: android.database.sqlite.SQLiteCursor

[pc: 0, pc: 14] local: driver index: 1 type: android.database.sqlite.SQLiteCursorDriver

[pc: 0, pc: 14] local: editTable index: 2 type: java.lang.String

[pc: 0, pc: 14] local: query index: 3 type: android.database.sqlite.SQLiteQuery



// Method descriptor #27 ()Landroid/database/sqlite/SQLiteDatabase;

// Stack: 3, Locals: 1

public android.database.sqlite.SQLiteDatabase getDatabase();

0 new java.lang.RuntimeException [2]

3 dup

4 ldc [3]

6 invokespecial java.lang.RuntimeException(java.lang.String) [4]

9 athrow

Line numbers:

[pc: 0, line: 8]

Local variable table:

[pc: 0, pc: 10] local: this index: 0 type: android.database.sqlite.SQLiteCursor



// Method descriptor #29 (II)Z

// Stack: 3, Locals: 3

public boolean onMove(int oldPosition, int newPosition);

0 new java.lang.RuntimeException [2]

3 dup

4 ldc [3]

6 invokespecial java.lang.RuntimeException(java.lang.String) [4]

9 athrow

Line numbers:

[pc: 0, line: 9]

Local variable table:

[pc: 0, pc: 10] local: this index: 0 type: android.database.sqlite.SQLiteCursor

[pc: 0, pc: 10] local: oldPosition index: 1 type: int

[pc: 0, pc: 10] local: newPosition index: 2 type: int



// Method descriptor #34 ()I

// Stack: 3, Locals: 1

public int getCount();

0 new java.lang.RuntimeException [2]

3 dup

4 ldc [3]

6 invokespecial java.lang.RuntimeException(java.lang.String) [4]

9 athrow

Line numbers:

[pc: 0, line: 10]

Local variable table:

[pc: 0, pc: 10] local: this index: 0 type: android.database.sqlite.SQLiteCursor



// Method descriptor #36 (Ljava/lang/String;)I

// Stack: 3, Locals: 2

public int getColumnIndex(java.lang.String columnName);

0 new java.lang.RuntimeException [2]

3 dup

4 ldc [3]

6 invokespecial java.lang.RuntimeException(java.lang.String) [4]

9 athrow

Line numbers:

[pc: 0, line: 11]

Local variable table:

[pc: 0, pc: 10] local: this index: 0 type: android.database.sqlite.SQLiteCursor

[pc: 0, pc: 10] local: columnName index: 1 type: java.lang.String



// Method descriptor #39 ()[Ljava/lang/String;

// Stack: 3, Locals: 1

public java.lang.String[] getColumnNames();

0 new java.lang.RuntimeException [2]

3 dup

4 ldc [3]

6 invokespecial java.lang.RuntimeException(java.lang.String) [4]

9 athrow

Line numbers:

[pc: 0, line: 12]

Local variable table:

[pc: 0, pc: 10] local: this index: 0 type: android.database.sqlite.SQLiteCursor



// Method descriptor #41 ()V

// Stack: 3, Locals: 1

public void deactivate();

0 new java.lang.RuntimeException [2]

3 dup

4 ldc [3]

6 invokespecial java.lang.RuntimeException(java.lang.String) [4]

9 athrow

Line numbers:

[pc: 0, line: 13]

Local variable table:

[pc: 0, pc: 10] local: this index: 0 type: android.database.sqlite.SQLiteCursor



// Method descriptor #41 ()V

// Stack: 3, Locals: 1

public void close();

0 new java.lang.RuntimeException [2]

3 dup

4 ldc [3]

6 invokespecial java.lang.RuntimeException(java.lang.String) [4]

9 athrow

Line numbers:

[pc: 0, line: 14]

Local variable table:

[pc: 0, pc: 10] local: this index: 0 type: android.database.sqlite.SQLiteCursor











The sync process seems to be correct, although that shouldn't be too much of an issue-- Adding it is more of a nice to have and it isn't really necessary.



As for queries-- that shouldn't be the case, they should work (for both offline and online).



There might be two separate issues here, first let's look at the online query-- can you post the error you are getting when you try to execute a query while online?
Thanks Edward,

I tested with 2 different Samsung models GT-B5510B and GT-19000B, (both with android 2.3) with the same problem in both devices. I will try to test with a device with a different android version. Write now, for the offline features, can I assume that for the Android 2.3 I need to run the sync process in the application thread AND I can't use queries (online OR offline)??
Hey,



After some investigation it looks like this issue occurs because a database transaction takes too long to finish up. I am not able to reproduce this, are you able to test it on any other devices? I wander if it is an issue with the 2.3 device, and if so, I'll have to do some more investigation for a workaround.



Also--



as for the other issue you linked, it is expected to see that message in the logs, however the library should catch it and load data from the database. Note that ONLINE_FIRST implies it tries to connect to your backend, fails (with that error being logged), and then pulls from the database. Are you seeing the onSuccess block being executed?
## Actually the android version is 2.3.6



Start to work after a delete the (android:process=":background sync"). The following test was OK:----

1)Clear the kinvey backend and the local Sqlite base.

2)Online save and get data => Result OK

3) Offline data save and get data => Result OK

4)Change to online, nothing happened

5)save data => the new data was saved AND the data saved offline was saved at kinvey !!



BUT if a include a query in the get there is exception (SQLiteCursor). follows the test:----

1) Include the lines in the get procedure

Query q = apdb.query();

q.equals("qtyNome","velocidade"); ---

3)Online Save data => result OK

4)Online Get data => exception.

This query worked in other situations (emulator). It worked only in the get ALL situation. I tried to avoid [this](https://support.kinvey.com/discussion/comment/201744408#Comment_201744408 "this") situation using a query instead of a " get all".



Exception in the log.d ---- 04-21 16:45:02.679: W/dalvikvm(17383): HeapWorker may be wedged: 5619ms spent inside Landroid/database/sqlite/SQLiteCursor;.finalize()V



Follows the exception from debug.

this SQLiteCursor (id=830008438712)

DBG false

mClosed true

mColumnNameMap null

mColumns String[1] (id=830008239328)

mContentObservable ContentObservable (id=830008005760)

mContentResolver null

mCount 0

mCurrentRowID null

mCursorState 0

mDatabase SQLiteDatabase (id=830008549296)

mDataSetObservable DataSetObservable (id=830008072656)

mDriver SQLiteDirectCursorDriver (id=830007994920)

mEditTable "query_Elementos" (id=830007999072)

mInitialRead 2147483647

mLock null

mMaxRead 2147483647

mNotificationHandler null

mNotifyUri null

mPendingData false

mPos 0

mQuery SQLiteQuery (id=830008175760)

mRowIdColumnIndex 0

mSelfObserver null

mSelfObserverLock Object (id=830007823904)

mSelfObserverRegistered false

mStackTrace DatabaseObjectNotClosedException (id=830007988216)

mStackTraceElements null

mUpdatedRows HashMap (id=830008147592)

mWindow null
Hey,



Can you give me some more information about the device? Android 2.6 doesn't seem to be an official android release, so there might have been some custom modifications to it.



In the meantime, you had to declare a ` ... ` within your manifest. One of the attributes on that xml item is `android:process=":backgroundsync"`, can you try removing this? That will allow the sync service to run on the same thread as your application, which might help out with the above mentioned issue.

## Issue more clear.

My new test is this:

1) testing in real device Android vers 2.6.35.7 -----

2) Using OfflinePolicy.LOCAL_FIRST -----

3) Made some offline save-----

4) Change to online (wifi = on)----

5) Made a save online => Result: kinvey never was updated with the offline saved data.

6) Change to a emulated device (android 4.4) -----

7) Repeated the same test => Result kinvey was updated normally.-----

My conclusion: Problem in background sync process in Android 2.6

Please Help !

Thanks.

I tested more and found this:

The app crash if i use a query:

Query q = apdb.query();

q.equals("qtyNome","velocidade");

**The sync process works normally if I use the emulator** instead of the physical phone (Samsung Android 2.6)
There is this Log with a TAG MessageQueue, after the save !!



04-19 17:06:15.996: W/MessageQueue(2042): Handler{4056fa08} sending message to a Handler on a dead thread

04-19 17:06:15.996: W/MessageQueue(2042): java.lang.RuntimeException: Handler{4056fa08} sending message to a Handler on a dead thread

04-19 17:06:15.996: W/MessageQueue(2042): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:196)

04-19 17:06:15.996: W/MessageQueue(2042): at android.os.Handler.sendMessageAtTime(Handler.java:457)

04-19 17:06:15.996: W/MessageQueue(2042): at android.os.Handler.sendMessageDelayed(Handler.java:430)

04-19 17:06:15.996: W/MessageQueue(2042): at android.os.Handler.sendMessage(Handler.java:367)

04-19 17:06:15.996: W/MessageQueue(2042): at android.os.Message.sendToTarget(Message.java:349)

04-19 17:06:15.996: W/MessageQueue(2042): at android.os.AsyncTask$3.done(AsyncTask.java:214)

04-19 17:06:15.996: W/MessageQueue(2042): at java.util.concurrent.FutureTask$Sync.innerSet(FutureTask.java:253)

04-19 17:06:15.996: W/MessageQueue(2042): at java.util.concurrent.FutureTask.set(FutureTask.java:113)

04-19 17:06:15.996: W/MessageQueue(2042): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:311)

04-19 17:06:15.996: W/MessageQueue(2042): at java.util.concurrent.FutureTask.run(FutureTask.java:138)

04-19 17:06:15.996: W/MessageQueue(2042): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)

04-19 17:06:15.996: W/MessageQueue(2042): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)

04-19 17:06:15.996: W/MessageQueue(2042): at java.lang.Thread.run(Thread.java:1019)

Login or Signup to post a comment