Saving real time data in Android application to access later - java

I am currently streaming information in the form of a String from an Arduino to an Android application via Bluetooth. My application currently just displays the data on a series of progress bars as the values come in. I would like to store the data as it comes in to be viewed later but am unsure as to how to achieve this.
I have a BluetoothActionListener which runs when new data is available. This is called up to 20 times per second so I am worried as to whether adding a memory save to a file within this function will have an effect on its performance.
The data arrives as a string via bluetooth and I would like to be able to store the entire session's worth of data (upto 10mins) in the same file on a different line. A simple text file with a timestamp on each line is sufficient.
Would using a internal/external memory write cause my foreground visuals to slow down or even become unresponsive, as each new string arriving causes each of the progress bars to update?

At twenty times a second? Probably not. Just keep the file open rather than closing it, and flush it every few writes.

Related

How to speed up excel reading/writing

I am using Apache POI to read/write to an excel file for my company as an intern here. My program goes through the excel file which is a big square with top rows computer names and left column user names. 240 computers and 342 users. the sheet[computer][user] is 0 in all spaces and the program calls PSLoggedon for each computer and takes the username(s) currently logged on and increments their 0 so after running it after a month, it shows who is logged in the most to each computer. So far it runs in about 25 minutes since I used a socket to check socket.connect before actually calling PSLoggedon.
Without reading or writing at all to the excel file, just calling all the PSLoggedon calls to each computer, takes about 9 minutes. So, the reading and writing apparently takes 10-15 minutes. The thing is, I am calling PSLoggedon on the computer, then opening the excel to find the [x][y] spot of the [computer][user] and then writing to it a +=1 then closing it. So the reason it is taking this long I suppose is because it opens and closes the file so much? I could be completely wrong. But I can't think of a way to make this faster by opening and reading/writing all at once and only opening and closing the file once. Any ideas?
Normally Apache-POI is very fast, if you are running into some issue then you might need to check below points:
POI's logging might be on, you need to turn them off:
You can add one of these –D to your JVM settings to do this:
-Dorg.apache.poi.util.POILogger=org.apache.poi.util.NullLogger
You may be setting your VM heap to low value, try to increase.
Prefer XLS over XLSX.
Get HSQLDB (or another in-process database, but this is what I've used in the past). Add it to your build.
You can now create either a file-based or in-memory database (I would use file-based, as it lets you persist state between runs) simply by using JDBC. Create a table with the columns User, Computer, Count
In your reading thread(s), INSERT or UPDATE your table whenever you find a user with PSLoggedon
Once your data collection is complete, you can SELECT Computer, User, Count from Data ORDER BY Computer, User (or switch the order depending on your excel file layout), loop through the ResultSet and write the results directly.
This is an old question, but from what I see:
Since you are sampling and using Excel, is it safe to assume that consistency and atomicity isn't critical? You're just estimating fractional usage and don't care if a user logged in and logged out between observations.
Is the Excel file stored over a slow network link? Opening and closing a file 240 times could bring significant overhead. How about the following:
You need to open the Excel file once to get the list of computers. At that time, just snapshot the entire contents of the matrix into a Map<ComputerName, Map<UserName, Count>>. Also get a List<ComputerName> and List<UserName> to remember the row/column headings. The entire spreadsheet has less than 90,000 integers --- no need to bring in heavy database machinery.
9 minutes for 240 computers, single-threaded, is roughly 2.25 seconds per computer. Is that the expected throughput of PSLoggedOn? Can you create a thread pool and query all 240 computers at once or in a small number of rounds?
Then, parse the results, increment your map and dump it back to the Excel file. Is there a possibility that you might see new users that were not previously in the Excel? Those will need to be added to the Map and List<UserName>.

How to make Bukkit not save chunks automatically at any time

Bukkit saves automatically every few minutes, and also saves when it shuts down.
I need a way to not save the chunks, because I'm in need of a system to make my minigame map to be completely fresh when the server restarts, for another round of the minimap.
What I tried to do:
Setting the save-automatically off in the server.properties;
Running the following to try to shutdown without saving:
Bukkit.getServer().unloadWorld(getServer().getWorlds().get(0), false);
Bukkit.shutdown();
What you have tried is the correct way to do this.
The problem is that you cannot unload default worlds (which are the Overworld, the Nether and the End).
You have to create a new one.
You need a WorldCreator object.
WorldCreator seed = new WorldCreator("arena");
World arena = seed.createWorld();
This is a custom world: regions are saved (if not set otherwise) but Bukkit will not know about it after the server restarts.
So you must run the code above the first time to generate the files, then to load them from disk if found.

How do I save chronometer elapsed time in android app

I'm developing a sort of parking meter counter app for a few specific locations. The app asks the user where he is (dropdown menu, saves column letter and number, like A6) and then shows a screen with the given location, a timer (chronometer class) counting up from 0 and the price that has to be paid on exit (calculated using elapsed hours * base price).
This all works nicely, until the user or the OS kills the app (task manager or memory management). Then, the next time the user opens the app, he's back at the main menu and his location, time and price has been lost.
I need a way to save all of the user's information and be able to load it up on app restart.
Initially I had thought to save the user's location and the exact time the chronometer started (DateTime.Now() maybe?) to a .txt file in the internal storage so that it would read:
mallname,columnLetter,columnNumber,startTime
This way, if the app is killed, or any time the app is started up from scratch, the MainActivity will first check if a file.txt exists in the app's internal storage, if it does, it immediately starts the lastPage activity, reading the .txt file to pass the values as parameters (thus, the comma separation). If there's no such file, it would just carry on normally. The last page does contain a reset button that would delete the file so that the app can start up normally the next time it's used.
I don't know how efficient this method is, but it's the first thing that came to mind. However, I don't know how to go about this. I have this same exact method programmed in C# for Windows Phone, but I don't know how to translate it into Java for Android. Also, in C# I didn't actually use a chronometer, rather, I had the startTime saved and used a timer that would calculate startTime - DateTime.now() on every tick (every second) and update the textBlock to show this.
Any help would be greatly appreciated.
Usually user data should be saved to a SQLite database, however in your case, since you're talking about a few variables, it'd be much easier for you to save these values in the application's SharedPreferences.
For every value you'd like to save, add this line to your Chronometer's onChronometerTick() method:
PreferenceManager.getDefaultSharedPreferences(this).edit().putInt("your_key", <Your_value>).commit();
This can later (whenever your application recovers from a crash, for example) be retrieved by:
PreferenceManager.getDefaultSharedPreferences(this).getInt("your_key", <Default_value>);
Regarding performance issues, if your Chronometer ticks once every second this should have no effect on your app's performances and is completely acceptable.

measuring statistics in java simulation

I have a group of nodes who send measurements to a bootstrap server. In the end I want the bootstrap server to sum all the measurements and write it to a file. One way to do that is to over-write the data to the file each time a measurement message is received(after summing up the current measurements). But this would be very inefficient. I want to store the measurement data and write it to file only once after the simulation is completed.
But the problem is that the simulator code that I am using is not under my control, its a library that I am using. So, I cant tell when exactly the simulation is going to end (and hence I cant tell which measurement message will be the last one).
I naively tried to store the measurement data in a static class but this data is not accessible when the simulation terminates. Is there any other way that I can do this ?
Thanks,
I would find the last message using a timeout.
Write to disk if you have new data but you haven't got anything for a while e.g. a second.
If you cannot store the data you need in the process (which it seems you can't, since the static class failed), you need to persist the data some other way. To an on-disk file is one option, and another common one would be to a database.

Designing a process

I challenge you :)
I have a process that someone already implemented. I will try to describe the requirements, and I was hoping I could get some input to the "best way" to do this.
It's for a financial institution.
I have a routing framework that will allow me to recieve files and send requests to other systems. I have a database I can use as I wish but it is only me and my software that has access to this database.
The facts
Via the routing framework I recieve a file.
Each line in this file follows a fixed length format with the identification of a person and an amount (+ lots of other stuff).
This file is 99% of the time im below 100MB ( around 800bytes per line, ie 2,2mb = 2600lines)
Once a year we have 1-3 gb of data instead.
Running on an "appserver"
I can fork subprocesses as I like. (within reason)
I can not ensure consistency when running for more than two days. subprocesses may die, connection to db/framework might be lost, files might move
I can NOT send reliable messages via the framework. The call is synchronus, so I must wait for the answer.
It's possible/likely that sending these getPerson request will crash my "process" when sending LOTS.
We're using java.
Requirements
I must return a file with all the data + I must add some more info for somelines. (about 25-50% of the lines : 25.000 at least)
This info I can only get by doing a getPerson request via the framework to another system. One per person. Takes between 200 and 400msec.
It must be able to complete within two days
Nice to have
Checkpointing. If im going to run for a long time I sure would like to be able to restart the process without starting from the top.
...
How would you design this?
I will later add the current "hack" and my brief idea
========== Current solution ================
It's running on BEA/Oracle Weblogic Integration, not by choice but by definition
When the file is received each line is read into a database with
id, line, status,batchfilename and status 'Needs processing'
When all lines is in the database the rows are seperated by mod 4 and a process is started per each quarter of the rows and each line that needs it is enriched by the getPerson call and status is set to 'Processed'. (38.0000 in the current batch).
When all 4 quaters of the rows has been Processed a writer process startes by select 100 rows from that database, writing them to file and updating their status to 'Written'.
When all is done the new file is handed back to the routing framework, and a "im done" email is sent to the operations crew.
The 4 processing processes can/will fail so its possible to restart them with a http get to a servlet on WLI.
Simplify as much as possible.
The batches (trying to process them as units, and their various sizes) appear to be discardable in terms of the simplest process. It sounds like the rows are atomic, not the batches.
Feed all the lines as separate atomic transactions through an asynchronous FIFO message queue, with a good mechanism for detecting (and appropriately logging and routing failures). Then you can deal with the problems strictly on an exception basis. (A queue table in your database can probably work.)
Maintain batch identity only with a column in the message record, and summarize batches by that means however you need, whenever you need.
When you receive the file, parse it and put the information in the database.
Make one table with a record per line that will need a getPerson request.
Have one or more threads get records from this table, perform the request and put the completed record back in the table.
Once all records are processed, generate the complete file and return it.
if the processing of the file takes 2 days, then I would start by implementing some sort of resume feature. Split the large file into smaller ones and process them one by one. If for some reason the whole processing should be interrupted, then you will not have to start all over again.
By splitting the larger file into smaller files then you could also use more servers to process the files.
You could also use some mass loader(Oracles SQL Loader for example) to take the large amount of data form the file into the table, again adding a column to mark if the line has been processed, so you can pick up where you left off if the process should crash.
The return value could be many small files which at the end would be combined into large single file. If the database approach is chosen you could also save the results in a table which could then be extracted to a csv file.

Categories