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.
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.
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.
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
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.
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.