Is RoboGuice wiki obsolete ? setBaseApplicationInjector does not exist? - java

I am trying to use the last version to date (3.0.1) of RoboGuice on my new Android application using Android Studio 1.5 (stable).
Long ago, I dealt with Guice & RoboGuice but I took on some reading on how to use Roboguice with new improvements & features it got since.
The point here is that I want to use a custom module for custom bindings.
In my specific case I have a SoundManager class that provides tools to play multiple audio tracks at will with an internal pool of MediaPlayer. The main constructor takes the applicationContext that will be used to create new MediaPlayer. Furthermore this class ought to be a singleton :
If a track is to be played throughout the entire application, the SoundManager cannot be destroyed / recreated ;
One pool of MediaPlayer is enough, much like a ExecutorPool. It ought to be re-used whenever necessary for better resources management.
So I did the following :
Creating an interface exposing the default behavior of my SoundManager : play, stop, resume, release etc... ;
Implementing this interface in a fully working class ;
Creating a Module extending com.google.inject.AbstractModule with the following code :
#Override
protected void configure() {
bind(SoundManagerInterface.class).to(SoundManager.class).asEagerSingleton();
}
Now the whole point of this SO post :
where did RoboGuice.setBaseApplicationInjector() go ?? All articles I read with modules examples, the most recent as early as 2014, expose the same method : creating an Application class extending android.app.Application and in the onCreate() method, use RoboGuice.setBaseApplicationInjector(). But it does not exist ! The only available methods I have are :
RoboGuice.getOrCreateBaseApplicationInjector()
RoboGuice.destroyInjector()
RoboGuice.newDefaultRoboModule()
RoboGuice.overrideApplicationInjector()
RoboGuice.setUseAnnotationDatabases()
RoboGuice.injectMembers()
In my case I used getOrCreateBaseApplicationInjector() because it seemed to be the closest to setBaseApplicationInjector() and finally went on testing my code.
Suprise, it worked ! My SoundManager is properly created and the applicationContext is somehow injected (from where, I do not know, but I hope it's not the calling Activity or else I am done for leaking memory...) and audio tracks are indeed played.
But is the instance of my SoundManager that of a singleton ? No it is not. I tried injecting 3 of those and there are all differents object as the debugger is showing...
So what am I doing wrong ?
This link : https://github.com/roboguice/roboguice/wiki/Advanced-Custom-Bindings#register-the-module-with-roboguice cannot be reproduced in my code :/

The correct setup code is as per the wiki :
public class MyApp extends Application {
#Override
public void onCreate() {
super.onCreate();
RoboGuice.getOrCreateBaseApplicationInjector(this, RoboGuice.DEFAULT_STAGE, RoboGuice.newDefaultRoboModule(this),
new SoundManagerModule(),
);
}
}
From your use case (persistence throughout the entire activity, start/stop etc), it sounds like you want to create a RoboService and inject the SoundManager into that. Please see the documentation on Services. Merely creating a Singleton will not allow you to completely avoid standard Android architecture patterns.

Related

Clear Difference Between 'application' and 'activity' [duplicate]

An extended Application class can declare global variables. Are there other reasons?
Introduction:
If we consider an apk file in our mobile, it is comprised of
multiple useful blocks such as, Activitys, Services and
others.
These components do not communicate with each other regularly and
not forget they have their own life cycle. which indicate that
they may be active at one time and inactive the other moment.
Requirements:
Sometimes we may require a scenario where we need to access a
variable and its states across the entire Application regardless of
the Activity the user is using,
An example is that a user might need to access a variable that holds his
personnel information (e.g. name) that has to be accessed across the
Application,
We can use SQLite but creating a Cursor and closing it again and
again is not good on performance,
We could use Intents to pass the data but it's clumsy and activity
itself may not exist at a certain scenario depending on the memory-availability.
Uses of Application Class:
Access to variables across the Application,
You can use the Application to start certain things like analytics
etc. since the application class is started before Activitys or
Servicess are being run,
There is an overridden method called onConfigurationChanged() that is
triggered when the application configuration is changed (horizontal
to vertical & vice-versa),
There is also an event called onLowMemory() that is triggered when
the Android device is low on memory.
Application class is the object that has the full lifecycle of your application. It is your highest layer as an application. example possible usages:
You can add what you need when the application is started by overriding onCreate in the Application class.
store global variables that jump from Activity to Activity. Like Asynctask.
etc
Sometimes you want to store data, like global variables which need to be accessed from multiple Activities - sometimes everywhere within the application. In this case, the Application object will help you.
For example, if you want to get the basic authentication data for each http request, you can implement the methods for authentication data in the application object.
After this,you can get the username and password in any of the activities like this:
MyApplication mApplication = (MyApplication)getApplicationContext();
String username = mApplication.getUsername();
String password = mApplication.getPassword();
And finally, do remember to use the Application object as a singleton object:
public class MyApplication extends Application {
private static MyApplication singleton;
public MyApplication getInstance(){
return singleton;
}
#Override
public void onCreate() {
super.onCreate();
singleton = this;
}
}
For more information, please Click Application Class
Offhand, I can't think of a real scenario in which extending Application is either preferable to another approach or necessary to accomplish something. If you have an expensive, frequently used object you can initialize it in an IntentService when you detect that the object isn't currently present. Application itself runs on the UI thread, while IntentService runs on its own thread.
I prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences. There are also ways to pass data from a Fragment to its parent Activity using interfaces.
The Application class is a singleton that you can access from any activity or anywhere else you have a Context object.
You also get a little bit of lifecycle.
You could use the Application's onCreate method to instantiate expensive, but frequently used objects like an analytics helper. Then you can access and use those objects everywhere.
Best use of application class.
Example: Suppose you need to restart your alarm manager on boot completed.
public class BaseJuiceApplication extends Application implements BootListener {
public static BaseJuiceApplication instance = null;
public static Context getInstance() {
if (null == instance) {
instance = new BaseJuiceApplication();
}
return instance;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onBootCompleted(Context context, Intent intent) {
new PushService().scheduleService(getInstance());
//startToNotify(context);
}
Not an answer but an observation: keep in mind that the data in the extended application object should not be tied to an instance of an activity, as it is possible that you have two instances of the same activity running at the same time (one in the foreground and one not being visible).
For example, you start your activity normally through the launcher, then "minimize" it. You then start another app (ie Tasker) which starts another instance of your activitiy, for example in order to create a shortcut, because your app supports android.intent.action.CREATE_SHORTCUT. If the shortcut is then created and this shortcut-creating invocation of the activity modified the data the application object, then the activity running in the background will start to use this modified application object once it is brought back to the foreground.
I see that this question is missing an answer. I extend Application because I use Bill Pugh Singleton implementation (see reference) and some of my singletons need context. The Application class looks like this:
public class MyApplication extends Application {
private static final String TAG = MyApplication.class.getSimpleName();
private static MyApplication sInstance;
#Contract(pure = true)
#Nullable
public static Context getAppContext() {
return sInstance;
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate() called");
sInstance = this;
}
}
And the singletons look like this:
public class DataManager {
private static final String TAG = DataManager.class.getSimpleName();
#Contract(pure = true)
public static DataManager getInstance() {
return InstanceHolder.INSTANCE;
}
private DataManager() {
doStuffRequiringContext(MyApplication.getAppContext());
}
private static final class InstanceHolder {
#SuppressLint("StaticFieldLeak")
private static final DataManager INSTANCE = new DataManager();
}
}
This way I don't need to have a context every time I'm using a singleton and get lazy synchronized initialization with minimal amount of code.
Tip: updating Android Studio singleton template saves a lot of time.
I think you can use the Application class for many things, but they are all tied to your need to do some stuff BEFORE any of your Activities or Services are started.
For instance, in my application I use custom fonts. Instead of calling
Typeface.createFromAsset()
from every Activity to get references for my fonts from the Assets folder (this is bad because it will result in memory leak as you are keeping a reference to assets every time you call that method), I do this from the onCreate() method in my Application class:
private App appInstance;
Typeface quickSandRegular;
...
public void onCreate() {
super.onCreate();
appInstance = this;
quicksandRegular = Typeface.createFromAsset(getApplicationContext().getAssets(),
"fonts/Quicksand-Regular.otf");
...
}
Now, I also have a method defined like this:
public static App getAppInstance() {
return appInstance;
}
and this:
public Typeface getQuickSandRegular() {
return quicksandRegular;
}
So, from anywhere in my application, all I have to do is:
App.getAppInstance().getQuickSandRegular()
Another use for the Application class for me is to check if the device is connected to the Internet BEFORE activities and services that require a connection actually start and take necessary action.
Source: https://github.com/codepath/android_guides/wiki/Understanding-the-Android-Application-Class
In many apps, there's no need to work with an application class directly. However, there are a few acceptable uses of a custom application class:
Specialized tasks that need to run before the creation of your first activity
Global initialization that needs to be shared across all components (crash reporting, persistence)
Static methods for easy access to static immutable data such as a shared network client object
You should never store mutable instance data inside the Application object because if you assume that your data will stay there, your application will inevitably crash at some point with a NullPointerException. The application object is not guaranteed to stay in memory forever, it will get killed. Contrary to popular belief, the app won’t be restarted from scratch. Android will create a new Application object and start the activity where the user was before to give the illusion that the application was never killed in the first place.
To add onto the other answers that state that you might wish store variables in the application scope, for any long-running threads or other objects that need binding to your application where you are NOT using an activity (application is not an activity).. such as not being able to request a binded service.. then binding to the application instance is preferred. The only obvious warning with this approach is that the objects live for as long as the application is alive, so more implicit control over memory is required else you'll encounter memory-related problems like leaks.
Something else you may find useful is that in the order of operations, the application starts first before any activities. In this timeframe, you can prepare any necessary housekeeping that would occur before your first activity if you so desired.
2018-10-19 11:31:55.246 8643-8643/: application created
2018-10-19 11:31:55.630 8643-8643/: activity created
You can access variables to any class without creating objects, if its extended by Application. They can be called globally and their state is maintained till application is not killed.
The use of extending application just make your application sure for any kind of operation that you want throughout your application running period. Now it may be any kind of variables and suppose if you want to fetch some data from server then you can put your asynctask in application so it will fetch each time and continuously, so that you will get a updated data automatically.. Use this link for more knowledge....
http://www.intridea.com/blog/2011/5/24/how-to-use-application-object-of-android

Scheduling asynchronus tasks in PlayFramework 2.5.X (Java)

We have a Play-Project that uses PlayFramework 2.5.4 and MongoDB. We want to update our database daily. At the moment we check the time everytime we get a Request and update if a day is over.
That leads to some Problems:
The current player has to wait a quiet long time until the request finishes
it can happen that there is one day no update (but we want everyday one, even if nothing changes)
we have to modify every request we insert.
So i found already the documentation of AKKA and old stackoverflowquestions (like How to schedule task daily + onStart() in Play 2.0.4?). But the solutions don´t work anymore.
Akka.system().scheduler()
is deprecated
system.scheduler()
gives compilingerrors (from docu) and i dont know if an import is missing or what else.
As i know you should use #inject since Version 2.4, but i cant find proper examples on how to use it with schedule or how to use it afterall
Actually all i want to do is call PlayerDBHandler.newDay() every day on the same time.
Thanks for Help
Without seeing the compilation errors, I'm guessing that system isn't defined. Expanding the example from the documentation, something like this should work.
public class SchedulingTask {
#Inject
public SchedulingTask(final ActorSystem system,
#Named("update-db-actor") ActorRef updateDbActor) {
system.scheduler().schedule(
Duration.create(0, TimeUnit.MILLISECONDS), //Initial delay
Duration.create(1, TimeUnit.DAYS), //Frequency
updateDbActor,
"update",
system.dispatcher(),
null);
}
}
system is injected, and you can also inject a reference to the actor. Alternatively, you can look up the actor ref from system.
Once you've adapted this to do what you want, declare SchedulingTask in a module.
package com.example;
import com.google.inject.AbstractModule;
import play.libs.akka.AkkaGuiceSupport;
public class MyModule extends AbstractModule implements AkkaGuiceSupport {
#Override
protected void configure() {
bindActor(UpdateDbActor.class, "update-db-actor");
bind(SchedulingTask.class).asEagerSingleton();
}
}
Finally, update your application conf to enable the module.
play.modules.enabled += "com.example.MyModule"

How to access the Guice injector throughout application

I've just started using Guice and after reading the docs, skimming through a few books and watching the 2009 Google I/O talk I'm trying to convert a thrift project that relies on a few global data structures. At the moment they're created when the thrift server starts and passed to the handler on each request. They're also used in every part of the code! Essentially singletons.
As I understand it's best practice to create the injector in your main method and load all you're modules once.
I'm not sure how I'm meant to use this injector somewhere else in my code. Should I wrap it in a singleton class and litter my code with
Injector injector = InjectorInstance.get();
ClassA obj = injector.getInstance(ClassA.class);
Or is there a method I don't know about
ClassA obj = Guice.getLastInjector().getInstance(ClassA.class);
I've also found a recommendation to pass around Providers but I'm not sure how that's any better than passing the actual data structures down the call stack.
If someone could explain the recommended pattern, or even better send me in the direction of a good open source project that uses guice I would be grateful!
For Guice, the idea is that you have an entire graph of dependencies, each of which keeps a reference to the things it needs across its lifetime:
class EntryPoint {
public static void main(String[] args) {
YourApp yourApp = Guice.createInjector(yourListOfModules())
.getInstance(YourApp.class);
yourApp.run();
}
}
class YourApp {
#Inject DependencyA dependencyA;
}
class DependencyA {
#Inject DependencyB dependencyB;
}
class DependencyB {
/** This is injected once, so you'll always only get the same instance. */
#Inject DependencyC dependencyC;
/** By injecting the provider, you can get multiple instances. */
#Inject Provider<DependencyD> dependencyD;
}
Guice takes care of the plumbing, so YourApp and DependencyA don't need to worry about whether DependencyB needs DependencyC or DependencyD. In this sense, you never call new: Guice takes care of creating every #Injected dependency for you, and then supplying its dependencies.
If you haven't plumbed through your dependencies (i.e. you still call new in your code), you'll no longer have access to the Injector from the manually-constructed class. In that case you may want to use getInstance or getProvider and stash it away in a static field. Guice will also help you do this with requestStaticInjection, which is not great for long-term Guice design but may help you work with legacy code or transitioning into Guice.

Facebook SDK friendPickerFragment.setOnSelectionChangedListener causing error for android project

I have set up an OnSelectionChangedListener to my project as follows:
friendPickerFragment.setOnSelectionChangedListener(new PickerFragment.OnSelectionChangedListener() {
#Override
public void onSelectionChanged(PickerFragment<?> fragment){
FriendPickerApplication application = (FriendPickerApplication) getApplication();
application.setSelectedUsers(friendPickerFragment.getSelection());
setResult(RESULT_OK, null);
finish();
}
});
This is the exact same format at the OnDoneButtonClickedListener in the facebook sdk sample app "FriendPickerSample". I am getting the error
java.lang.ClassCastException: android.app.Application cannot be cast to com.garrenkeith.facebook.FriendPickerApplication
I am looking for a solution to fix the code that will add the selected user to the application when a user is selected.
Check your manifest file. You probably haven't configured your FriendPickerApplication class in the <application> tag.
Furthermore, are you sure you need to subclass `Application'? From the Android docs:
There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton.

Android Memory Managment: Engine as Singleton?

I'm going through some memory issues with my Android development.
I was wondering if my actual model would work, and also would like some input on how to do this in a better way:
I need public static final globals
I need public global variables that never gets garbage collected
I need to have an Engine running and never destroy without me calling stop()
MainApplication : Application
public static final Boolean DEBUG = false;
onCreate()
Engine.getEngine().prepare()
MainActivity : Activity
onResume()
Engine.getEngine().start()
onPause()
Engine.getEngine().stop()
Engine
prepare()
MainApplication.DEBUG = true;
start()
LocationManager.requestLocationUpdates()
stop()
LocationManager.removeUpdates()
Engine is a Singleton class, receiving location updates and such.
It is imperative that my Engine class does not get released not the DEBUG variable.
For your "Type 1" constants use a dedicated public class containing public static final T NAME = Val; - declarations.
For the Engine, I'd recommend using a Service.
For your "Type 2" vars, the Service could offer getters or you could make use of SQLite.
I see there's some "Location"-Stuff going on there ... the developer website has some good "best practices" on using the Location Services. Maybe there you'll get some more inspiration.

Categories