Share data between fragments in android - java

What is the best solution to deal with an "AdapterA of a RecyclerViewA which is inside a FragmentA" that want to use data from another "AdapterB of a RecyclerViewB which is inside a FragmentB" ?
I am stuck,i tried to :
1- Make the data static in the adapter (no garbage collector)
2- Duplicate data that i need (waste of memory)
(it works but may be there is a better solution)
Thank you in advance. (plz ask for details if you need)

If you, in MainActivity, create a new instance of a class where you contain whatever you want both fragments to access. If you implement Serializable or Parcelable, you can also send it to each fragment using Bundle/Intent.
Then, as you have the same instance in two different fragments, if you edit data in fragment X, fragment Y will be able to access it.
See this:
|---MainActivity---|
| | |
V V V
Frag A <->Data <->Frag B
MainActivity creates a new class(data) which it sends to each of the fragments. The fragments can update the data in the class. Please note, that you have to use class if any given data type isn't supported.
If you don't feel like using Serializable or parcelable, if possible, send MainActivity as an instance to each of the fragments. From each fragment you then get the MainActivity instance and find the data you need.
If you can't pass MainActivity to either of the fragments, and cannot use Serializable/Parcelable and the data type isn't supported by bundle.putExtra or intent.putExtra, you have to use a static import.
Those are your only options.
Alternatively, you can create a class that extends "Application". Then you write:
MyApplicationClass mac = (MyApplicationClass) getApplicationContext();
Then you access the data in the application-extending class(here: the mac instance)
Final words
If you do not want to use static instance, send a parcelable/serializable class with the contents, or use a class extending Application, there is no way you can transfer the data(considering you are using a HashMap which you claim cannot be sent by Intent or Bundle). If you had a data type or class that was possible to send using Intent or Bundle, you wouldn't have to use static instance or parcelable/serializable class. But with the position you are in, I have presented all the options you have. There are basically no other ways than using a class containing the hashmap, using a static instance or utilizing the Application class.

Related

How can I pass a string value from a Fragment to an Activity in Android Studio?

I have an Android app with a Fragment that contains an EditText field. When the user enters a value in the EditText field, I need to pass this value to the hosting Activity so that it can be used in other parts of the app.
I have tried using an Intent to pass the data, but this opens a new instance of the Activity, which I do not want. I have also tried using a Bundle, but I'm not sure how to access the Bundle from the Activity.
What is the best way to pass a string value from a Fragment to an Activity? Are there any code examples or tutorials that can help me achieve this?
Without much detail I would say that you best bet is using a shared ViewModel between the activity and the fragment.
one resource you can easily follow: https://www.geeksforgeeks.org/shared-viewmodel-in-android/
1. First approach
The best approach is to use Interface, try to search how to pass data from Fragment to Activity using Interface.
2. Second approach
This approach is to use ViewModel like the example mentioned above https://stackoverflow.com/a/75472219/11170352
3. Third approach
This is the laziest approach follow this example
YourFragment
// Get a reference to the hosting Activity
YourActivity yourActivity = (YourActivity) getActivity();
// Call a public method in the Activity to pass the data
yourActivity.setData(myData);
YourActivity
public void setData(String data) {
// Do something with the data
}
Note that this approach assumes that the hosting Activity is of a specific class (YourActivity in this example). If you need to use this approach with multiple Activities, you may want to add some checks to ensure that the Activity is the correct type before casting it.

When to use static vs. intents for "global" instances of an object

I want to instantiate an object in my MainActivity class that will be used and altered by my other activities.
The object is a custom data type.
Would it best best to declare the object as public static in MainActivity and then just use MainActivity.object throughout my application? Or would it be better to just pass the object around using intents?
The main thing I'm worried about using static is that I've seen people saying you use it when you care about privacy but I'm not too sure what that means so.. hoping to get some input.
Thanks
If you need one object on all app, you can store this object in Application class

Android: Passing same variable between 3 activities?

So I have a (Kotlin) data class that gets instantiated in my startup activity (we'll just call the object dataObj). I have two other activities that need access to the dataObj that was instantiated on startup. I know I could have my data class implement the Serializable interface so that I could pass the object between the three activities using intents. But I also have been thinking that I could use a static variable in the constructor so that I could easily just grab the values for the class. I'm just trying to figure out what is recommended and what is good practice.
It really depends on your use case, but I'd generally recommend against static implementations (to include singletons, see What is so bad about singletons?). They become hard to test adequately over time and can (in short) lead to many other problems depending on implementation.
If it is a relatively simple object where state change is rare, only done in one Activity at a time, and/or irrelevant, implementing a Parcelable and passing that to each Activity via an Intent is probably best.
If this is a complex object or an object that can change dynamically, the preferable solution would be to use a dependency injection platform (such as Koin if you're using Kotlin) to instantiate the data and provide it as a dependency. Koin is pretty straight forward, a very basic implementation from the Koin website (and missing just a few lines to be complete):
// Injected by constructor
class MyViewModel(val repo : MyRepository) : ViewModel()
// declared ViewModel using the viewModel keyword
val myModule : Module = module {
viewModel { MyViewModel(get()) }
single { MyRepository() }
}
// Just get it
class MyActivity() : AppCompatActivity() {
// lazy inject MyViewModel
val vm : MyViewModel by viewModel()
}
In this case, your object would be something like MyRepository() in the example. You'd just have to add the startKoin([list of modules]) from there. If you wanted MyRepository() in your Activity you'd include it like val myRepo: MyRepository by inject(). I don't know if this is outside the scope of your project though, it all depends on what you're trying to do exactly.
One big issue with this is that static variables don't survive Android low-memory state, but sending intent between survives. Also read here about static variable. (Link)
You have two options here:
Send it via Intent after implementing Serializable or Parcelable by you data class,
Save your data object to .txt file and read it when you need it.
static it is not created for this kind of things and You shouldn't use it in this case.
In my opinion You should go with first option.
This isn't the best method (although there really isn't a perfect way to do this), but you could instantiate it in a custom Application class.
class App : Application() {
val yourObject by lazy { YourObject() } //by lazy is useful if the Object needs to hold a Context or something that isn't immediately available
}
Add android:name=".App" to the application tag in your manifest so your App class is actually used. .App assumes it's in the root of your application package.
Then, from anywhere you have a reference to a Context, you can do something like:
(context.applicationContext as App).yourObject
to access the Object.

Where I should store SQLite database reference?

I'm creating simple application that uses JSON format and SQLite database to store parsed information into that. I'm aiming to support both normal devices and tablets, so I'm using Android Fragment API.
My problem is that I'm not sure where I should store the reference to my database, at this moment I have main activity that incorporates two fragments - list fragment and details fragment (both of them are adjusted for tablets and normal phones).
I need to fill mentioned list with information from database and in future I want to implement additional search function so reference to database must be shared by almost all fragments/activities.
In addition I have special class(Util) that stores HTTP object and JSON parser. Is it good idea to add static database reference to that class and create new instance of it in seperate thread (initialization block) ? Or I should consider create it in MainActivitity and create getter and setter ? My MainActivity implements appropriate interfaces from list fragment so I'd need to cast it.

How to Bundle google cloud endpoint message class in android

To pass data from an Activity to a Fragment, naturally, I think of using a Bundle. The problem in my case is that the Object I need to pass is a Google Cloud Endpoint message, which is neither Parcelable nor Serializable. So how might I pass the data?
For clarity, a Google Cloud Endpoint message is a POJO that is used to pass data to and from endpoint methods. I assume they would be Serializable, but to my surprise they aren't.
You can:
Subclass and implement Serializable or Parcelable on that class
Or use any other strategy to pass data inside of the app:
Singleton class holding any memory cache you may use
If the fragment is inside of the activity you can access the fragment from the activity and pass the variable in
In the worst of cases you can always use SharedPreferences or any kind of disk persistence

Categories

Resources