I'm developing an android application that deals with bitmaps. Right now I'm using an LRUCache to store these bitmaps, but there are going to be multiple fragments that require access to this cache. What's the best way to handle to handle a global application cache? Should I use a singleton? Should I create a new cache for each activity/fragment that requires access to it?
To avoid Singletons in Android Development, like in your question I would suggest anybody using Fragments to store real global Objects in the MainActivity. It should look like this:
MainActivity:
public class MainActivity extends FragmentActivity{
//eg a ArrayList
private ArrayList<MyObjects> mObjectContainer = new ArrayList<MyObject>();
//Do something with the list and fill it
public ArrayList<MyObjects> getObjectContainer(){
return mObjectContainer;
]
public void addObject(MyObject object){
if(!mObjectContainer.contains(object)){
mObjectContainer.add(object);
}
}
}
Fragment:
public class MyFirstFragment extends Fragment{
onCreateView(...){
//make typical Fragment init like create View
ArrayList<MyObjects> list = ((MainActivity)getActivity()).getObjectContainer();
//add a new Object
((MainActivity)getActivity).addObject(new MyObject("any data"));
}
}
Related
In my Android Application I've some objects which represent different kinds of operations.
public class OperacionDivisa implements IOperacion {
public class OperacionLargo implements IOperacion {
public class OperacionMedio implements IOperacion {
public class OperacionOpciones implements IOperacion {
Each kind of operation implements IOperation interface so I can make an ArrayList of IOperations and store all operations in a single ArrayList.
Now I'd like to do the inverse process. I want to get the arraylist of operations from Firebase (which has already been achieved) and I'd like to show the operations in a ListView
I created a custom adapter as follows:
public class ListViewAdapterOperaciones extends ArrayAdapter<IOperacion>
The issue is that I need to cast each object to its original class to show in a textview different attributes. So this is not useful.
IOperacion operacion = (IOperacion) getItem(position);
So, for each object I'd like to show some data in the listView but I haven't been able to figure out how to do this. Any help would be appreciated.
Thanks in advance.
Use an if statement (or similar) to check instanceof, then use the objects as the subclass.
if (operacion instanceof OperacionLargo) {
// Large operation
} else if (operacion instanceof OperacionDivisa) {
// Other operation
}
A network call returns a very large json file. However, I just need to use a small portion of this through out the entire app. What is the best strategy on using a small amount of data for several fragments and activities ?
I tried to use shared preferences, but that does not store objects.
For sharing complex data structures or objects, I would extend Application by making a custom sub class. Application object (as the name implies) is accessible to all Activities, even when app transitions from one to another. Below is a very simple example, just to show you the idea. You can modify/adjust that to your needs.
public class MyApplication extends Application {
private X x;
public static void setX(X x) { ... }
public static X getX() { ... }
}
public class ActivityA extends Activity {
...
MyApplication.setX(x);
}
public class ActivityB extends Activity {
...
X x = MyApplication.getX();
}
X can be a collection, data structure, or any object for that matter.
When extending Application, you need to declare it in the manifest. You can find information on how to do that.
Extract the required data from your JSON as a String and then pass it as an extras parameter to the Activities and Fragments that need it:
Intent intent = new Intent(context, SomeActivity.class);
intent.putExtra("YOUR_DATA_KEY", yourJsonString);
startActivity(intent);
and then extract it back again at the Activities and Fragments that need it:
Intent intent = getIntent();
String yourJsonString= intent.getStringExtra("YOUR_DATA_KEY");
I am trying to do something like that , Firstly , there is a MainActivity which stores courses in ArrayList and these courses are showed by listview.After that , I pass to another activity which is called as ShowDetailActivity with startActivity() to show course details when I click list view element.Then, I pass to another activity which is called EditCourseActivity to edit course which is shown by ShowDetailActivity. The problem is that When I want to edit course , I have to access MainActivity 's Arraylist (private) but I cannot pass with startActivity() because MainActivity did restart (reinstalled) that's why there is no courses on arraylist. The question is How can access from EditCourseActivity to MainActivity 's arraylist to show updated courses ?
Store the course information in a singleton class
public class CourseHolder{
public static CourseHolder instance=null;
public static CourseHolder getInstance(){
if(instance==null){
instance=new CourseHolder();
}
return instance;
}
private Course courses[];
private CourseHolder(){
courses=new Course[10];
}
public void setCourse(int index, Course course){
courses[index]=course;
}
public Course[] getCourses(){
return courses;
}
}
In the EditCourseActivity, after editing, store the updated course information in the copy of CourseHolder
In MainActivity.onResume(), call listView.setAdapter(null), then refresh it with the data inside the CourseHolder
As a generic answer: detach the data from its representation. You can achieve this in many ways:
Singleton wrapper for your array list
To be android specific: wrap your array in a ContentProvider
Use Android SDK SQL database support
I am attempting to build an Android application that has two tabs, one for a textField/button and TreeMenu (where each element has a checkbox associated with it) and another for a list. I am also using an ActionBarSherlock. I have already successfully written the program in a single main activity, but am having difficulty figuring out how to divide this original activity to correspond with the two new fragment instances I need to create for each tab. Moreover, each time an item is added in the first tab (whether it is from being checked off or added to the textField), the list in the second window ought to recognize the update.
To build the action bar I can do this...
ActionBar actionbar = getSupportActionBar();
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionbar.setTitle("AppName");
To create the tabs..
ActionBar.Tab Frag1Tab = actionbar.newTab().setText("InputTab");
ActionBar.Tab Frag2Tab = actionbar.newTab().setText("ListTab");
To create the fragments and its listeners underlying each tab...
Fragment Fragment1 = new Fragment_1();
Fragment Fragment2 = new Fragment_2();
Frag1Tab.setTabListener(new MyTabsListener(Fragment1));
Frag2Tab.setTabListener(new MyTabsListener(Fragment2));
To add them to the action bar...
actionbar.addTab(Frag1Tab);
actionbar.addTab(Frag2Tab);
All of this appears within my MainActivity. I want, for example, an ArrayList variable to be accessible to both Fragments so, like I said, I can update the list. I would love to hear any help you can provide. I would be interested to see how the Otto API could work for something like this, but I am not picky!
In some of the answers there's a suggestion to put the ArrayList in a singleton, but that doesn't really solve your problem does it? Sure, you'll be able to access it from where ever you like, but it doesn't help you keeping two different fragments, both using the arraylist, in sync.
Start by putting the ArrayList in a singleton as suggested or in your MainActivity. Once that is done you have at least two options for keeping the fragments in sync with the content of the ArrayList:
Make the ArrayList Observable (check ObservableArrayList) and let the Fragments Observe the ArrayList for changes.
Make use of an event bus (like Otto) and let the singleton or MainActivity (depending on where you put the ArrayList) post update events on the bus when the arraylist changes and have the Fragments subscribe to the events.
A singleton class could help solve your problem.
public class GlobalApp {
private static GlobalApp instance = new GlobalApp();
private GlobalApp() {}
public static GlobalApp getInstance() {
return instance;
}
public ArrayList < ClassName > varName = new ArrayList < ClassName > ();
}
Then use in your class like this..
GlobalApp.getInstance().varName
I had the same issue a little time ago with an ArrayList and other data. In the end I decided to create a class that extends application and that holds all the global data and can be accessed everywhere from the app. Do you want and example?
As John said, when you want to access data in several activities, just create a class that extends Application:
import android.app.Application;
/**
* Application class used to share data between activities.
* #author Longeanie Christophe
*
*/
public class MyApplication extends Application {
//Put your class members here
#Override
public void onCreate() {
//initialize what's needed here
}
//Getters and setters...
}
In all your activities, you can access this class and its data through this instruction:
MyApplication myApp = (MyApplication) getApplication();
Here you go:
first be sure you declare it in your AndroidManifest:
<application
android:name="com.example.main.ApplicationClass"
etc..>
<!-- other activities, services etc: -->
</application>
and your class:
public class ApplicationClass extends Application {
private static ApplicationClass THIS = null;
ArrayList<String> list = new ArrayList<String>();
public void onCreate() {
super.onCreate();
THIS = this;
}
public static ApplicationClass getThisInstance() {
return THIS;
}
}
How to save List<UserDefinedClass> of between Activity switching ? I get data in onClickView function. Does UserDefinedClass need to implements some interface ?
I believe the best way would be to keep the list in the Application context.
In any of your activitys call yourApp using:
((yourApp)getApplication()).//any public function
public yourApp extends Application{
private List<UserDefinedClass> yourList;
//create functions to manipulate the list example:
public void add(UserDefinedClass a){
//add this to list
}
//finally function to access list
public List<UserDefinedClass> getList(){
return yourList;
}
}
//example:
List<UserDefinedClass> aList = ((yourApp)getApplication()).getList();
It is best to only pass an identifier to the next Activity instead of passing your entire list.
UserDefinedClass should not implement some interface, rather UserDefinedClass should be the class type of the List. In other words, every item in your list should be of UserDefinedClass. That can be a String or even a custom class.
Yes you can pass it if it implements Parcelable. However if its a large amount of data a database or file may work out better for you.