Updating realm object by increments - android

I have a realm object that contains list of items with IDs
#SerializedName("products")
RealmList<ProductDialItem> products;
#SerializedName("previous_suppliers")
RealmList<SuppliersDialItem> previousSuppliers;
#SerializedName("tariffs")
RealmList<TariffsDialItem> tariffs;
#SerializedName("deposit_frequencies")
RealmList<SimpleDialItem> depositFrequencies;
#SerializedName("bank_codes")
RealmList<SimpleDialItem> bankCodes;
#SerializedName("gas_usages")
RealmList<SimpleDialItem> gasUsages;
And so on, each item in list has ID. The server sends a json response with values to be filled in the object.
But we also use Last-Modified header, so that server only sends items that changed. I want only to update items, not to delete any of them.
Tl;dr how do I only update/add items to realm, but not delete them

let the object contain:
class MyClass{
int x = 0;
int y = 0;
int z = 0;
}
then if you need to increment the variables from the web:
MyClass finalObject = new MyClass();
MyClass tempObject = new Gson().fromJson(response,MyClass.class);
incrementObjects(tempObject,finalObject);
and now create the method incrementObjects() :
private void incrementObjects(MyClass obj1, MyClass obj2){
obj2.x += obj1.x;
obj2.y += obj1.y;
obj2.z += obj1.z;
}

You can Query on Realm when you get updated data response like,
//Create RealmList when you get updated Data in your api response.
RealmList<YourModel> updatedData = yourResponseData.getData();
//Get data from localDatabase and Query on
RealmQuery<YourModel> where = mRealm.where(YourModel.class);
for (int i = 0; i < updatedData.size(); i++) {
//put condition to match data based on your database.
where = where.notEqualTo(YourModel.NAME,updatedData.get(i).getName());
}
//Now this where.findAll(); , will return list of data which is notEqual To updatedData
//perform update operation with this or deleteFrom local Data and insert new/updated Data.
where.findAll();

Related

Data from API parsing in for cycle with bad result

I parse data from API (https://statsapi.web.nhl.com/api/v1/standings) in for cycle. In debug mode, I see, that data are correct from API, but when I write first record to "tabulkaTimov", and for cycle have j=1 (j=2,j=3, ... etc), my first record is replace by next team.
Screenshot of my app:
https://ctrlv.cz/shots/2019/01/03/bbEf.png
It is table of NHL league.
public static List<TableTeamsModel> convertJsonToTableTeams(JsonObject data){
List<TableTeamsModel> tabulkaTimov = new ArrayList<>();
JsonArray pocetDivizii = data.get("records").getAsJsonArray();
for(int i=0;i<pocetDivizii.size();i++){
TableTeamsModel tabulka = new TableTeamsModel();
JsonObject division = pocetDivizii.get(i).getAsJsonObject();
tabulka.setDivisionName(division.get("division").getAsJsonObject().get("name").getAsString());
JsonArray teams = division.get("teamRecords").getAsJsonArray();
for(int j=0;j<teams.size();j++) {
JsonObject teamRecords = teams.get(j).getAsJsonObject();
tabulka.setTeamName(teamRecords.get("team").getAsJsonObject().get("name").getAsString());
tabulka.setGoalsGot(teamRecords.get("goalsAgainst").getAsInt());
tabulka.setGoalsScored(teamRecords.get("goalsScored").getAsInt());
tabulka.setPoints(teamRecords.get("points").getAsInt());
tabulka.setGamesPlayed(teamRecords.get("gamesPlayed").getAsInt());
tabulkaTimov.add(tabulka);
}
}
return tabulkaTimov;
}
Looks like you are creating a new tabulka object outside of your for loop and then add it multiple times in the same arraylist.
This will add it once (reference) and just update its content.
Here is what you can do
public static List<TableTeamsModel> convertJsonToTableTeams(JsonObject data){
List<TableTeamsModel> tabulkaTimov = new ArrayList<>();
JsonArray pocetDivizii = data.get("records").getAsJsonArray();
for(int i=0;i<pocetDivizii.size();i++){
// Remove the creation of the tabulka object from here
JsonObject division = pocetDivizii.get(i).getAsJsonObject()
JsonArray teams = division.get("teamRecords").getAsJsonArray();
for(int j=0;j<teams.size();j++) {
JsonObject teamRecords = teams.get(j).getAsJsonObject();
// And then put the object creation here.
// as we did't have it above, the division name has to be set here too.
TableTeamsModel tabulka = new TableTeamsModel();
tabulka.setDivisionName(division.get("name").getAsString());
tabulka.setTeamName(teamRecords.get("team").getAsJsonObject().get("name").getAsString());
tabulka.setGoalsGot(teamRecords.get("goalsAgainst").getAsInt());
tabulka.setGoalsScored(teamRecords.get("goalsScored").getAsInt());
tabulka.setPoints(teamRecords.get("points").getAsInt());
tabulka.setGamesPlayed(teamRecords.get("gamesPlayed").getAsInt());
tabulkaTimov.add(tabulka);
}
}
return tabulkaTimov;
}
This way you will add a different/new object each time you go over the loop into your ArrayList; - instead of adding the same reference of the same object every time with its data updated.

ArrayList<HashMap<String,String>> Overwrite the items in list [duplicate]

I'm adding three different objects to an ArrayList, but the list contains three copies of the last object I added.
For example:
for (Foo f : list) {
System.out.println(f.getValue());
}
Expected:
0
1
2
Actual:
2
2
2
What mistake have I made?
Note: this is designed to be a canonical Q&A for the numerous similar issues that arise on this site.
This problem has two typical causes:
Static fields used by the objects you stored in the list
Accidentally adding the same object to the list
Static Fields
If the objects in your list store data in static fields, each object in your list will appear to be the same because they hold the same values. Consider the class below:
public class Foo {
private static int value;
// ^^^^^^------------ - Here's the problem!
public Foo(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
In that example, there is only one int value which is shared between all instances of Foo because it is declared static. (See "Understanding Class Members" tutorial.)
If you add multiple Foo objects to a list using the code below, each instance will return 3 from a call to getValue():
for (int i = 0; i < 4; i++) {
list.add(new Foo(i));
}
The solution is simple - don't use the static keywords for fields in your class unless you actually want the values shared between every instance of that class.
Adding the Same Object
If you add a temporary variable to a list, you must create a new instance of the object you are adding, each time you loop. Consider the following erroneous code snippet:
List<Foo> list = new ArrayList<Foo>();
Foo tmp = new Foo();
for (int i = 0; i < 3; i++) {
tmp.setValue(i);
list.add(tmp);
}
Here, the tmp object was constructed outside the loop. As a result, the same object instance is being added to the list three times. The instance will hold the value 2, because that was the value passed during the last call to setValue().
To fix this, just move the object construction inside the loop:
List<Foo> list = new ArrayList<Foo>();
for (int i = 0; i < 3; i++) {
Foo tmp = new Foo(); // <-- fresh instance!
tmp.setValue(i);
list.add(tmp);
}
Your problem is with the type static which requires a new initialization every time a loop is iterated. If you are in a loop it is better to keep the concrete initialization inside the loop.
List<Object> objects = new ArrayList<>();
for (int i = 0; i < length_you_want; i++) {
SomeStaticClass myStaticObject = new SomeStaticClass();
myStaticObject.tag = i;
// Do stuff with myStaticObject
objects.add(myStaticClass);
}
Instead of:
List<Object> objects = new ArrayList<>();
SomeStaticClass myStaticObject = new SomeStaticClass();
for (int i = 0; i < length; i++) {
myStaticObject.tag = i;
// Do stuff with myStaticObject
objects.add(myStaticClass);
// This will duplicate the last item "length" times
}
Here tag is a variable in SomeStaticClass to check the validity of the above snippet; you can have some other implementation based on your use case.
Had the same trouble with the calendar instance.
Wrong code:
Calendar myCalendar = Calendar.getInstance();
for (int days = 0; days < daysPerWeek; days++) {
myCalendar.add(Calendar.DAY_OF_YEAR, 1);
// In the next line lies the error
Calendar newCal = myCalendar;
calendarList.add(newCal);
}
You have to create a NEW object of the calendar, which can be done with calendar.clone();
Calendar myCalendar = Calendar.getInstance();
for (int days = 0; days < daysPerWeek; days++) {
myCalendar.add(Calendar.DAY_OF_YEAR, 1);
// RIGHT WAY
Calendar newCal = (Calendar) myCalendar.clone();
calendarList.add(newCal);
}
Every time you add an object to an ArrayList, make sure you add a new object and not already used object. What is happening is that when you add the same 1 copy of object, that same object is added to different positions in an ArrayList. And when you make change to one, because the same copy is added over and over again, all the copies get affected.
For example,
Say you have an ArrayList like this:
ArrayList<Card> list = new ArrayList<Card>();
Card c = new Card();
Now if you add this Card c to list, it will be added no problem. It will be saved at location 0. But, when you save the same Card c in the list, it will be saved at location 1. So remember that you added same 1 object to two different locations in a list. Now if you make a change that Card object c, the objects in a list at location 0 and 1 will also reflect that change, because they are the same object.
One solution would be to make a constructor in Card class, that accepts another Card object. Then in that constructor, you can set the properties like this:
public Card(Card c){
this.property1 = c.getProperty1();
this.property2 = c.getProperty2();
... //add all the properties that you have in this class Card this way
}
And lets say you have the same 1 copy of Card, so at the time of adding a new object, you can do this:
list.add(new Card(nameOfTheCardObjectThatYouWantADifferentCopyOf));
It can also consequence of using the same reference instead of using a new one.
List<Foo> list = new ArrayList<Foo>();
setdata();
......
public void setdata(int i) {
Foo temp = new Foo();
tmp.setValue(i);
list.add(tmp);
}
Instead of:
List<Foo> list = new ArrayList<Foo>();
Foo temp = new Foo();
setdata();
......
public void setdata(int i) {
tmp.setValue(i);
list.add(tmp);
}

How to display database RANDOM in android listview

anyone know hot to display random data from database in mysql and display in listview?
i can display all data without random, but i want to displayed it random, anyone can help?
my code :
for (int i = 0; i < response.length() ; i++) {
try {
JSONObject obj = response.getJSONObject(i);
Exercise exercise = new Exercise();
if (obj.getString("KindOf").equals(textKind.getText().toString()) && obj.getString("Type").equals("Strength")) {
exercise.setTipe(obj.getString("Type"));
exercise.setJenis(obj.getString("KindOf"));
exercise.setNama(obj.getString("Name"));
exerciseList.add(exercise);
} catch (JSONException e) {
e.printStackTrace();
}
}
If you want to shuffle an ArrayList, you can just use the Collections shuffle method.
Collections.shuffle(exerciseList);
Or
SELECT *
FROM excercises
ORDER BY RAND();
If you want it at DB level.
Create a random number with
Random rand = new Random();
int n = rand.nextInt(exerciseList.size());
Then use the random number as an index to get an item from your exerciseList and add it to a new array if it doesnt exist there yet.
To random ArrayList, you can just use the Collections shuffle method.
Collections.shuffle(exerciseList);
Or you can use random function in web service method when you access data from database.

How to post multiple rows (or a LIST object) to PHP using JSON (Android)

I am creating an android application in which I am using SQLite. I have one table in which I have 5 fields. There are many rows in that table and I want to send all those rows using JSON to my PHP code so I can receive the object and insert it in the MySQL database.
What is the best way to do it. I am using LIST object but don't know how I can use POST it using JSON.
Please guide!
i am using this code
mCursor =db.rawQuery("SELECT * FROM customer", null);
while (mCursor.moveToNext()) {
// In one loop, cursor read one undergraduate all details
// Assume, we also need to see all the details of each and every undergraduate
// What we have to do is in each loop, read all the values, pass them to the POJO class
//and create a ArrayList of undergraduates
customer = new Customer();
customer.CustomerName = mCursor.getString(0).toString();
customer.Phone = mCursor.getString(1).toString();
customer.BrandName = mCursor.getString(2).toString();
customer.City = mCursor.getString(3).toString();
customer.FamilyMembers = mCursor.getString(4).toString();
customerList.add(customer);
}
for (int i = 0; i < customerList.size(); i++)
{
JSONObject row = new JSONObject();
row.put("Customer", customerList.get(i));
json.put(row);
}
Don't know how to post it to PHP code.
You have to iterate through your List and fill an JSONArray with JSONObjects for each row. In the JSONObject you can have the key as your column-name and the value with the type you need.
JSONArray json = new JSONArray();
for (int i = 0; i < list.size(); i++) {
JSONObject row = new JSONObject();
row.put("key1", list.get(i).value1);
...
json.put(row);
}
(not tested). Then you can post the json.toString() to the server and retrieve it in PHP with
$jsonstring = file_get_contents('php://input', true);

How to bulk insert from Json to Sqlite in Android [duplicate]

This question already has answers here:
Android SQLite database: slow insertion
(5 answers)
Closed 8 years ago.
How is it possible to insert bulk json data coming from server into Sqlite database in Android very efficiently. The method I use now is very inefficient and it takes almost a minute to complete insertion of about 2000 records. The method I am following is :
for (int i = 0; i < jsonObj.length(); i++)
{
JSONObject itemObj = (JSONObject) jsonObj.get(i);
ContentValues value1 = new ContentValues();
ContentValues value2 = new ContentValues();
value2.put(DbHelper.BusinessID,itemObj.getString("BusinessID"));
value2.put(DbHelper.LocationID,itemObj.getString("LocationID"));
JSONArray list = itemObj.getJSONArray("OfficeDetails");
if (list != null)
{
for (int k = 0; k < list.length(); k++)
{
JSONObject elem = list.getJSONObject(k);
if (elem != null)
{
try
{
value1.put(DbHelper.Office_Code,elem.getInt("Office_Code"));
value1.put(DbHelper.Office_District,elem.getInt("Office_District"));
db.insert(DbHelper.MessageDetail,null, value1);
}
catch (Exception e)
{
e.printStackTrace();
}
}
db.insert(DbHelper.Message,null, value2);
}
The input that is coming is a nested Json array, which itself is nested. Is there a better way to fastly insert huge amount of data in very short time ?
You could try bulkInsert as the following:
ContentResolver.bulkInsert (Uri url, ContentValues[] values); //Array of rows to be inserted
This only fits if you are going to use only 1 URI, if you are going to use multiple uris, you should use applyBatch method in your ContentResolver.
Hope it helps
First create the model class of your json data. Using Gson you can get data inside an arraylist. then you can insert data into sqlite using that arraylist. GreenDao is your best option for fast performance.
when you receive json data in a stream, use following code :
Type collectionType = new TypeToken<ArrayList<your_model>>() {}.getType();
Gson gson = new Gson();
ArrayList<your_model> yourModelList = gson.fromJson(stream, collectionType);
There is an excellent library called JSQL available in Github.
https://github.com/wenchaojiang/JSQL
Its makes it so easy to save Persist JSON string and JSON Objects to your SQLite on Database.
Create a list of your json data and then used this custom query for bulk data insertion:
/**
* insert the bulk data into database
*
* #param query to insert data into table
* #param parameter data to be inserted into table
* #return number of rows got inserted
*/
protected int insertBulk(String query, String[][] parameter) throws SQLiteConstraintException, SQLiteException {
int rowCount = -1;
SQLiteStatement statement = mSqldb.compileStatement(query);
mSqldb.beginTransaction();
try {
for (int index = 0; index < parameter.length; index++) {
statement.bindAllArgsAsStrings(parameter[index]);
statement.execute();
statement.clearBindings();
}
rowCount = parameter.length;
} finally {
mSqldb.setTransactionSuccessful();
mSqldb.endTransaction();
}
return rowCount;
}

Categories

Resources