the right place to deserialize on Android - java

I'm developing an Android app which stores a TreeSet object using serialization in a file. I need to serialize the object on close of my app and deserialize on launch because I need an access during a complete runtime. Unfortunately it's quite unpredictable on which activity the user will start/end so it's unclrear to me where are the right places to put this serialization and deserialization calls so that the object is available during the complete runtime.
thanks in advance for any ideas

Well, depending on how performance dependant your app is and how complex your serialization process is I'd read on startup in your main activities onCreate() and write everytime a value is being set. Simple and unefficient, but safe.

Related

Parcelable and serializable in kotlin [duplicate]

Can anybody please tell why we need to serializable object for passing one activity to another activity in android? Android is following Java syntax. In java we can pass object to another class without serializable.
Thanks
In ordinary java programs passing parameters(Object type), is kind of create a new handler to the object and giving to another method (In regular words passing the reference by value).
But when it comes in android, passing object references from activity to activity, where their states have to be persisted, is a serious headache.
One way you can do is create a static object in the first activity and access from the second, though this seems to be a easiest way, there is no guarantee that the system maintains the activity in the memory. Therefore the second activity may loose the object reference.
Other way, and the mostly recommended way is serializing(Kind of flatten the object) the object and pass with the intent as extra. In android there are two ways to serialize.
Implement the java's serializable interface
Implement the android's parcelable interface
However, on the android, there is a serious performance hit that comes with using serializable, the solution is using parcelable.
You can find a pretty good tutorial and explanation on android parcelable implementation here.
We need to understand following concepts before getting to the answer:
Android uses Binder for inter-process process. It is required even for simple app because the OS and the apps run in different processes.
Marshalling:
A procedure for converting higher level application data structures into parcels for purpose of embedding into Binder transaction
Unmarshalling
A procedure for reconstructing higher-level application data-structures from parcels received though binder transactions.
You can consider Intents as higher level abstraction of Binder
Based on the documentation following is the way how intent communication occurs:
Activity A creates an Intent with an action description and passes
it to startActivity().
The Android System searches all apps for an intent filter that
matches the intent. When a match is found,
the system starts the matching activity (Activity B) by invoking
its onCreate() method and passing it the Intent.
Why Parcelable or Serializable
IPC (Inter Process Communication) requires data in Intent to be Marshalled and unMarshalled. Binder provides built-in support for marshalling many common data-types. However when we define custom object, it would impact this process and the final object received might be corrupted during the process.
When you define custom object, you need to be responsible for providing this marshalling and unmarshalling which is achieved through Parcelable and Serializable (Since comparison between these two would be another topic I won't discuss much here). Both of these provide mechanisms to perform marshalling and unmarshalling. This is the reason why you need to use Parcelable or Serializable.
Using Parcelable you write the custom code for marshalling and unmarshalling the object thereby you gain complete control over the process.
Serializable is a marker interface, which implies the user cannot marshall the data according to their requirements and its done on JVM, which doesn't give any control at your side.
Disclaimer: Description above is my understanding for the rationale behind the need for serialization based on some
documentation
There are basically two questions in your question, so let's decouple it.
Why marshall in a Parcelable instead of passing an object reference directly?
It's obvious faster and more memory efficient to reference objects rather than marshall/unmarshall them. So you shouldn't use Parcelable when you can pass the object directly.
However, there are situations where you may not have access to the object reference.
in Intent because the process that handles the Intent may not be the process that emitted the Intent (it's an inter-process communication)
in Activity lifecycle, for instance in onRestoreState(), because the whole app may have been killed by memkiller when the user wants to resume it.
everywhere else where Android frameworks requires
In IPC, why use Parcelable rather than Serializable like Java does?
That's only a performance optimization.
If We want to pass object from Activity to to Another Activity . We need to save the passing state.
//to pass :
intent.putExtra("MyClass", obj);
// to retrieve object in second Activity
getIntent().getSerializableExtra("MyClass");

Android saving dilemma' was using serialization, which is wrong

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.

sending a stream of data from the main activity to a thread in a different class

Currently I have an app which has code in its main activity that reads data from an xbee. My problem is that I want to relay this data to 4 different threads in 4 different classes throughout my project. I looked into bundling it, but that seems like a one time data transfer, not a stream of it.
One idea I had was to write the data to a string called messages and then have a getMessages() function, but I ran into a problem calling a static method from a non-static class or vise versa.
Have you considered using SharedPreferences or extending Application? SharedPreferences will let you store basic types (String, int, boolean, etc) in persistent storage. Application can be extending to store variables / methods that can be accessed anywhere in your program. For example, MyApplication app = (MyApplication)getApplicationContext();
Are you looking to modify this stream of data in each of your threads, or simply read a value and modify data separately? You may want to setup some boolean flags to ensure you aren't accessing / modifying data that isn't safe to perform those operations on. Hope that helps! Let me know if I can provide a code example for clarity.
one way of doing it to simply make your main activity write into android.database.sqlite and others will simply read from it
since not sure how your code layout is I just refer you the documetation page :
http://developer.android.com/reference/android/database/sqlite/package-summary.html
You can create one handler for each of your threads and then post messages on all the handlers. Below is the link which creates an Handler and post messages from the handler reference:-
using a Looper in a Service is the same as using a separate thread?
You can implement observer pattern to solve this.Make the four classes as observers and the activity as subject.
Expose a api like onDataChanged(byte[] data) which will be called whenever your activity has some new data.
To learn more about observe pattern refer-https://en.wikipedia.org/wiki/Observer_pattern
You can also have a look at classic producer consumer problem if you want synchronization https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem

How to get a reference to the stock launcher activity object?

I want to read out the shortcuts' and widgets' position and name on the screens of the launcher. Since every launcher is different, I will focus on the stock launcher of Android for the moment. I have not found an API to do this, so I am trying my luck with Java's Reflection API. So far I have been able to get the class and read out the type of the variable holding the items on the desktop called mDesktopItems: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/2.2.2_r1/com/android/launcher2/Launcher.java#201 But to read out the variable's content, I need a reference to the launcher activity object. It's obvious that this object does not have to exist, but I can probably check regularly and once it does, I would fetch the data.
So how do I get a reference to the launcher activity object? Or could you think of a better way of fetching the required data?
I don't think this is going to work via reflection. The launcher is a separate app from yours, running in a different process under a different user in its own VM. You're not going to be able to get a reference to the launcher activity object. This is by design. Think of the security implications if any app could read the contents of any other app's variables.

How do a share a large object within an activity in Android?

I have a Network Client class that is receiving a large binary block and parsing it into a usable Java object. The Network Client is on a separate thread from the app's View. What is the best way to make this object available to the View? I've come up with the following solutions, but I feel like none of them are the correct one:
Create the object in the Network Client and let the View access it directly
I would send a small message in a Handler telling the View that the data has been updated
Con: requires that I synchronize the object between the threads to ensure that the Network Client doesn't replace the object while the View is accessing it
Serialize (Parcel?) the object in the Network Client and send it through a Handler to the View
Pro: there are no questions of ownership of the data
Con: would probably be a huge performance drain on the app
Create a reference to the object and pass that to the View
I come from a C++ background, and I'm not sure if this is even possible in Java. I C++, I could just send the View a pointer to the object and let it take care of it. That seems like something Java wouldn't let me do. Is this feasible?
Are any of these solutions advisable, or should I approach the problem in a completely different way?
If you don't want to keep downloading when the activity is in the background, then use non-blocking IO, not threads.
If you do want to keep downloading when the activity is in the background, you probably want to use a service. You can make the object Parcelable or so; I think the underlying service implementation passes pointers around if your activity and service are within the same process (I think they are by default, but ICBW).
If the object is really big and you don't feel comfortable returning it with a get method, maybe you could put its contents into an SQLite database and optionally expose it as a ContentProvider. You could also send an Intent and either cause the View to then go and grab the payload or attach it to the Intent.
Look at the application class subclassing this class and referencing this within your manifest will enable you to store the reference to the service/download controller at a central position that will be available in every activity of your app. This enables you to keep the data in memory and reduce the need of recreating the big object if you need it in more places then just one activity.
For the download you can use a local service that communicates with your activity through a binder object. Keep in mind that a service is not a thread. If you want have the download running in the background you need to create a thread in the oncreate method of your service.
Also keep in mind that it is good practice to have an annotation show the user that a service is doing something and let him access the service and cancel it or view it status.

Categories

Resources