Permanent Objects passed from one Activity to another - java

I must pass an ArrayList from one Activity A to another Activity B.
I did it using getSerializableExtra and putExtra methods. I already know the meaning of these methods, but I don't know if stuff that I passed using them is stored permanently in the new activity or if it is necessary to reload activity A in order to retrieve my data in B.
So the question is: how can I load my data in a initial splash screen and then use it in all my others activity without reloading the splash screen?

Don't use Preference Class! Preferences are only used for settings values. For passing data to another Activity use Serializable or Parcelable. Remember that all the objects which will be passed to another activity have to implement Serializable or Parcelable. So you extend the ArrayList to a custom Class which implements Parcelable or Serializable.
You do this like this:
Intent intent = new Intent(getContext(), SomeClass.class);
intent.putSerializableExtra("value", <your serializable object>);
startActivity(intent);
and receive them like
YourObject yourObject = getIntent().getSerializableExtra("value")
or look here for Parcelable
Help with passing ArrayList and parcelable Activity
Data processed in Activity A does not need to process again in Activity B. If the data is computed in A and you send it to B computed, B receives it computed already.
Here are some ways to do it right: http://developer.android.com/guide/topics/data/data-storage.html

You can use Preference class, in which you can define its static instance. Than create variable according your desire datatype (even ArrayList). Make property for get and set of this variable.
Set the value on splash screen and get anywhere in application where you need.
Try this, if you need , I will upload code also.

I have written some code regarding that, it would help other activities to fetch data easily, use this when the data is not confidential,
public class HelperShared {
public static final String score = "Score";
public static final String tag_User_Machine = "tag_User_Machine",
tag_Machine_Machine = "tag_Machine_Machine",
tag_Draw_Machine = "tag_Draw_Machine",
tag_Total_Machine = "tag_Total_Machine";
public static SharedPreferences preferences;
public static Editor editor;
public HelperShared(Context context) {
this.preferences = context.getSharedPreferences(score,
Activity.MODE_PRIVATE);
this.editor = preferences.edit();
}
/*
* Getter and Setter methods for Machine
*/
public void setUserMachine(int UserMachine) {
editor.putInt(tag_User_Machine, UserMachine);
editor.commit();
}
public void setMachineMachine(int MachineMachine) {
editor.putInt(tag_Machine_Machine, MachineMachine);
editor.commit();
}
public void setDrawMachine(int DrawMachine) {
editor.putInt(tag_Draw_Machine, DrawMachine);
editor.commit();
}
public void setTotalMachine(int TotalMachine) {
editor.putInt(tag_Total_Machine, TotalMachine);
editor.commit();
}
public int getUserMachine() {
return preferences.getInt(tag_User_Machine, 0);
}
public int getMachineMachine() {
return preferences.getInt(tag_Machine_Machine, 0);
}
public int getDrawMachine() {
return preferences.getInt(tag_Draw_Machine, 0);
}
public int getTotalMachine() {
return preferences.getInt(tag_Total_Machine, 0);
}
}

if your question is "how can I load my data in a initial splash screen and then use it in all my others activity without reloading the splash screen?" Than I have better solutions for you.
Create a Class Memdata.java
public class Memdata{
private static Memdata instance = null;
private String userobject;
public static Memdata getInstance(){
if ( instance == null){
instance = new Memdata();
}
return instance;
}
public String getuserobject() {
return userobject;
}
public void setuserobject(String userobject) {
this.userobject= userobject;
}
}
on You Splash Screen' onCreate method, set the value
Memdata obj = Memdata.getInstance();
obj.setuserobject("hello");
Than in any activity, where you want to access this variable, just make its object and get value.
Like in MyActivity class
Memdata obj = Memdata.getInstance();
String str = obj.getuserobject()
You can define any type of variable according your requirement.

You can extend the base Application class and add member variables to it:
public class MyApp extends Application {
private String appLevelString;
public String getAppLevelString() {
return this.appLevelString;
}
public void setAppLevelString(String val) {
this.appLevelString= val;
}
}
You will have to update the manifest file as follows:
<application android:icon="#drawable/icon"
android:label="#string/app_name"
android:name="MyApp">
You can get and set data like this:
//For setting
((MyApp) this.getApplication()).setAppLevelString("Test string");
//For getting
String str = ((MyApp) this.getApplication()).getAppLevelString();

Related

How to use SharedPreferences to save and read from a Class

I want to use the SharedPreferences in a Class that has no Activity. I have wrote this code but im still getting an error. Can you help me out please?
package com.example.keypass;
import android.content.Context;
import android.content.SharedPreferences;
public class test {
SharedPreferences sharedPreferences;
public void loadInt(){
sharedPreferences = this.getSharedPreferences("com.example.keypass",Context.MODE_PRIVATE);
int usrPassword = sharedPreferences.getInt("meinInteger", 0);
}
}
If I use the same code in a Class with Activity it works. But in this class is not working.
Here Maybe this help
Its a good practice making separate class file for shared prefrence
first, create a file(class) name Constants.java
public class Constants {
static Constants _instance;
Context context;
SharedPreferences sharedPref;
SharedPreferences.Editor sharedPrefEditor;
public static Constants instance(Context context) {
if (_instance == null) {
_instance = new Constants();
_instance.configSessionUtils(context);
}
return _instance;
}
public static Constants instance() {
return _instance;
}
public void configSessionUtils(Context context) {
this.context = context;
sharedPref = context.getSharedPreferences("AppPreferences", Activity.MODE_PRIVATE);
sharedPrefEditor = sharedPref.edit();
}
public void storeValueString(String key, String value) {
sharedPrefEditor.putString(key, value);
sharedPrefEditor.commit();
}
public String fetchValueString(String key) {
return sharedPref.getString(key, null);
}
}
The above code will generate an XML file inside your phone with the name AppPreferences
where you can store value in key-value pair
Now go to an activity where you want to access shared preference
Constants.instance(this.getApplicationContext());
Now when you want to store inside shared preference use like that
Constants.instance().storeValueString("companyKey", "Brainwash Inc.");
now when you want to fetch data from shared prefrence
String companyName = (Constants.instance().fetchValueString("companyKey"));
Note Its for Activity if you want to use inside fragments use getactivity() instead of getapplicationcontext()
To be able to use shared preference in a class, you have to pass in the context. You can try to add a constructor with the context parameter in it and call this class inside the activity you want.

How can I add methods that I often use to android studio?

For example,
public void show_message(String message){
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
I want this method add auto Activity.java when create new activity or java class.
I want to save different methods like this and include it in the my project quickly where it is needed.
What you should do is create a BaseActivity and make your activity extend this BaseActivity. Add all the default methods in this activity so you can use them everywhere. You can refer this Github project for reference. It uses MVP.
Here is direct link to BaseActivity.
You just need to make a Common Utilities class. Just copy and paste the class in whatever project you are using it. Just make its method access specifiers as public staic so that you can easily access it.
For e.g.
CommonUtilities.showToastMessage(String text);
What I would do is create a config class and store all these small things in it. For example have a look at this :
public class Config {
public Context context;
public String sharedPrefsName;
public String carTablesName, carsTableCarColumn, databaseName;
public int databaseNewVersion, databaseOldVersion;
public boolean showNotificationsToCustomer;
public String customerNotificationState;
public String userMobile;
public SharedPreferences preferences;
public String customerChatTableName;
public String customerChatMessageColumn;
public String customerChatSentByCustomerColumn;
public String customerChatTimeColumn;
public String loggedInUserId;
public String loggedInUserName;
public String customerChatSupportNotifyingUrl;
public Config(Context context) {
this.context = context;
customerChatSupportNotifyingUrl = "";
customerChatTableName = "customerChat";
customerChatMessageColumn = "customerMessage";
customerChatTimeColumn = "sentOn";
customerChatSentByCustomerColumn = "isSentByCustomer";
sharedPrefsName = context.getString(R.string.shared_prefs_login_validator);
preferences = context.getSharedPreferences(sharedPrefsName, Context.MODE_PRIVATE);
customerNotificationState = context.getString(R.string.customer_notification_state);
showNotificationsToCustomer = preferences.getBoolean(customerNotificationState, true);
carTablesName = context.getString(R.string.user_car_table);
carsTableCarColumn = context.getString(R.string.user_car_table_car_column);
databaseName = context.getString(R.string.user_db);
databaseNewVersion = 3;
databaseOldVersion = 1;
loggedInUserId = preferences.getString(context.getString(R.string.user_db), "");
userMobile = preferences.getString(context.getString(R.string.user_mobile), "");
loggedInUserName = preferences.getString(context.getString(R.string.user_name), "");
}
}
I've placed all the constants in a single file so you need not look at them always. If your app grows in size this would be extremely useful.
For using a progress dialog I use a class like this :
public class MyProgressDialog extends ProgressDialog {
String title, message;
public MyProgressDialog(Context context, String title, String message) {
super(context);
if (!title.equals("")) this.setTitle(title);
this.setMessage(message);
this.setCancelable(false);
this.setIndeterminate(false);
}
}
This is nothing but a single class that extends ProgressDialog.So you can aquire all the functionalities of the progress dialog class.
Similarly for toast you could do the same. If you want them to appear when the activity gets created simply keep this:
MyProgressDialog dialog=new MyProgressDialog(this,"title","message");
dialog.show();
in your activity's onCreate() method. You can do the same for toast too.
In case if it is a java class just create a constructor and keep that snippet in that constructor..
You need to read about "File Templates" https://riggaroo.co.za/custom-file-templates-android-studio/ this a large topic, but this is worth it.

Calling external methods without instantiating an object

I was wondering if it was possible to call the methods of an external class without actually having to declare an object of that class. They way I've got it set up causes the ArrayList stored within the object empties every time the method the object is used in is called.
If I can call the method without an object, then I can fix my problem.
Thanks in advance.
calling class:
public class BookingScreen extends Activity {
GAClass sendApplication = new GAClass();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_booking_screen);
}
public void saveBookingInfo(View view) {
EditText applicantNameText = (EditText) findViewById(R.id.applicantNameTextField);
EditText itemToBurnText = (EditText) findViewById(R.id.itemToBurnTextField);
String appName = applicantNameText.getText().toString();
String appItemToBurn = itemToBurnText.getText().toString();
if (appItemToBurn.isEmpty() || appName.isEmpty()) {
Toast.makeText(BookingScreen.this, "Please fill in all fields.", Toast.LENGTH_SHORT).show();
}
else {
sendApplication.storeApplication(appName, appItemToBurn);
this.finish();
}
}
External method class:
public class GAClass {
ArrayList<Application> peopleAttending;
public void storeApplication(String name, String item){
peopleAttending = new ArrayList<>(10);
peopleAttending.add(new Application(name, item));
}
}
You can do something like below
public class GAClass {
public static ArrayList<Application> peopleAttending=null;
public static void storeApplication(String name, String item){
if(null==peopleAttending){
peopleAttending = new ArrayList();
}
peopleAttending.add(new Application(name, item));
}
}
You can invoke above method like below
GAClass.storeApplication(str_name,str_item);
when you make peopleAttending arraylist static it can be access in static method and
if(null==peopleAttending){
peopleAttending = new ArrayList();
}
Above code ensure first time initialization if peopleAttending 9s null
Use static methods. You can call a static method without creating object of enclosing class.
https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
What exactly are you trying to achieve?
The static methods in a class would not need an instance of the class so you can make the methods you need (that do not require the state of the object - i.e. do not need a particular object to work on) static and call them like this:
ClassWithStaticMethods.staticMethod() ;

Getters returning null

I know why my problem is occurring but i'm unsure on how to deal with it.
So I have 3 classes, 1 of these holds my getters & setters. In one class I am setting the values, in the other I am getting the values. When I get the values they are returned null. This is obviously because the two instances of the getter/setter object I created in the classes are separate from one another. What i'm trying to find out is how I can set the values in one class and get them in another without having two separate instances of the getter/setter class. My wording is terrible so here's a more visual explanation:
Class 1
Encapsulation encap = new Encapsulation();
encap.setValue(10);
Class 2
Encapsulation encap = new Encapsulation();
encap.getValue(); //I want this to return 10
Class 3 (Encapsulation)
private int value;
public void setValue(int value){
this.value = value;
}
public int getValue(){
return value
}
In Class2, you are creating a new instance of class Encapsulation. (Notice new Encapsulation()). So obviously, that won't hold the values.
Instead, I would suggest you two solutions:
First:
Save that object in an Application class as you are working on Android application.
public class TestApplication extends Application {
public Encapsulation tempClass;
public TestApplication () {
// TODO Auto-generated constructor stub
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
public Encapsulation getTempClass() {
return tempClass;
}
public void setTempClass(Encapsulation tempClass) {
this.tempClass = tempClass;
}
}
Now in your Activity:
//after setContentView
testAppObj = (TestApplication) getApplication();
testAppObj.setTempClass(myTempClassObj);
//retrieve as:
Encapsulation obj = testAppObj.getTempClass();
You must register your Application class in your manifest file just like you register your activities:
<application
android:name="com.pkg.test.TestApplication " />
Second:
Keep object encap as static in Class1. So you can access it from calss2. (I don't prefer static.)
Hope it helps.
Make value static, it will keep the same value across all Encapsulation instances
private static int value;
public void setValue(int aValue){
value = aValue;
}
public int getValue(){
return value;
}
Just declare an object of the Encapsulation class once,and use the same instance to call the getter and setter.
Like this:
Encapsulation encap = new Encapsulation();
encap.setValue(10);
encap.getValue();
It works.

Creating a SharedPreferencesUtil

This is my first time using SharedPreferences in my Android app. Since I will be using the SharedPreferences over and over again, I have created a utility class called SharedPreferencesUtil which contains a lot of static methods which allow me to access and modify the values. For example:
/**
* This method is used to add an event that the user
* is looking forward to. We use the objectId of a ParseObject
* because every object has a unique ID which helps to identify the
* event.
* #param objectId The id of the ParseObject that represents the event
*/
public static void addEventId(String objectId){
assert context != null;
prefs = context.getSharedPreferences(Fields.SHARED_PREFS_FILE, 0);
// Get a reference to the already existing set of objectIds (events)
Set<String> myEvents = prefs.getStringSet(Fields.MY_EVENTS, new HashSet<String>());
myEvents.add(objectId);
SharedPreferences.Editor editor = prefs.edit();
editor.putStringSet(Fields.MY_EVENTS, myEvents);
editor.commit();
}
I have a few of questions:
1. Is it a good decision to have a utility class SharedPreferencesUtil ?
2. Is the use of assert proper?
3. Is that how I will add a String to the set?
In general I think utility classes like this are fine. A few recommendations I'd have are:
Initialize your Context in a subclass of Application (in Application.onCreate()) and store a reference to that in your utility class. You don't have to worry about a memory leak if you ensure you only use the application context instead of an Activity context, and since SharedPreferences doesn't use any theme attributes, there's no need to use an Activity context anyway.
Check and throw an exception warning that the class hasn't been initialized yet if you try to use it without initialization. This way you don't need to worry about checking for a null context. I'll show an example below.
public final class Preferences {
private static Context sContext;
private Preferences() {
throw new AssertionError("Utility class; do not instantiate.");
}
/**
* Used to initialize a context for this utility class. Recommended
* use is to initialize this in a subclass of Application in onCreate()
*
* #param context a context for resolving SharedPreferences; this
* will be weakened to use the Application context
*/
public static void initialize(Context context) {
sContext = context.getApplicationContext();
}
private static void ensureContext() {
if (sContext == null) {
throw new IllegalStateException("Must call initialize(Context) before using methods in this class.");
}
}
private static SharedPreferences getPreferences() {
ensureContext();
return sContext.getSharedPreferences(SHARED_PREFS_FILE, 0);
}
private static SharedPreferences.Editor getEditor() {
return getPreferences().edit();
}
public static void addEventId(String eventId) {
final Set<String> events = getPreferences().getStringSet(MY_EVENTS, new HashSet<String>());
if (events.add(eventId)) {
// Only update the set if it was modified
getEditor().putStringSet(MY_EVENTS, events).apply();
}
}
public static Set<String> getEventIds() {
return getPreferences().getStringSet(MY_EVENTS, new HashSet<String>());
}
}
Basically, this avoids you having to always have a Context on hand to use SharedPreferences. Instead, it always retains a reference to the application context (provided you initialize it in Application.onCreate()).
You can check out how to use SharedPreferences properly here and check another example on the Android docs.
EDIT: As to your design question, it really shouldn't matter to have a static class or not.
Your SharedPreferences are shared throughout the app, and although you can create multiple SharedPreferences objects, they will essentially store and save to the same part of your app as if you just used one object.

Categories

Resources