I am working on database for a game.
I would like to get the score from one activity and call it in database activity, where it will be updated in the database by using intent, the game gets paused when intent is fired.
I have also tried using application class (suggestions on that are welcome).
Is there any way to pass data among activities by firing intent in background so that it does not interrupt the gameplay?
Your database should not be in an Activity. An Activity represents one screen (or one use-case) in your application, and should not represent implementation details like a database-class.
As an alternative, you can put your database code in a Singleton class that can be accessed from everywhere in the same application. You can also create the database in the Application's onCreate method and store it in a static field there or just create a separate class that exposes static methods to access the database.
If you are somehow dead-set on using Intents, you would need to use a database Service instead of an Activity. This way the current Activity will remain on top when you send the data to the service. But that would complicate things a lot compared to a simple static class/singleton approach.
You seem to have a big mix up: There shouldn't be a database activity. You should create a database helper class and make it a member variable in your application class.
// inside application class
private static MyDatabaseHelper mMyDB;
public MyDatabaseHelper static getDatabase() {
if (mMyDB == null) {
// mInstance should be the application instance, means make the
// application class a singleton
mMyDB = new MyDatabaseHelper(mInstance);
// the constructor should open/create the database
}
return mMyDB;
}
With this you can work with your database from everywhere.
With that you can easily update every value from everywhere. So no need to fire an intent to pass values around. Instead just update your database directly.
There are multiple ways to this.
You can use handlers, services, then use setresult which give call back to onactivity result of the parent activity.
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
Bundle b = new Bundle();
b.putInt("key", 1);
intent.putExtras(b);
startActivity(intent);
Related
Lets say I have 10 activities in backstack. How can a change in some 10th activity in the backstack(which is an instance of activity A) will trigger a change in 2nd activity in the backstack(which is also an instance of activity A).
The reason I cannot use StartActivityForResult is that the change might occur in the nth activity. I cannot just keep on sending the data backwards using onActivityResult.
Also I cannot use static data because of no.of instances of the same Activity.
Actual Scenario:
Take the case of twitter, where I have my followers list with an option to follow the users in the list and I can select one person, go to his followers list where I will see a follow option for every user and so on.
So, if I follow a user on some 10th list in the backstack, how will that get reflected in the 1st list which contains the same user? I mean it must change from follow to following.
You should be storing your data somehow that is separate from the Activity. Typically this is done in via the sqlite database. The basic idea is when the use performs an action that you wish to record you save it somehow. More than likely in a database. Now that data is stored and accessible.
The next step is how to display updated data in an Activity. This is typically done in Activity#onResume(). In onResume you would perform some actions that can retrieve the stored data and then update your display. startActivityForResult is used more or less for what its name implies. Starting another Activity with the intent of the callee providing the caller some data. It is not used to try to send data and state through the Activity stack.
If you don't want to use startActivityForResult then you need create static instance of each activity to make it accessible from any other activity.eg:-
public class xyz extends Activity
{
private static xyz instance;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
................
................
instance = this;
}
public static xyz getInstance(){
return instance;
}
}
I have 2 activities (ActivityA and ActivityB)
In ActivityA i'm creating a new Object Game which has an ArrayList inside
Game game = new Game();
I start ActivityB
public void startActivityB(View view){
Intent i = new Intent(this,ActivityB.class);
i.putExtra("Game", game);
startActivity(i);
}
In activity B I get the object, access to they ArrayList and delete some elements. (I check the ArrayList before and after deleting, and they were successfully deleted)
The problem is that when i finish the ActivityB, and start it again, the deleted elements are still on the ArrayList.
You should start activity B with startActivityForResult, and pass back to ActiviyA the modified ArrayList through onActivityResult
That is because you are editing two different instances of a duplicated object. Consider making it static in Activity A and accessing it directly in Activity B.
OR
Consider an MVC structure for your app. You should really not be passing multiple versions of large amount of data across activities. Standardize the way in which you access and modify the data.
My app contains 2 activitys. Activity A is the one which is created by starting the app. In this one I create an object of my own class MyClass. This class contains one string and 3 integers. In activity A this object gets written.
The second activity B needs to read this object. How can I pass it from A to B? Or is there an other solution?
There are couple of way you can pass an object from one activity to another:
1. Application Class: this class is visible to all your application Activities so you can save your object in this class from one Activity and then access it from the other.
2. You can break apart your Class into the simple variables: string and 3 integers and pass them via a bundle or the intent it self from one activity to another, then construct your object again.
Intent intent = new Intent (this, TargetActivity.class);
intent.putExtra(KEY, value);
intent.putExtra(KEY, "value");
startActivity(intent);
3. If your object implements Serializable/Parcelable then you can pass it via a bundle.
Example on how to serialize an object:
How do I serialize an object and save it to a file in Android?
One option could be implementing Serializable interface and then you can pass object instances in intent extra using putExtra(Serializable..) variant of the Intent#putExtra() method.
//to pass :
intent.putExtra("MyClass", obj);
// to retrieve object in second Activity
getIntent().getSerializableExtra("MyClass");
It can be tricky, because there's no guarantee that your application can't be killed between activities. Actually, it can be killed during activities, so keeping persistent objects around can be tricky.
My preferred way to do this is the "singleton pattern" in which you create a class whose purpose is to create a single instance that holds whatever data you want to hang around. If your application gets killed, the singleton instance will be lost and have to be re-created, but all Android apps run this risk all the time anyway.
See Save multiple instances states of the same Activity in Android for my implementation of a singleton in Android.
Oh, and I should add that this only works within an application where all the activities are in the same process, sharing the same address space. Otherwise, you'll have to make your object serialiazable and write it off to a file.
What is the purpose of using an intent with a message instead of just declaring a static variable in java and calling it from the new activity? It seems easier to me this way because you can have the static variable be anything you want (i.e. ArrayList, Object, etc.).
public class FirstActivity extends Activity {
public static String name;
...
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
name = "Robert";
startActivity(intent);
}
public class SecondActivity extends Activity {
...
textView.setText(FirstActivity.name);
}
By using extras to start SecondActivity, you make it more reusable. Many of the stock activities work this way, that's why you can reuse for example the camera activity to take and save photos, because it does not make assumptions about who is calling it.
In your case SecondActivity depends on FirstActivity having been loaded in the JVM. I would not count on that, and it's certainly not a recommended practice to have such dependency between activities. Don't do this. Use extras to pass values between activities, as recommended by the SDK.
To clarify, the OP's strategy won't work if another app outside of his/hers wants to handle the Intent. Because of this, it's not a "best practice".
There are roughly 30 different putExtra variations for an Intent, each representing a different data type you can add. They include general purpose data types such as Bundle, Parcelable, Serializable, and so forth. I can't think offhand of anything that these don't cover.
I don't use statics or variables defined by overriding Application or other similar ways of assuming that some data is floating about in storage. It's much more robust to assume that my Activity or Fragment is totally independent.
Using Intent make you slower than static
For example if you use mvp or mvvm
At least you have to pass like id through layer by later
I noticed that most programmers in Android use an Intent or broadcast receiver to send a short text message from one class to another class.
If I am using a utility class that does not extend any other class like Activity or Service, why not just directly access the variable in the utility class like this.
UtilityClass utility = new UtilityClass();
String gotIt = utility.theOtherVariable; // direct access to variable in other class
is there anything wrong with doing it this way? I would rather do this than use an intent or broadcast receiver to send the small text message from the utility class to the Activity class.
EDIT
in addition to the instance of the class, you can also make the variable static that your are passing from one activity to another. in either case I don't see any value to using an extra of intent or broadcast receiver to pass information from one Activity to another.
Yes of-course you can use that And even it is good practice that you are using your own data structure but it is depend on need and scenario.
For example suppose you are receiving data from gps and you need that data in your app at some 5-6 places then its good to design one class and store the gps data in the variable of the class and access it where ever you want in your ways
Yes of course its good thing to make public class and keep your where Variable and Function as publicly so you can use in further activity.But that you all ready know that this type of function and variable will be use in some activity.
Where Intent is like Good and easy way to switching data one activity to anther activity.like if you don't want to use some variable more then single next activity then it will useful. More Impotent use of Intent is Return activity Result. like if you want to perform action but its depend on next activity then Intent will use as powerful tool to achieve your task.
Short and Sweet : It's Depend on Requirement.
Try this,
UtilityClass utility = new UtilityClass();
Initialized Utilityclass in Your Activity.Use Utilityclass object you will get all values in your utliityclass.
Example,
public class UtilityClass{
public static string gotIt = "value";
}
public class MainActivity extends Activity {
UtilityClass utility = new UtilityClass();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.xml);
String str = utility.gotIt;
}