I have a class, Savable that serialize the entire class. It was quick easy and great. Unfortunately, this is a problem if I want to update my app. If I make any changes to Saveable, or its descendants, when an instance is deserialized from an older version, there are virtual, and or abstract errors and other errors thrown.
Reading the Android saving data page here, developers are supposed to use one of the ways listed. As I am building an alarm app, I have opted for the SQLLite option.
The problem, until now, my app has been created with my Saveable class in mind. Switching to a database will require a full reworking of my Alarm class because Alarm has other descendants of Saveable in it. Therefore, to save each alarm, I will need a database for every sub-class of Saveable.
Currently, I have a method, Saveable.save(Context context) that serializes the object to fill. This will require a rewrite because now instead of serializing the entire Alarm class, I need to save the core Alarm stuff the Alarm.db, the subclasses of Saveable into subclass.db.
This presents another issue now with loading. I have a method, Saveable.LOAD(File path), which deserializes a Saveable object, that can be cast to it's original class. Now, since the Alarm class contains other Saveable objects that need to be saved in separate DBs, the Alarm class will need a reference to the each sub-saveable class in alarm.
Needless to say, this becomes explosively messy, quickly. I am not opposed to the work (programming is amazing), but before I short change myself again, is this the way you would solve this problem?
I'm a newer programmer, but can't you get a serialization code for updating that allows an object/class to used with an updated version by going into the command line and putting say: serialver class name and it spits out the static final longserialVersionUID. Then make a static final long serialVersionUID = (insert random long number the command line gives here) in the class you want to serialize and then use with an updated version of the program. You probably already know this, and may not be the answer you are looking for, but me being new its the only way I have heard of serializing a class, updating the source code, then deserializing a class and using it with the updated code.
Related
I'm making an Android app that will have the timetables of a local bus.
There are more than one timetable, the one that will be use depends on the day.
If it's a holiday I must use a special timetable, so I want to know when is a holiday and when is not.
The thing is that I'm creating a class that will handle this, it will try to retrieve information from memory or from a web api. Then some other classes will be able to communicate with this class, but it doesn't seem necessary to me to have more than one instance of this class, I could create just one instance and share it with the rest of the classes.
Could this class be a Singleton or it would be better if I create a normal class ?
In your case (retrieving info from memory), definitely avoid using a singleton class because it will highly likely be tied to your Activity context.
Your class will have a static reference to a class, therefore
it will be kept in memory when not needed.
singleton may be reinstantiated, or may use obsolete instance, with new instations of activities. You will lose control of the current variables.
diffent instances of the same activity class are highly likely to conflict with this class.
Examples of the same activity class several instantiation:
Change device orientation.
Running app from the webbrowser's, Google Play, file browser intent.
Besides, at some point, when you add functionality based on user reviews, your app will grow, you are likely want to refactor your class, break it into subclasses, put some of its methods into separate threads. It will no longer be easy to do.
It might seem fun while the app is small, and untested, but later, in Android specifically, you will run into a nightmite with unpredictable and hard to detect errors.
Because of Android's special way to recreate activity class, through onCreate, onResume etc. you will run into a nightmare, when the app will start living its own life.
You will no longer be able to rely on the assumption that the current singleton instantiation actually belongs to your current activity.
You may swap between orientations or run your app from different entry points (launcher, recent apps, google play), and it may reuse the variables actually prepared for a different activity instantiation.
If you need only one instance of the class, just create one instance of the class in the onCreate method - and that will make the app much more manageable.
One of the main advantages a Singleton class brings you is the fact that you are sure to have one and only one instance of an object doing some thing, and that it is instantiated only once (preferably at a specific point of your application, for instance at startup or only after certain other operations have been performed)
An example could be for instance a cache implementation: you want to make sure that all classes that need a certain cache read and write from the same object, that maybe is created and filled with information at startup time.
Your does not seem to be the case, unless you fetch the information you need when your application starts and then you keep them memorized for some reason: in this case you want to make sure your information is fetched one and only one time, to avoid wasting memory and elaboration time. Also, a Singleton is fine if you need to do some kind of operation when your class is instantiated, like opening a connection that then stays open.
On the other hand, if you just need a class with some method to call some external apis or database and you don't need to memorize any information in it, there is no reason to initialize a singleton.
If this is your case, why don't you try some static class/methods? They can be called like normal methods directly on the class with no need to instantiate objects or keeping a state, saving memory and avoiding side effects.
I have defined a class which acts like a model/pojo. The class has many keys/variable. I have implemented custom solution for storing the POJO on disk for future uses. Now what I want to do is that whenever any value in the class/POJO is changed, I should call a method which sync the fresh changes with file on disk.
I know I can define setter for each variable. But it's quite tedious to do for 100s of direct and sub fields, and even if I define setter for each field, I have to call sync function from all the setters.
What I need is single proxy setter or interceptor for all change pushes to variables in class.
I am using this in an android application, so whenever the user enters new details in his/her account I have to store those details at that specific instance of time for preventing the data loss. I am using GSON for serialising and de-serialising.
Sorry for using vague terminologies, never been to college :|.
The easiest solution is indeed to use a setter. You only have to create one for each field you want to monitor, and most IDEs generate them for you or you can use something like Koloboke, so it being tedious isn't really an argument.
A proxy class or reflection would also be possible, but that is pretty hacky. Another way would be an asynchronous watcher/worker that checks for changes in you POJO instances, but even that seems unnecessarily complicated.
Apart from that you might need to rethink your POJOs structure if it has that many fields.
The problem with persisting(in your case writting to a disk) entity on each property update is that most of the updates are modifying more then one property. So in case you have a code like this:
entity.setA(avalue);
entity.setb(bvalue);
entity.setc(cvalue);
You would write it to the disk 3 times, which is probably not a best way, as it takes more resources, and 2 out of 3 writes are unnecessary.
There are several ways to deal with it. Imagine you have some service for saving this data to a disk, lets name it entityRepository. So one option is manually call this entityRepository each time you want to save/update your entity. It seems to be very uncomfortable, comparing to calling this automatically on setter call, however, this approach clearly shows you when and why your entity is persisted/updated, in your approach it's unclear, and can lead to some problems future problems and mistakes, for example, in future you will decide that you now need to update one of the properties without immideately persisting, then it appears that you will need 2 setter, one with update, and one without...
Another way is to add version property, and when its setter is called inside this setter call entityRepository.save(this).
The other way is to look at AOP, however anyway I don't recommend persist entity on any change, without having control over it.
You are talking about data binding. There is no built-in way for that so you have indeed to sync it yourself. Look into How to Write a Property Change Listener. There are also lots of other approaches to this, but as said no built-in way.
I know with javax.tools.* it is possible, but since this is not included in the Android API, I'm desperately wondering, is this possible?
Right now, my goal is to create a drag-and-drop tool to allow users to create their own layouts (as not everyone wants to learn Mobile Development, as it requires a lot of time, dedication and practice) similar to how Android Studio does it's own. However, of course the most important thing is to implement functionality via onClickListener and onTouchListeners. I've begun remedying this by creating my own DSL (Domain-Specific-Language) with a GUI front-end allowing users to choose what they want via PopupMenu and SubMenus. For example...
Statements
{ if, for, while }
Statements must be followed immediately by a reference and then a conditional (obtained from that reference), like a "if(Object.conditional())" statement.
References
{ Object1, Object2, Object3 }
The objects are references to other Views (I.E, Buttons, Layouts, WebView, etc.).
Conditionals|Actions|Getters|Setters
{ isSomething(), doSomething(), getSomething(), setSomething() }
Each Reference's methods, wrapped so that each wrapper keeps track of it's method's attributes and description (hence documentation).
It would go something like such...
IF ImageView1.isVisible()
ImageView1.setVisible(false)
ELSE
ImageView1.setVisible(true)
Of course, the method setVisible(boolean) is a wrapped version of setVisiblity(int).None of this is typed, it is obtained from a simple PopupMenu which shows them the applicable selections based on current context.
How I plan on transcribing this to compiling code was to convert the statement into Java code, inserting references on the fly as they are needed (I.E, ImageView1 would be defined in java as private ImageView ImageView1;), generate methods somewhat similar to how ButterKnife generates it's extra classes for it's onClick and onTouch annotations, etc.
Then, after planning all of this (been working on it for 2 weeks now), I find out that Android does not have support for compiling code like this. Please tell me something like this is possible. It's something I 100% wanted to do. Is this possible with any third party libraries?
If not, is there some possible way to mimic doing so? I could do it the long and slow way, of preparing every such possible way, keeping track of the references myself through a map, and when it is about to be called, directly call the implemented method for the View associated with that key, which theoretically COULD work. In fact, that'd be my second go-to if I can't. It'd be messy though.
Sorry if this is too long, I just want to get this to work.
TL;DR: Is there a way to compile a generated Java file created at Runtime in Android (since javax.tools.* does not exist), and if not what would be the best way to do so?
I'm starting with Android and wonder if background Task like DB reading and saving are always encapsulated in private classes?
I mean, at the moment I have:
private class SaveToDB extends AsyncTask..
private class ReadFromDB extends AsyncTask..
public void onButtonClick(View v) {
new SaveToDB().execute();
}
And so on. This way, I always have to create a new object if I want to execute background tasks. Is that the correct way?
What I wonder is that all my private classes are "actions" itself, not really objects. As they are named eg save or read which naming normally applies to methods by convention, not to classes.
Moreover, in case I'm doing it right: is it good practice to neast the private classes inside MyApplication Activity? Or should I refacter them out into own separate classes?
You could write a service to handle all the background content management. So, when you want to save, you just message the service and tell it to write data. This is much more complicated. For simple things, you can do it exactly as you are currently.
EDIT:
Also, as Ian pointed out, take a look at the new database interfacing classes post 3.0.
If you are firing of async tasks to interact with a sqlite database, then its not the best way to do things these days, you should check out cursor loaders instead.
http://developer.android.com/guide/topics/fundamentals/loaders.html
http://developer.android.com/reference/android/content/CursorLoader.html
Once you got your head around them they are much easier than firing off async tasks, infact they build on top of async tasks to address some of the issues you describe and are tolerant to configuration changes.
I highly recommend to move away from AsyncTask (for db access) and use the Loader API instead.
Its backported in the compatibility package so you can use them in older versions prior to Honeycomb.
Not always.
For example, if you've got a task that is to be used by different activities (I'm not talking about sharing the same instance), you will want a public class so you don't write it several times.
If you only use that (class of) task in one place, private class might help keeping your code cleaner.
It is a correct way for using AsyncTask, which isntance you can execute once.
Class Name can be DbSaver isntead of SaveToDb for instance which is more readable.
If that class is used only one Activity you can nest them, why not. But if you have task which is executed within different Activities, it is a good idea to create his own file.
It is good design to loosely couple your database access from your UI code. One way to avoid having to create a new object every time would be to make the database access classes a singleton and just return the instance of the class whenever you need to make a transaction.
To your last question it is a better idea to move the database management to its own class so that it can be accessed across several activities. If you do it all in a private class then what happens when you have a new activity that need s database access?
I am currently working on a videogame, and i want to have the user be able to save their character to a new file. I know how to use the file io (for the most part), but i have been using the 'serialize' to serialize a whole object (that contains all the variables for the character) and save it to a file. The problem is that i am constantly updating the object and making changes to it, so when i try to load the old character with the new object, it errors and crashes. Same with levels as-well (an object holding a few 2d-array of variables).
There must be a better way to do this so it is compatible with future versions. If there is a way, would anybody please offer some source code and/or a link to a nice tutorial? All help is appreciated, thanks!!!
Use XML or an embedded database (fast and lightweight) such as Derby or H2. You could even use a plain old properties file.
In fact, see if the properties file will work for you. And only if that won't work, try XML or the embedded database approach.
if you are looking for java serializers here is the benchmark for you https://github.com/eishay/jvm-serializers/wiki/
Apache Avro seems to perform well.
Another way is to store the values in the persistent store like HSQLDB or H2 db and load it to memory at startup and persist when needed.You can also use SQLite (for driver check this)
You can implement Externalizable instead of Serializable, and in the readExternal() and writeExternal() methods you can put the logic to read/write the object. This way you have full control of serialization/deserialization and can make changes fairly easily. Alternatively you can use JSON serialization by using Gson. I would not recommend XML, but if you want to you can check out xstream for the same thing.
If you are extending your objects in backwards compatible ways, i.e. add fields, and not removing fields. Make sure that you have declared a serialVersionUID as per the serializable javadoc.
http://download.oracle.com/javase/1.5.0/docs/api/java/io/Serializable.html
One additional option to consider since you're already using serialization, you could implement Externalizable instead of Serializable. The code you use to serialize objects would remain the same. However in your class you would specify exactly how you want it serialized by overriding readExternal() and writeExternal(). E.g.:
public class MyClass implements Externalizable {
private int foo;
private String bar;
public readExternal(ObjectInput in) {
foo = in.readInt();
bar = in.readUTF();
}
public writeExternal(ObjectOutput out) {
out.writeInt(foo);
out.writeUTF(bar);
}
}
Just be sure to keep the order the same when reading and writing. Try to only add fields, however if you need to remove a field leave a gap to account for old versions.
Ultimately though if you're making a lot of changes it might best to switch to a properties or XML file as LES2 suggested. It'll be more portable and readable that way.
This game uses java.util.prefs.Preferences for cross-platform convenience. Because keys are stored individually, new additions rarely interfere with existing entries.