I have:
public MissionActivity extends AppCompatActivity {
public SoundPlayer getSoundPlayer();
public DiffrentSoundPlayer getDiffrentSoundPlayer()
//...etc.
}
I am passing this Activity in constructor to another class that need all
this soundplayers and assetManager. All these players need to be created in activity. My question is: is this a good practice in Android to pass reference to Activity to another object?
Passing the activity is not in itself problematic, but given the scope of activities is something that should be done thoughtfully.
Depending on your specific case I would consider wrapping the objects that you have created on the activity inside a data transfer object and pass that object to the class that needs the objects. And by "data transfer object" I simply mean an object whose sole purpose is to store the data/objects that you are transferring.
But simply passing the activity to the other class is also completely okay, as long as you don't store the activity in that other class (just store the objects that you need from the activity).
Related
I'm not sure if what I'm asking is correct, so please forgive my ignorance.
I need to use an object initialised in the main activity in another one.
I serialized the object class with implements Serializable and sent it to the new activity putting into an extra, retrieving it later with intent.getSerializableExtra.
The other way would be access directly the previously public declared object from the activity using the following:
MainActivity mainActivity = (MainActivity) this.getParent();
Object object = mainActivity.object;
Is any of this correct?
If yes, which one?
If both which is better?
I am not sure if you have the right design in the first place. Trying to cast the MainActivity is not a good practice. This is a step towards making it a God class.
I am not sure what is the point of sending a Serializable object. In general more likely is to use some primative values or Strings. If is something heavy why to pass it? And what bothers me more is that you are saying that you want to use something "initialized " in the MainActivity which makes me think that you are not trying to pass data, but access the state of MainActivity from another Activity which is a bad practice.
The Views needs to present data and notify for events like clicks some "other code". Nothing more. You can have some singleton class and change its state as appropriate depending on the actions in the First Activity. Then from the Second Activity, let's say you have MVVM, you create the ViewModel and observe it, the ViewModel in its init{} can call the shared singleton and can propagate the data back to the second Activity through LiveData, or better just to tell it what to "show" to the user.
I hope it helps.
What is the best way to pass data from an Activity to fragment, but the fragment is hosted by another activity.
Elaborating:
Activity A hosts Fragment A (content in activity A) <== Activity B
I have already achieved this, but apparently, my way of doing it has caused some memory leak.
An example would be to refresh a RecyclerView contained in a fragment when an activity is closed, but I do not want to put it in the onResume.
interface contained in the activity(is not the host)
public class Activity extends AppCompatActivity{
public static OnlistenClose delegate;
public interface OnlistenClose {
void refreshList();
}
}
//fragment that implements the interface
public class FragmentB extends Fragment implements Activity.OnlistenClose{
Activity.delegate = this;
#Override
public void refreshList(){
//my code
}
}
Using square/leakcanary indicates there are leaks.
What is the best way to pass data from an Activity to fragment, but the fragment is hosted by another activity.
Ultimately, you are passing data from one activity to another. If the data is stored permanently in a database or file, then the receiving activity should just read the data after the first one has updated it.
On the other hand, if you are passing data that only needs to be available in memory, then you can pass the data with an Intent.
As you have seen, keeping a reference to one activity in another activity causes memory leaks. The callback method which you are attempting to use is only valid for the activity which owns the fragment, not for a second activity. Instead, you should honor the activity lifecycle and use Intents for communication as appropriate.
There is no "best practice" for a general question or even a specific circumstance.
Standard ways of passing data:
Intents
Storage
Shared Preferences
Internal Storage
External Storage
SQLite Databases
Network Connection
Static class (no link necessary)
Etc, etc
There are many ways to accomplish a task as there are ways to describe that task in a sentence.
I finished my work.
I completed my task.
It's published in the Play Store.
I'm done.
I have nothing to do.
I need to pass an object between 2 activities that have no connection between them (meaning, neither of them calls the other).
My Main_activity extends TabActivity. I have 2 tabs : CurrencyList (extends ListActivity implements OnItemSelectedListener) and CurrencyCalculator extends Activity.
I also have class currencyData that saves data about different currencies.
In the CurrencyList activity I created a new currencyData object and initiate it with data.
How can I pass it also to the CurrencyCalculator activity?
2 quick ways:
1. use an static method in your activity to retrieve current ticket id
2. Design and implement an interface and register the fragments as listeners from the activity
Static Method is preferable for large data.
If there is absolutely no connection between them, then one method of accessing data in different Activity classes would be to declare the data members as static class members. Keep in mind that static objects from Activities persist even after you destroy the activity and Android keeps this around for some time even after the you leave the application.
These might not be the easiest ways (just some alternate approaches to the two answers given). You can use a Handler or a BroadcastReceiver to pass the data to the other activity through an intent.
Note
that your object would have to implement either Serializable or
Parcelable if you want to pass it through an intent. I have used
Serializable before and as long as your object does not have any
nested custom objects, you actually have to do no additional work.
Also the assumption is that the receiving activity is alive and is
able to receive the broadcast and/or message.
Another approach would be to write the object to a file (again it would need to be serializable) and read it back in the other activity.
My app contains 2 activitys. Activity A is the one which is created by starting the app. In this one I create an object of my own class MyClass. This class contains one string and 3 integers. In activity A this object gets written.
The second activity B needs to read this object. How can I pass it from A to B? Or is there an other solution?
There are couple of way you can pass an object from one activity to another:
1. Application Class: this class is visible to all your application Activities so you can save your object in this class from one Activity and then access it from the other.
2. You can break apart your Class into the simple variables: string and 3 integers and pass them via a bundle or the intent it self from one activity to another, then construct your object again.
Intent intent = new Intent (this, TargetActivity.class);
intent.putExtra(KEY, value);
intent.putExtra(KEY, "value");
startActivity(intent);
3. If your object implements Serializable/Parcelable then you can pass it via a bundle.
Example on how to serialize an object:
How do I serialize an object and save it to a file in Android?
One option could be implementing Serializable interface and then you can pass object instances in intent extra using putExtra(Serializable..) variant of the Intent#putExtra() method.
//to pass :
intent.putExtra("MyClass", obj);
// to retrieve object in second Activity
getIntent().getSerializableExtra("MyClass");
It can be tricky, because there's no guarantee that your application can't be killed between activities. Actually, it can be killed during activities, so keeping persistent objects around can be tricky.
My preferred way to do this is the "singleton pattern" in which you create a class whose purpose is to create a single instance that holds whatever data you want to hang around. If your application gets killed, the singleton instance will be lost and have to be re-created, but all Android apps run this risk all the time anyway.
See Save multiple instances states of the same Activity in Android for my implementation of a singleton in Android.
Oh, and I should add that this only works within an application where all the activities are in the same process, sharing the same address space. Otherwise, you'll have to make your object serialiazable and write it off to a file.
I need to keep a reference to an object between different activities. The two said mentions seem to create new objects from activity to activity. This is a problem because changes to the object in the "child" activities don't persist once the parent activity gets focus. My solution to this was just to create a static getter in the parent-most activity which the child activities call and work with. Is this the incorrect way to go about this?
If you want to share a single instance of an object between activities, you can create a singleton class. The only thing wrong with using your parent-most activity class to implement the singleton might be that it might violate the single responsibility principle.
You can make your object persistent throughout the whole application lifecycle by making it a field in your Application-derived class.
public class MyAppication extends Application {
private Object mMyData;
public setData(Object data) {
mMyData = data;
}
public Object getData() {
return mMyData;
}
}
Then ((MyApplication)getAppllication()).setData or getData()
This way you can exchange data within the application because MyApplication will always exist.
You'll also have to add MyApplcation to manifest
You should create a Singleton, this has a single instance whenever you talk to it. (Just like your describing).
Here's one I made earlier : https://stackoverflow.com/a/6539080/413127