So basically, I'm creating a game on a SurfaceView and I have these classes on my main CustomView:
private TitleScreen titleScreen;private GameScreen gameScreen;private PauseScreen pauseScreen;private GameOverScreen gameOverScreen;
Each of these classes have a draw(Canvas canvas) method, and is called when the user goes to another screen. But the thing is, I have a SoundPlayer class that includes all of my sound effects using SoundPool. It will be used on all these classes. Is there actually a way that the SoundPlayer only loads once, then is available throughout these classes? Or do I have to call release() and recall the constructor everytime I switch? Thanks in advance. :D
UPDATE (SOLVED):
So here's what I did. I created an instance of my SoundPlayer class:
public class SoundPlayerInstance { private static SoundPlayer soundPlayerInstance; private SoundPlayerInstance(){} public static void createInstance(Context context){ soundPlayerInstance = new SoundPlayer(context); } public static SoundPlayer getInstance(){ return soundPlayerInstance; }}
On my main view, before I do anything, I call this in my constructor:
SoundPlayerInstance.createInstance();
Then, on any of my classes, I can just call it to play the sound:
SoundPlayerInstance.getInstance().playSound();
I think this will be useful not only for situations like these, but it can also be useful for developers (like me) that want to instantiate a class that is available throughout all other classes. Thanks to system32 for answering my question. :)
Is there actually a way that the SoundPlayer only loads once, then is
available throughout these classes?
It's possible. Make SoundPlayer class singleton.
public class SoundPlayer
{
private static SoundPlayer instance;
private SoundPlayer()
{
// Do some stuff
}
public static SoundPlayer getInstance()
{
if(instance == null)
instance = new SoundPlayer();
return instance;
}
}
To access globally, just call SoundPlayer.getInstance()
Related
Hi I am kind of new to android, still learning. And my problem is that, for example I have a method which was created in the MainActivity and I need to call it from another class.
Is it a good practice to get the instance of the MainActivity so that I may be able to call the method in the MainActivity from another class?
This is an example:
public class MainActivity extends AppCompatActivity {
private static MainActivity inst;
public static MainActivity instances()
{
return inst;
}
#Override
public void onStart() {
super.onStart();
inst = this;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void showToast (String text){
Toast.makeText(inst, text, Toast.LENGTH_SHORT).show();
}
Then this is the other class:
public class broadcastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
MainActivity instance = new MainActivity();
instance.showToast(AnyText);
}
}
I saw this type of coding while looking at tutorials and wondered if it's a good practice or maybe there might be a better way? Since I get the warning of Do not place Android Context Classes in static classes
Thanks in advance for any insight or help! :D
I guess You want to make A singleton of Activity Class
but as Mention in All Pattern Design
using Singleton
If and Only If its only way to Make A Global Variable
Singleton is based on Lazing Initialing and Load On Memory
so I guess If you cant to Interact With Activiy You can Use
BroadCast Or Intents
You can call method from another class like this:
MainActivity instance = new MainActivity();
String data = instance.data();
and create data method in that class:
public String data() {
return mangaId;
}
Is it a good practice to get the instance of the MainActivity so that
I may be able to call the method in the MainActivity from another
class?
You totally can do this but you don't need to make it static and use a constructor. Just create a new instance like follows and you'll access the public methods
MainActivity mainActivity = new MainActivity();
mainActivity.showToast(text);
About the warning
It suggests avoiding having context fields defined as static. The warning itself explains why: It's a memory leak. If you make it static it will be accessible anywhere in your app and some methods can hold the reference to this context for a really long time and it won't be garbage collected. It will lead to a outofmemory exception and the app could crash. But here you're trying to invoke showToast() from broadcastreceiver so you can just get rid of static references. And it you need them in the future you safe ways to inject context
You cannot create instances of an Activity using the new operator.
You have to use an Intent to let an Activity to be created.
So you cannot get a reference to an instance of your activity.
The only methods you can use of your activity class are static ones.
I've stumpled upon an Android Application Class which implements the Singleton pattern and bind a static object to it.
public class App extends Application
{
public static BigObject myObj;
private static App instance;
public static App getInstance()
{
return instance;
}
#Override
public void onCreate() {
super.onCreate();
instance = this;
myObj = new BigObject(this);
}
}
Are there any problems with this implementation, regarding performance, memory leaks or maybe Exceptions, when getInstance().myObj.something() is called form BroadcastReceiver or Service?
The only drawback I see is somewhat ugly code, using dependency injection would be better. I don't know, but if OS guarantees that all other components will be launched after Application::onCreate than there is no issues. Even non-main threads will not cache value of bigObject. But if you want set value of bigObject after onCreate, or it's creation takes long time you can face issues with data racing or slow startup.
I don't see any problems with this implementation. The Application object is basically a singleton.
I have a class called myConstants and in it i list all my constants so when i need them I just reference MyConstants.MYCONSTANT. However, i would like to implement something like this for methods. i am repeating a lot of code, for instance, i have a formatCalendarString(Calendar c) method in 3 activities. seems redundant and unecessary. but i cant make them static because i get static calling non-static errors and the only other way i can think is to make a MyConstant object then call public functions off that object, like this...
MyConstants myConstants = new MyConstants();
myConstants.formatCalendarString(Calendar.getInstance());
is there some way i can just call the formatCalendarString() inside MyConstants class without generating an object?
You can use singleton pattern to cache instances. Keeping methods in something like parent activity does not make any sense (as primary role of activity is user interaction).
Example:
public class MyConstants {
private static MyConstants ourInstance;
private MyConstants() {
//private constructor to limit direct instantiation
}
public synchronized static MyConstants getInstance() {
//if null then only create instance
if (ourInstance ==null) {
ourInstance = new MyConstants();
}
//otherwise return cached instance
return ourInstance;
}
}
You just need a private constructor and public static method that would only generate instance if it is null.
Then, call MyConstants.getInstance().whateverMethod(). It will create only single instance.
However when using singleton, please keep memory leaks in mind. Do not pass activity context directly inside singletons.
If you want to have all methods in activities, you can put then in abstract class BaseActivity, which extends Activity, and then make your activities extends BaseActivity. However, if these methods doesn't correspond to something about activity, I suggest some Singleton or Util class
I agree with Pier Giorgio Misley. It's also good to add a private constructor, because you don't obviously want to instantiate an object.
Can't you just use a parent class? That way you can just inherit the methods and manage in one source. Then you don't have to use static functions then.
Edit: Like Tomasz Czura said, just extend the Class.
public class ParentClass {
public void commonMethod(){
}
}
public class OtherClass extends ParentClass{
}
You can use the Static keyword.
Static methods can be referenced from outside without istantiating the new object.
Just create a class:
public class MyClassContainingMethods{
public static String MyStaticMethod(){
return "I am static!";
}
}
Now call it like
String res = MyClassContainingStaticMethods.MyStaticMethod();
Hope this helps
NOTE
You CAN call non-static from static by doing something like this:
public static void First_function(Context context)
{
SMS sms = new SMS();
sms.Second_function(context);
}
public void Second_function(Context context)
{
Toast.makeText(context,"Hello",1).show(); // This i anable to display and cause crash
}
Example taken from here, you will obiouvsly have to fit it into your needs
I created a class that uses 1 SOUNDPOOL to play musical notes. The problem is that there are a lot of notes and thus loading takes too long. I'd like to know if it was possible to use a single instance of the class in several activities to avoid having to recreate my music player each time.
have you heard of Singleton Design Pattern? Have a look at Wikipedia. Following this design pattern will ensure you have ever created only one instance of the class and all other classes will reuse this only instance.
Use Singletone design pattern
public class ClassicSingleton {
private static ClassicSingleton instance = null;
protected ClassicSingleton() {
// Exists only to defeat instantiation.
}
public static ClassicSingleton getInstance() {
if(instance == null) {
instance = new ClassicSingleton();
}
return instance;
}
}
As the other said, use Singleton. In fact, Android provides a Singleton object already, which is the Application. You may want to use that.
I got a singleton class in my application, which is defined just somewhat like:
public class SingletonTest {
private SingletonTest() {}
private static SingletonTest instance = new SingletonTest();
public static SingletonTest getInstance() {
return instance;
}
}
When I exit my application and open again, the instance has not been initialized again because the former one is not destroyed and still in JVM. But what I want is to initialize the static field every time I enter my application. So, what should I do in the onDestroy() method? Thanks a lot!
Your static variable will remain in memory as long as your application stays in memory.
This means that, a static variable will be automatically destroyed together with your app.
If you want a new instance of your singleton, you will need to create a static method that reinitializes your singleton and call it in the onStart of your application object or the first activity you launch(or whenever you need it)
private Singleton() {}
private static Singleton mInstance;
//use this method when you want the reference
public static Singleton getInstance() {
//initializing your singleton if it is null
//is a good thing to do in getInstance because
//now you can see if your singleton is actually being reinitialized.
//e.g. after the application startup. Makes debugging it a bit easier.
if(mInstance == null) mInstance = new Singleton();
return mInstance;
}
//and this one if you want a new instance
public static Singleton init() {
mInstance = new Singleton();
return mInstance;
}
something like that should do.
From what you are saying, it seems that Singleton is not suited for what you want to do. You should declare an instance variable that would be initialized/cleared by the methods onCreate()/onStart() and onStop()/onDestroy().
See this graph for the Activity lifecycle.
Source : http://developer.android.com/reference/android/app/Activity.html