Using an object of one class in many other classes - android

I am making an android app. I have a User class which has many getters and setters.
I have many activities in my app and by just creating a single object of User class I want to access that object from many activities.
How can I do that?
Thank you for the answer. But the scenario is like this. I have a database and in there is a table user which contains all the information about the user registration like name,age, password, emailID, last logged in etc. Each of these fields are there in the user class. Now my first activity is for accepting the terms and conditions page. If the user accepts it then I want to update that particular column in the database table. Then in next activity user registration will happen. Then I need to store that data in the database table. So in the same row all that data has to be inserted in the database. How will this be done

Try using singleton:
class User {
private static User sInstance;
private User() {
}
public static User getInstance() {
if(sInstance == null) {
sInstance = new User();
}
return sInstance;
}
// ... other methods
}
In activities:
User.getInstance().doSomething();
More here: https://stackoverflow.com/a/16518088/1979756
UPDATE:
If you are using db, look at SQLiteOpenHelper. Extend it and manage all data there. Also, you can use some libs to manage your db data: ormLite, greenDAO, realm, etc. You can find a lot of info about them on SO.

Related

Is it possible to partial update a RealmObject

My app gets it data from a REST API.
Depending on the endpoint I get list of complete or partial Account.
When the API responds I call realm.copyToRealmOrUpdate(accounts).
My problem is that if a complete account is already stored in realm and the same partial account but where relation_tx, relation_rx, message_last_rx, message_last_tx are null is in the accounts list, the complete account is overriden completely.
I only want realm to update fields which are not null.
Any suggestions?
Any way I can override the Account.update() method?
#RealmClass
public class Account extends RealmObject {
public String timestamp;
#PrimaryKey
public long id;
public String name;
public String email;
public Relation relation_tx;
public Relation relation_rx;
public Message message_last_rx;
public Message message_last_tx;
}
I think you'll have to manually compare. Don't call realm.copyToRealmOrUpdate(accounts) with the content from the server.
Instead, name your server response serverAccounts. For every account in it: get the account (localAccount) with this id from Realm. If not found (null): add the serverAccount to the DB. If found: update your four fields manually on the localAccount and save the localAccount to the DB.
To optimize the above, you might want to do a single Realm query with a list of ids (from the serverAccounts) and save your changes in one batch to Realm as well.

RealmResult as RealmObject field

I'm trying to figure out the best way to set up a RealmObject with a RealmResult as one of its fields.
For example, let's say I have two RealmObjects, Goal and Achievement. The Goal object contains fields that define a query of Achievement's the user wants to track (e.g. date range the achievement was created, type of achievement, etc) and has custom methods to extract statistics from those Achievements.
What is the best way for Goal to contain this RealmResult of Achievements? Here are some ways I've thought of doing this:
Have a persisted RealmList field in Goal and update it anytime a field is changed that would change the resulting query. But how would this RealmList get updated if a new Achievement gets added to the realm?
Use #Ignore annotation on a RealmResult<Achievement> field within Goal. Anywhere in Goal where mResult is used, first check if null and requery if needed. This seems like I will be doing a lot of unneccessary querying if I'm using something like a RecyclerView that refetches the object in getItem().
Have a wrapper class that contains a Goal object and the RealmResult<Achievement> as fields. Add a listener to Goal so that anytime a relevant field changes the RealmResult can be requeried.
I'm leaning towards the last one as the cleanest way to keep a valid RealmResult. Am I missing an easier way to accomplish this?
Okay so I'm trying to implement a wrapper class (which I think is similar to the DAO abstraction #EpicPandaForce was mentioning, but I'm not super familiar with that)
public class GoalWrapper {
private RealmResults<Achievements> mResults;
private Goal mGoal;
private Realm mRealm;
public GoalWrapper(Realm realm, Goal goal) {
mRealm = realm;
mGoal = goal;
// TODO: does this need to be removed somewhere? What happens when GoalWrapper gets GC'd?
goal.addChangeListener(new RealmChangeListener<RealmModel>() {
#Override
public void onChange(RealmModel element) {
// rerun the query
findResultForGoal();
}
});
findResultForGoal();
}
/**
* Run a query for the given goal and calculate the result
*/
private void findResultForGoal() {
mResults = mRealm.where(Achievement.class)
.greaterThanOrEqualTo("date", mGoal.getStartDate())
.lessThanOrEqualTo("date", mGoal.getEndDate())
.equalTo("type", mGoal.getAchievementType())
.findAll();
calculateStats();
}
private void calculateStats() {
// Get relevant stats from mResult...
}
}
I haven't tested this code yet but I plan to have a RecyclerView.Adapter with an ArrayList of GoalWrapper objects.
My one concern is that I never remove the listener on mGoal. Do I even need to remove it? What happens in the case that the ArrayList gets GC'ed? I would think that the Goal field and resulting listeners attached to it all get GC'ed as well.

Using a Singleton for Current logged in user of mobile app

Is creating a Singleton to keep track of the current logged in user of a mobile app a bad idea? The class below is something along the lines of what I've used before and it works fine, but I always feel it's not the best way of doing things.
public class LoggedInUser {
private static LoggedInUser ourInstance = null;
User user;
public static LoggedInUser getInstance() {
return ourInstance != null ? ourInstance : new LoggedInUser();
}
private LoggedInUser () {
user = new User();
}
public void setUser(User user) {
this.user = user;
}
public User getUser() {
return this.user;
}
}
I use the info of the user pretty often throughout the app, and sometimes the User object isn't trivially small so passing the object between each view doesn't sound like the best option either. What is normal practice for this?
The user has to log in every time they use the app, so I also don't want to write the information to the phone necessarily.
I have found a similar question (Is Singleton the best way to keep data in memory on an Android application?) and the answer posted by charlag is actually pretty mature:
I would use the following: Interface CurrentUser. CurrentUser has methods to retrieve and update user. User may be stored in DB, preferences or mixed. I would use Dagger to inject CurrentUser when needed. CurrentUser implementation should itself be a singleton, because Dagger doesn't guarantee qualities of singleton. Bonus points if your CurrentUser has something like RxJava stream or LiveData to keep observers up-to-date.
As an alternative to Singleton you may want to implement Fragment
Holder pattern with retained fragments but in your situation Singleton
seems better. Just make sure that you use interfaces and injection to
not compromise testability and to keep your components separated.
Do not fall into keeping your objects within the App class, unless it is crucial to instantiate your app's dependencies correctly - it sounds nice and easy, but can also get out of control pretty quick.
Singleton is normal.
But you can always use Application class and its variables (both static and object) to store the data.
public class MyApp extends Application {
public static LoggedInUser user;
#Override
public void onCreate() {
super.onCreate();
user = LoggedInUser.getInstance();
//...
}
//or even
public LoggedInUser user_obj;
}
AndroidManifest.xml:
<application
android:allowBackup="true"
android:largeHeap="true"
android:name=".MyApp"
android:icon="#drawable/iconlite"
android:label="#string/app_alias"
android:theme="#style/AppTheme" >
somewhere in the code use MyApp.user or ((MyApp)getApplication()).user_obj

OrmLite inside an Android Module

I'm trying to put all the DatabaseRequests inside a module in Android to centralize all the acces to DDBB in the same place.
I'm wondering if I'm making any mistake doing that. The apps works in the right way but I'm concerned about best practices doing that.
I have an static class called DatabaseRequest where all the requests are inside, for instance:
public static void insertUser(Context context, User user) {
DataBaseHelper mDataBaseHelper = OpenHelperManager.getHelper(context, DataBaseHelper.class);
try {
Dao<User, Integer> dao = mDataBaseHelper.getUserDao();
dao.createOrUpdate(user);
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (mDataBaseHelper != null) {
OpenHelperManager.releaseHelper();
}
}
}
The context param is the context of the activity that's making the request.
Is there any performance issue related with this code?
Thanks in advance ;)
No, as Gray (ORMlite creator) said in this post:
is it ok to create ORMLite database helper in Application class?
What is most important with your code is that it guarantees a single
databaseHelper instance. Each instance has it's own connection to the
database and problems happen when there are more than one (1)
connection opened to the database in a program. Sqlite handles
multiple threads using the same connection at the same time but it
doesn't handle multiple connections well and data inconsistencies may
occur.
And in your case you may have multiple connections at one time.
I can preset you my approach on how I'm using ORMlite, I have one singleton class public class DbHelper extends OrmLiteSqliteOpenHelper which takes care of creating database connection and holds all Dao fields. You will have database upgrade code there and some other stuff so consider making facade classes. In my case each facade holds one Dao object for one model class, where i keep logic for complex item retrieving (and for simple cases i just delegate it to Dao object.

General Android Advice: Global Variables

I was wondering what is the best way to handle global variables for android apps. For example, I'm just trying to create a basic login/register system. I've created a user class (that has various attributes like username, password, etc..), so that when we go to the register activity, the User class constructor is called to create a unique user object once all the fields are filled out. I was then thinking of simply having a global arrayList of type User so that I could just loop through all the users on a login attempt.
So far (due to a combined lack of experience in java, and being very new to this android stuff), I haven't been able to implement this successfully. I have a class which I call "globalStuff" which has a bunch of public static variables (i.e. the list of users and current user), which I thought could be accessed from any activity the user navigates to.
There must be a better way to go about this. I've been reading through a few tutorials and a few posts on here, but none address this very basic idea. So what would be the best way to approach something like this?
Thanks for any help!
It's called a static singleton and it looks like this:
public class Global {
private static Global instance = null;
public static Global getInstance() {
if( instance == null )
instance = new Global();
return instance;
}
// additional methods, members, etc...
}
Then you just refer to it in your code as:
Global.getInstance().getUserList();
etc.

Categories

Resources