Global data between activities [duplicate] - android

This question already has answers here:
What's the best way to share data between activities?
(14 answers)
Closed 6 years ago.
I have a activity that shows a list of products and a detail view where I can edit these products. I want to access the same list of products from both activities.
How do I store/use this global data between these multiple activities?

You may want to use a Singleton design pattern: create a class and limit it to have only one instance that will hold a list of products. After that, access this instance and the same list from both of your activities:
// singleton Manager
public class ProductManager {
private static ProductManager sInstance;
private List<Product> mProducts;
// private constructor to limit new instance creation
private ProductManager() {
// may be empty
}
public static ProductManager getInstance() {
if (sInstance == null) {
sInstance = new ProductManager();
}
return sInstance;
}
public List<Product> getProducts() {
return new ArrayList<>(mProducts);
}
// add logic to fill the Products list
public void setProducts(List<Product> products) {
mProducts = new ArrayList<>(products);
}
}
Access it later from both activities:
MyListActivity.java:
// set products once you get them
ProductManager.getInstance().setProducts(yourProductsList);
// ...
DetailsActivity.java:
// get the same list
ProductManager.getInstance().getProducts();
// ...

1) You can define array List as a static in Application Level or Base Activity.
2) Pass array List to other Activity using serializable or parcelable.
3) You have more data in array list then you can use SharedPreferences.

Related

What is the recommended way to update a LiveData variable in ViewModel from Repository in the MVVM design pattern?

I am a beginner in MVVM architecture. I want to retrieve a list of items from the database and I want to keep track of the number of items that i retrieve. I am following the MVVM design pattern. The following is the first approach I thought of:
class SampleViewModel extends ViewModel
{
private MutableLiveData<Integer> count = new MutableLiveData<>();
getItems();
public void getItems()
{
List<String> items = new ArrayList<>();
/*
* I am skipping the code to access the database and retrieving the list
* */
for (String item : items)
{
items.add(item);
count.setValue(items.size());
}
}
LiveData<Integer> GetCount()
{
return count;
}
}
Then observe the count data from my activity. But, then I learned that, it is recommended to do database related tasks from the Repository and according to this doc, LiveData variable is not recommended to be passed from ViewModel to Repository. So, my question is how can I update count variable from Repository or in other words, What is the recommended way to update a LiveData variable in ViewModel from Repository, so that it can be observed fro the activity properly?

How to send data between one adapter to another adapter?

Actually, I have a Recyclerview where has a button and(where I get id with position[from RestAPi call])--->>when the button is clicked I set another recylerview..and now I want to the from the first RecyclerviewAdapter.
I have already tried global variable
Here is images enter image description here
From my previous answer from another question i think you need a Singleton Pattern rather than a Global Variable
You simply need a getter that returns the another Adapter's ArrayList<SingleItemModel> but the problem you will face is that you need to have the same instance of the Adapter from the Activity in order to get the populated ArrayList<Model>.
A good workaround is to used Bill Pugh's Singleton in the Adapter
public class Adapter {
private ArrayList<Model> list;
private Adapter() {}
public static Adapter getInstance() {
return InstInit.INSTANCE;
}
// Don't forget to set the list (or NPE)
// because we can't argue with a Singleton
public void setList(ArrayList<Model> list) {
this.list = list;
}
// You can now get the ArrayList
public ArrayList<Model> getList() {
return list;
}
private static class InstInit {
private static final Adapter INSTANCE = new Adapter();
}
// Some codes removed for brevity
// Overrided RecyclerView.Adapter Methods
.................
}
Retrieving the ArrayList assuming that the following Adapters are Singleton
AdapterOne a1 = AdapterOne.getInstance();
AdapterTwo a2 = AdapterTwo.getInstance();
ArrayList<Model> a1RetrievedList = a1.getList();
// You don't need to create a new instance
// creating a new instance doesn't make sense
// because you need to repopulate the list
// for the new instance.
ArrayList<Model> a2RetrievedList = a2.getList();
// You can also retrieve from AdapterTwo

Android LiveData Modification prob

I want to show a product list in my Android Application using Android new Architecture components. I have a Pojo class named Products like below:
public class Products {
private List<ProductDetails> products = null;
private Integer onSaleCount;
private Integer total;
private Integer page;
.........................
}
The webservice returns the list with pagination:
#GET("/products/")
Call<Products> getProducts(#Query("page") int page)
So each product list call, I am getting one set products list with other data.
I have already defined method to call the same in ProductListRepository:
public class ProductListRepository {
#Inject
ProductService mProductService;
public Products getProductList(int pageNo) {
.......................
..................
}
}
But I am facing problem to set the LiveData in ProductViewModel because I want to merge the List of ProductDetails with older one and also update the value of the other variables in Products like onSaleCount, pageNo.
public class ProductListViewModel extends ViewModel {
private final ProductListRepository mProductListRepository;
private MediatorLiveData<Products> mProducts;
public void getProductList(int pageNo) {
Products products = mProductListRepository.getProductList(pageNo);
if(products==null){
mProducts.setValue(products);
}else{
// **How to add old List and new List and set it to LiveData**
}
return mProducts;
}
}
Can anyone help me?
To just modify data, mProducts can be MutableLiveData<Products>, and your code like this:
public void getProductList(int pageNo) {
Products products = mProductListRepository.getProductList(pageNo);
if (products == null) {
// Nothing to do, no new data
} else {
Products oldProducts = mProducts.getValue();
// merge oldProducts and products into newProducts, as you prefer
mProducts.setValue(newProducts);
}
}
MediatorLiveData is designed to observe multiple LiveData sources.

for Android is it a good idea to pass a list of object from one Activity to another ?

Is it a good idea to pass a list of object from one Activity to another for Android ?
It is quiet troublesome to pass a list of object in an intent, and I wonder whether it affect the performance if the object list is too large or the object is too complicated.
Is it a better solution to get the list of object from other place, for example, query the DB once more , or save the list of object in a temporary class and fetch it in new Activity?
As long as you are passing Parcelable objects' list, nothing's wrong when passing through Intent. Regarding performance, that is up to you and the amount of data you pass.
As per my experience, If you are passing data up to 1MB of size, it should be fine. Anything above that will fail as this seems to be the limit. Read this.
Besides, you are welcome to use preferences, SQLite, files or static-object-referencing methodologies to fetch your data anytime and anywhere.
Solution1 : Use Intent
Send :
Intent data = new Intent(Activity1.this,Activity2.class);
data.putParcelableArrayListExtra(Constant.LIST_OBJECT,
(ArrayList<? extends Parcelable>) getObjects());
receive :
List<YOUR_OBJECT> objects = data.getParcelableArrayListExtra(Constant.LIST_OBJECT);
Solution2 :
public class SessionData {
private static SessionData instance;
private final List< YOUR_OBJECT > listSessionObjects;
private SessionData() {
listSessionObjects = new ArrayList<>();
}
public static final SessionData getInstance() {
if (instance == null) {
instance = new SessionData();
}
return instance;
}
public List<YOUR_OBJECT> getListSessionObjects() {
return listSessionObjects;
}
public void setListSessionObjects(List<YOUR_OBJECT > objects) {
listSessionObjects = objects
}
}
to use it :
SessionData.getInstance().getListSessionObjects();
SessionData.getInstance(). setListSessionObjects(objects);

Using a ForeignCollection

My entity contains the following private ForeignCollection attribute:
#ForeignCollectionField
private ForeignCollection<Order> orderCollection;
private List<Order> orderList;
What is the best way or usual way to avoid a having a caller use a ForeignCollection? Is there any neat way to return the Collections data to a caller?
How does the following method look? It allows a caller to access the data via a List. Would you recommend doing it this way?
public List<Order> getOrders() {
if (orderList == null) {
orderList = new ArrayList<Order>();
for (Order order : orderCollection) {
orderList.add(order);
}
}
return orderList;
}
If it's ok to change the signature to Collection rather than List, you could try using Collections.unmodifiableCollection().
public Collection<Order> getOrders()
{
return Collections.unmodifiableCollection(orderCollection);
}
Otherwise, your approach of using a lazy member variable is fine (provided you don't need synchronization). Also, note that you can just use the constructor of ArrayList to copy the values from the source collection:
orderList = new ArrayList<Order>(orderCollection);

Categories

Resources