Android XML internal storage - java

I am trying to save some data using XML in android to save into the devices internal storage.
I want to be sure the app is written by the open/closed and single responsibility -principle.
(So i could easly switch between methods of storage)
-domain
|---db
|---|---appReader
|---|---|---AppReader.java
|---|---|---XMLAppReader.java
|---|---appWriter
|---|---|---AppWriter.java
|---|---|---XMLAppWriter.java
|---DBFacade.java
|---DBFacadeImpl.java
-MainActivity.java
This is my current structure,...
The problem i am facing now, is that in every tutorial about android and xml they use the function openFileOutput(filename,Context.Mode_Append) I guess this is a function from Activity superclass ?
How would i have to initialise my FileOutputStream and still keep my open/closed and single responsibility principle intact ?
Should i pass an Activity instance to my XMLAppWriter constructor ?
Doesn't this undermine the Single responsibility principle ?

Instead of pass activity instance as parameter, you can use application's context method, which doesn't violate single responsibility principle.
getApplicationContext().openFileOutput(name, mode);

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");

Is this a good reason to use a Singleton?

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.

Where I should store SQLite database reference?

I'm creating simple application that uses JSON format and SQLite database to store parsed information into that. I'm aiming to support both normal devices and tablets, so I'm using Android Fragment API.
My problem is that I'm not sure where I should store the reference to my database, at this moment I have main activity that incorporates two fragments - list fragment and details fragment (both of them are adjusted for tablets and normal phones).
I need to fill mentioned list with information from database and in future I want to implement additional search function so reference to database must be shared by almost all fragments/activities.
In addition I have special class(Util) that stores HTTP object and JSON parser. Is it good idea to add static database reference to that class and create new instance of it in seperate thread (initialization block) ? Or I should consider create it in MainActivitity and create getter and setter ? My MainActivity implements appropriate interfaces from list fragment so I'd need to cast it.

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