I am trying to implement a solution for storing reference data in the database of my app.
The data is initially stored as JSON files, which I will need to sync from a server on each launch. I have a local copy of the files baked into the app. Each launch I have to check shared preferences for a version. And if it not present, I assume it is the first launch. So i need to read in the files, write the files to the database and fire on completed when that is done. The first screen expects this data to be in the database, so I will be not showing the UI for that screen in this scenario, until the process completes.
However in the future the network call to sync these files can happen asynchronously so want to be able to fire on completed on my observable as soon as i see the shared prefs have a version number and then ill kick of the update completely asynchronously
How can i set up a stream to represent this. I think the stream type will probably be void and i will just fire onCompleted/error as the subscriber doesnt care about the data, only what the process is complete
You could do something like this:
updateChecker.hasUpdates()
.flatMap(hasUpdates -> {
if (hasUpdates) {
return dataUpdater.update();
}
return Observable.just(false);
})
Assuming that
class UpdateChecker {
public Observable<Boolean> hasUpdates() {
return Observable.just(true); // Replace by API call
}
}
class DataUpdater {
public Observable<Boolean> update() {
// update the database here
return Observable.just(true);
}
}
Related
I am trying to have a system where I add an object (shifts in this context) and the front end receives that and processes that without refreshing the page and making another api call. Currently, I have two functions, getAllShifts and addShift. When I add a shift I expect the getAllShifts to be updated automatically using sinks. However, the response that I get is not something I expect. The code is shown below:
private Sinks.Many<Shift> shiftSink=Sinks.many().replay().latest();
public Mono<Shift> addShift(Shift shift) throws InterruptedException {
Mono<Shift> newshift= shiftRepository.save(shift);
newshift.subscribe(u-> this.shiftSink.tryEmitNext(u));
return newshift;
}
public Flux<Shift> getAllShifts(){
this.shiftRepository.findAll().subscribe(u-> this.shiftSink.tryEmitNext(u));
shiftSink.asFlux().subscribe(u-> System.out.println(u + "UUUUUUUUUUUUU"));
return shiftSink.asFlux();
}
When the getAllShifts endpoint is engaged from the frontend using eventsource and I add a shift, I expect to receive one event containing the data from that newly added shift. Instead multiple events containing that data are emitted as shown in the picture below.
Any help would be appreciated...
I use the Parse.com Cloud service in my Android app to sync data between devices.
I use the app mainly offline and use the local data store.
There is one class called Point that has a unique number as identifier I want to display. So when working offline I want to create a Point as draft (with a draft text as number) and when synchronizing I want it to get the real number that is unique over all the devices.
How would I set the number when saving? I was thinking about adding a WebHook in the cloud when saving the Point and giving it a unique number and then in my app use
newPoint.saveEventually(new SaveCallback() {
public void done(ParseException e) {
//query for the number
}
});
to query the point from the cloud to get the number after it has been saved. But this seems kind of too complicated for such a simple requirement. And I am not sure if the SaveCallback() is always triggered when saving it.
I would recommend using an afterSave trigger on the Point class to set the unique identifier when the object is newly created. Then, as you've mentioned, you'll need to fetch the value before displaying it.
Here's what the cloud code could look like:
// Assign the Point a unique identifier on creation
Parse.Cloud.afterSave("Point", function(request) {
// Check if the Point is new
if (!(request.object.existed())) {
// Get the unique identifier
var uniqueIdentifier = ...
// Set the unique identifier
request.object.set('uniqueIdentifier', uniqueIdentifier);
}
});
One important bit of information to keep in mind about using saveEventually with SaveCallback() is:
The callback will only be called if the operation completes within the
current app lifecycle. If the app is closed, the callback can't be
called, even if the save eventually is completed.
Source: Hector Ramos
If the unique identifier should be immediately displayed in the app or if the callback needs to be handled consistently, it would probably be best to use saveInBackground rather than saveEventually.
Another option would be to dynamically change the callback depending on network availability and/or offline settings. For example, if the offline mode is used anytime when the cell signal or wifi is unavailable, then network reachability could be used to check for a network and then use saveInBackground or saveEventually as appropriate.
Update
OP ended up using this code:
Parse.Cloud.beforeSave("Point", function(request, response) {
if (!(request.object.existed())) {
var query = new Parse.Query("Point");
query.addDescending("uniqueIdentifier");
query.first({
success: function(result) {
var maxId = result.get("uniqueIdentifier");
request.object.set("uniqueIdentifier", maxId + 1);
},
error: function() {
}
});
}
response.success();
});
I have a trouble, i need to get event/callback when i try to write to database.
I added greenDao lib to project, and i able to write/delete in db.
But no idea how to get callback after some operation under db.
In introduction to lib i read "AsyncOperationListener for asynchronous callback when operations complete".
Used this tutorial:
http://blog.surecase.eu/using-greendao-with-android-studio-ide/
Can anybody help me with this trouble?
UPD:
ok here we added some list in storage
getMyObjectDao().getSession().startAsyncSession().insertOrReplaceInTx(MyObject.class, list);
error here
List<MyObject> items = getBoxDao(c).getSession().startAsyncSession().loadAll(MyObject.class);
How can we asynchronously load data from db?
Is this correct solution?
#Override
public void onAsyncOperationCompleted(AsyncOperation operation) {
String operationIs = null;
switch (operation.getType()) {
case LoadAll:
itemsList = BoxRepository.getAllBoxes(getApplicationContext());
By default all the operations are performed synchronously, eliminating the need to get any callback. But the recent version of GreenDAO introduces AsyncSession, which can be used to perform operations asynchronously and also provides a way set listener on it. See the example below:
AsyncSession asyncSession = App.getInstance().daoSession.startAsyncSession();
asyncSession.setListener( new AsyncOperationListener() {
#Override
public void onAsyncOperationCompleted(AsyncOperation operation) {
// do whats needed
}
});
asyncSession.insert(MyObject);
Simple ask if anything unclear!
I have developed an application in Android that downloads a lot of data through XML query REST.
The problem is that every time you start the app takes a long time to download the data.
My question is:
How can I serialize these data, and update perhaps after a certain period of time?
I want some advice or idea to implement, or even better an example.
thanks
Use that one to serialize:
http://simple.sourceforge.net/
You can schedule an async task or a thread to update it.
Example for a thread that serializes data incl. a lock (only parts of the code)
static final Object sDataLock = new Object();
Serializer mSerializer;
class AsyncSave implements Runnable
{
Object mSerialize;
File mStorage;
public AsyncSave(Object serialize, File storage)
{
mSerialize = serialize;
mStorage = storage;
}
#Override
public void run()
{
try {
synchronized (sDataLock) {
// write
mSerializer.write(mSerialize, mStorage);
}
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
}
How can I serialize these data, and update perhaps after a certain period of time?
You can use thread/async task if you want certain data to be downloaded in certain activity. The async task/thread will be destroyed if the activity is destroyed.
If you want to download the data in certain time, use a Service instead. With a service, your data will be downloaded even if the apps is closed. For example, you can set your apps to download certain data once a day.
I have been working on a library for Android. The library has a method which fetches data from a web service and puts it in a database. The fetching part is, of course, not done on the main thread. Here's a sample method:
public void fetchData() {
remoteTable.get(new TableOperationCallback<TEntity>() {
public void onCompleted(TEntity entity, Exception exception, ServiceFilterResponse response) {
if (exception == null) {
//CALBACK RECEIVED
//Put data in local database.
}
});
}
Now, somewhere else in my app, where the library is being consumed, I do something like this to refresh the data:
public void refreshData(){
mylibrary.fetchData();
List<MyItems> mList = localtable.getItems();
}
Here, the first statement will go and fetch the data on background thread. So, the second statement will be executed even before the data is actually fetched. How do I get around this? I want the second statement to be executed only after the callback of the first is complete.
Edit: If it matters, the method refreshData is not in any activity. I put that method in a separate class (and called it ViewModel - .NET habit!).
You can have a look at this link
Android Update Current Activity From Background Thread
You basically want a Callback interface. When the task in the library completes, then you do what you have to do