Android: How to save an instance of parcelable object? - java

I am trying to save an instance of StatusBarNotification, so that i could show the notification later to the user. I noticed that StatusBarNotifcation is not Serializable but Parcelable. Is there any way to store the exact instance state in the database so that even if user turns of his phone, the instance object is stored.
I know its not the best practice to store the Parcelable object in database. But I need to do it.
If there is any way i could get the byte array of the instance, I am open for suggetions.
EDIT
I found out today that, if I turn off my android phone with some un-attended notification, when I restart my phone I am still able to see the same notifications. That being said, android is somehow saving the same instance of notification.
Now my question is, how?? And if android does why can't us.

Is there any way to store the exact instance state in the database so that even if user turns of his phone, the instance object is stored.
No. In particular, not only do you have no way of persisting the PendingIntents associated with the Notification, but you have no way of recreating them with all the security rules intact. A PendingIntent is tied closely to the app that creates it; you are not the app that created those PendingIntents originally.

I think you cannot save the parcelable object of notification in the database (also not a good practice).

Related

Storing shared values in SQLite database vs passing through intents

My app initially makes a request for a list of objects from a server. These objects are currently kept in memory as an ArrayList<MyObject>. However, I want these objects to be passed through multiple activities before the user terminates the flow by pressing a button. I could make the ArrayList serializable and pass it through Intent extras. But I could also store MyObject(s) in a SQLite database and access/modify them in any Activity without having to go though intents. I was wondering what the norm is to accomplish this.
EDIT: forgot to mention that all the values would be deleted once the user terminates the flow.
SQLite is not the best way to go in your case since you don't need the data to be persistent after you close the app. It will just slow your app having to store and retrieve all entries on every activity transition. You can do one of the following instead:
Pass Serializable the way you described. Might be slower than the other alternatives though
Make MyObject implement Parcelable and use [intent.putParcelableArrayListExtra()](https://developer.android.com/reference/android/content/Intent.html#putParcelableArrayListExtra(java.lang.String, java.util.ArrayList))
Extend Application and load the list from the network in your Application.onCreate() and call getList() from activities that need it. That way you load it once and you don't need to pass it between different activities.

Storing Application context in SharedPreferences when app crashes

Currently im storing all of my users information and there friends information inside a class i have created called userInfoCore that extends Application so i can store the values in the Context. When my app crashes it gets rid of al those values and my users are forced to relogin, so i would like to store them in SharedPreferences to be grabbed again in the onCreate of my MainActivity.
I know how to store them, thats not the issue. The issue is i dont want to overcrowd my code with repetitive code and put the storing methods in all the onDestroy's of all my Activities, and i cant #Override onDestroy in my userInfoCore class because its not an Activity i imagine?
Some insite would be great. Thank!
EDIT:
Ive found out that this line in the android manifest is causing my Application Context data to be destroyed even when the user presses the home screen. android:launchMode="singleInstance"
My thoughts are YES i could store them in the onPause or do what #CommonsWare suggested. However like i said, i dont want to have to do all of that. If i can find the root of the cause of the issue... which i have. (The singleInstance in manifest) then i would be much happier.
Some insite would be great.
Update your persistent store when the data changes. A custom Application subclass, like any singleton, should only be treated as a cache or other transient spot for data. If you care about the values, persist them, at the point when the data is changed.
This is a good argument for using the Model-View-Presenter (or Model-View-Controller) pattern. By separating your Model (domain data and procedures) from your View and Presenter (Layout and Activity respectively) you only have to write the Store logic once.
Then you have two choices: either do as #CommonsWare suggests, have the model write itself whenever it changes, or add a simple call in each Application's onPause (onDestroy is too late! It may never get called.) to the model to tell it to save itself.
Note: the model can accept a context as a construction parameter for use in finding a shared preferences, or it can create it's own named preferences using the PreferenceManager

Get an object "FragmentManager" in "Service"

Is it possible to get an object "FragmentManager" in "Service"? Is it possible to pass an object "FragmentManager" from "Activity" in the "Service".
PS: Includes not officially supported features.
Is it possible to get an object "FragmentManager" in "Service"?
No, sorry.
Is it possible to pass an object "FragmentManager" from "Activity" in the "Service".
That would be an exceptionally bad idea.
If you wish for your service to update your UI, bear in mind that there might not be a UI. The user is welcome to press their BACK or HOME button to exit your UI, even while your service is running.
Also bear in mind that it might be a different UI. For example, when the user rotates the device from portrait to landscape, your activity (and fragments, by default) will be destroyed and recreated. Or, the user may tap on something that brings a different activity to the foreground, and that activity has its own fragments and manager.
Therefore, to have your service update your UI, you need to use a communications path that supports this sort of decoupled operation, such as:
send a broadcast
send a broadcast using LocalBroadcastManager
update content via a ContentProvider, with activities using CursorLoader or ContentObserver to be notified about data changes
etc.

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