Save new data to another realm database and replace current

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Save new data to another realm database and replace current



Current situation



In my application I'm saving into default realm database more or less 100Mb of data using the insert method with a JsonReader instantiated from a downloaded json file.


realm database


insert


JsonReader


json file



Now: everything works fine, but saving that amount of data takes some minutes (between 2 and 5) just for the parse-save operation. (I use OKHTTP to download a json file -.txt- and InputStream -> JsonReader -> Gson -> realm.insert for the parsing-inserting operation)


OKHTTP


.txt


InputStream


JsonReader


Gson


realm.insert



Possible improvement idea



Since in my app logics this operation might also be done on a background thread, I was wandering if it was possible to perform an operation like the following:


new realm database



Possible problems with that implementation



I'm fine with the development of this solution, but before performing a refactor operation like that, I have a couple of questions:


database2


background thread


UI


database1


main thread


database2 insert


default configurations


custom configurations



This is what I would like to do for the final replace operation (obv it's just a sample, just take the concept out of this):


Realm oldRealm = Realm.getDefaultInstance();
Realm newRealm = Realm.getInstance(secondConfig);

//assume it's inside a transaction
oldRealm.delete(mytable.class);
oldRealm.insert(newRealm.where(myTable.class).findAll());



About this:



Thanks all and sorry for the long post/bad english



Edit



My download-save code (semplified. I download +- 30 files synchronously and I save them into my database. The biggest one is around 70Mb and it takes really a lot for the write transaction):



I removed not useful code and left only the relevant part. The line taking all the time is the insert into the database.
I also tried not using Gson but I need it since


//i'm inside an AsyncTask here
@Override
protected Void doInBackground(String... params)
Realm realm = null;
try
realm = Realm.getDefaultInstance();

String url = myDownloadFileURL;

//here I download my files with OkHttp
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(600, TimeUnit.SECONDS)
.readTimeout(600, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build();

Request request = new Request.Builder().url(url)
.addHeader("Content-Type", "application/json")
.addHeader("Connection", "close")
.build();
Response response = client.newCall(request).execute();

ResponseBody responseBody = response.body();

if (responseBody == null)
return null;


// I save all my files into the internal storage because otherwise they will make the connection timeout
File extStorageDirectory = Environment.getExternalStorageDirectory();
File myFolder = new File(extStorageDirectory, BuildConfig.FLAVOR);
myFolder.mkdirs();
final File file = new File(myFolder, fileName + ".txt");
FileOutputStream outputStream = new FileOutputStream(file);
InputStream is = responseBody.byteStream();
byte buffer = new byte[4096]; //Buffer size, Usually 1024-4096
int len;
while ((len = is.read(buffer, 0, buffer.length)) > 0)
outputStream.write(buffer, 0, len);

outputStream.flush();
outputStream.close();

responseBody.close();
client.connectionPool().evictAll();

//here I analyze my downloaded data and I save them to realm.
//I put only one case, they are all the same :)
switch (fileName)
case "Cities":
realm.executeTransaction(new Realm.Transaction()
@Override
public void execute(Realm realm)
try
// 0 --> REFER BELOW
catch (Exception error)
//removed not useful code


);
break;

default:
break;

response.close();

catch (IOException error)
//removed not useful code
finally
if (realm != null)
realm.close();


return null;


@Override
protected void onPostExecute(Void v)
//removed not useful code



0 --> REFER BELOW



For that part of code (the slow one) I tried many ways.. those 2 are the best ones for performance and non-error thrown:



1) Using a parsed list


Log.wtf("SYNC", "City - start delete");
realm.delete(City.class);
Log.wtf("SYNC", "City - end delete, start create");
BufferedReader reader = new BufferedReader(new FileReader(file));
realm.insert((List<City>) gson.fromJson(reader, new TypeToken<List<City>>().getType()));
Log.wtf("SYNC", "City - end create");



2) using JsonReader


Log.wtf("SYNC", "City - start delete");
realm.delete(Meter.class);
Log.wtf("SYNC", "City - end delete, start create");
InputStream is = new FileInputStream(file);
JsonReader jReader = new JsonReader(new InputStreamReader(is));
jReader.beginArray();
while (jReader.hasNext())
realm.insert((City) gson.fromJson(jReader, City.class));

jReader.endArray();
jReader.close();
Log.wtf("SYNC", "City - end create");



In both cases the insert operation is pretty long.



The problem might be Gson, but I need to parse my models because I have some Date fields that have to be parsed with a custom typeAdapter.





It'll crash saying "you need to be in a write transaction", because executeTransaction is missing.
– EpicPandaForce
Aug 9 at 15:29



executeTransaction





@EpicPandaForce yeah I know that, it was just a line written to explain what I was thinking :) My goal was to know if the process might work or not and if that might be worth the effort
– Pier Giorgio Misley
Aug 9 at 15:46





I'm actually more curious why it takes 2-5 minutes to build initially. Is it done in a single transaction? What does method profiling say?
– EpicPandaForce
Aug 10 at 8:41





@EpicPandaForce I added the relevant code of my download AsyncTask. It is surely optimizable, but I don't really know how
– Pier Giorgio Misley
Aug 10 at 9:22









By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard