In my app I have 5 String arrays that represent different fields of objects.
i.e.
String_A[1],
String_B[1],
String_C[1],
String_D[1],
String_E[1],
All are attributes of the same object (which is not really an object).
Now I want to store those in order to be able to use them in a new activity that I am creating. Since you are not able to pass objects around I thought that i should save them in Shared preferences.
My question is: Should I save them as separate strings or create a new class with all those fields and then serialize the objects?
Which is the best way in terms of memory usage? In fact is there any other way that you might achieve similar functionality?
Thanks in advance
Mike
If each of those String Arrays are big "enough" and it appears you do want to store them - have you considered Sqlite? SharedPreferences is most effective to store primitive data in key-value pairs. Check this link - it has neat comparison about the options you have - http://developer.android.com/guide/topics/data/data-storage.html
You can pass around objects via an intent. The extras function of an intent can store a bundle and send it to specified activities, however they cannot be called at any time (like from a later activity without being explicitly sent). If this is a one time pass to a different activity, the you'd probably want to use that.
http://developer.android.com/reference/android/content/Intent.html#putExtras%28android.content.Intent%29
Here is an example from a test app I made a while back:
public void onClick(View v) {
switch(v.getId()) { //this references the unique ID of the view that was clicked
case R.id.Button01: //this is what happens when the Button in the XML with android:id="#+id/Button01" is clicked
Intent nameGreet = new Intent(this, MainMenu.class);//creates Intent which will send the EditText input
String theName = firstName.getText().toString();// creates a new string named "theName" which is the text from an EditText called "firstName"
nameGreet.putExtra("helloName", theName);//puts the input from EditText into the Intent, this is a key/value pair
this.startActivity(nameGreet);//setting off the Intent
break;
Then you catch it like so:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main_menu);
String personsname = this.getIntent().getStringExtra("helloName");
welcome = (TextView)this.findViewById(R.id.TextView01);
welcome.setText(personsname);
Hope this helps.
You can pass a Serializable using an Intent.
Intent.putExtra(String name, Serializable value).
Related
Intent myIntent = new Intent(this,Q1.class);
In my app I have 1000 different activities namely Q1,Q2,Q3....Q1000.
I have a button on each activity and I want when a user clicks on it, he should land on some random activity.
How to achieve this ?
Although this is terrible, I'll still show a possible way to do this. But just remember, this is TERRIBLE.
You can store all the activity classes in an ArrayList.
ArrayList<Class<Activity>> activities = new ArrayList<> ();
And then you add all the activities into the ArrayList. Yeah, I know, this part is tedious. For example,
activities.add (Activity1.class);
And then you create a Random called rand and use that to access an element in the list:
list.get (rand.nextInt (list.size()));
Here is another "better" way to do it, but it's still kinda bad. I strongly advise you to store teh questions in a database. Anyway, here's the better-but-still-bad method.
You create a question class:
public class Question {
//here you can put correctAnswer, questionText etc
}
After that, you make an ArrayList of Questions i.e. ArrayList<Question>.
ArrayList<Question> questions = new ArrayList<> ();
And still, you need to add 1000 questions to the array list. Then you can just use a Random to access it.
When you want to display a question in one activity, you can just putExtra in Intent before starting the activity. putExtra basically passes some "parameter" thingys to the activity. Then in the activity, you can just get the "Extra" and use the Question object to display. e.g. set the text of a TextView to the question text.
this can be also used:
try {
Random rand=new Random();
Intent i = new Intent(this, Class.forName("test.hu.test.Q"+rand.nextInt(1000)+"")); // get activity's class by reflection
startActivity(i);
}catch (Exception e)
{
}
But i also suggest to use DB.
This is a real noob question I'm sure, but I am finding it quite perplexing.
Why an earth would you want to ever use intent.putExtra method to share information between classes in Android?
Let me explain. I am making my first Android app following the instructions from the developers guide (I am already at a moderate level with Java) and I am using some code that looks like this:
//Class field
//key holds string????? not fully understanding this...
public static final String EXTRA_MESSAGE = "self.anon.myfirstapp.MESSAGE";
//this method is activated by a button being pressed
public void sendMessage(View view) {
Intent intent = new Intent(this,DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
//puts string message inside the string EXTRA_MESSAGE - why????
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
OK firstly I want to point out I see what is happening and for the most part how it works (am just confused by the field declaration = "myClassPath" why?)...
BUT....
Surely it would be easier just to have a static field called:
public static String message;
then my method would look like this:
public void sendMessage(View view) {
Intent intent = new Intent(this,DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
message = editText.getText().toString();
startActivity(intent);
}
Then when my class DisplayMessageActivity needs the string message he just calls for:
String message = myClass.message;
That seems so much more straight forward. What is with the creation of the new string EXTRA_MESSAGE which just seems to hold the string message and why send it with the intent when my other class can access this info directly anyway -- and what does the field declaration with the "self.anon.myfirstapp.MESSAGE" mean? I can find no such folder or path leading to anything.
As someone else stated there are often situations (such as a screen rotate) in which the android system destroys and restarts the app - so all variable data is lost. It would only work consistently the way you suggest if your data is hard coded as a final variable. That is not the only reason for using intents though.
The great thing with using an intent to pass information is that you can use the intent not just to communicate with sub-activities within your own application but to any activity installed on that android system. For example you may want to launch an intent which starts the phone application and include as an extra the number that you want to call.
Perhaps a better question than yours though is "why would you not use intents to pass information?" The intent.putExtra() method allows you a convenient flexible and straight forward method to pass as much information as you like in a safe and secure way to any other activity.
intent.putExtra(EXTRA_MESSAGE, message);
works like a key value pair, when you want to retrieve the information from the intent you can simply do intent.get<type>Extra and get said information, in this case, intent.getStringExtra("self.redway.myfirstapp.MESSAGE'). its simply the key to retrieve the information, it does not have to be your entire classpath.
it could just as easily be intent.putExtra("message",message).
They are helpful when passing information that you don't necessarily want to reveal to another class but you do want it to be able to get that information in another manner from what i have found.
message = myClass.message It is not always certain that this will retain its value especially when it extends Android framework classes like Activity. When your activity is recreated(change of screen orientation) then message can lose its current value and be assigned a default value. myClass.message would work if message was a static field or else you would need to provide getter and setter methods for object of the Activity Class. Well creating objects of activity class is unheard of in my experience.
I have question for receive value in smartwatch. Currently I follow this steps from this question
Actually,the person who ask it has the answer how to do that, but since my reputation for comment is not enough, so I can't ask question by comment in his/her question.
Right now, based on Mr. Eir,the person who answered the question. I have problem in what he answered:
You also want to pass some arguments to your Extension, i.e. the
String you mention. This can be a bit tricky; normally, you would pass
that String in the Intent itself, as an extra, but here, that is not
available. You need to save that information (the String) on a
location that your Extension can access as well. So, if your Activity
and your Extension are part of the same app, that location can be the
app preferences: the Activity saves the value in the preferences, and
the Extension reads it from the same preference and displays it on the
SmartWatch or whatever.
He said that I can save the value in preference and the Extension reads it from the same preference and displays it on the SmartWatch. Unfortunately, I don't know how the extension reads it. I have try to put the value in samplepreferenceactivity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences settings = getSharedPreferences("SHARED_PREFS_FILE",0);
String message = settings.getString("send", "message");
}
I don't know how to put the value in controlextension class, If it possible to put, I want to you use for changing "Hello watch". Below you can find controlextension class:
public class HelloWatchExtension extends ControlExtension{
...
public HelloWatchExtension(Context context, String hostAppPackageName) {
super(context, hostAppPackageName);
width = getSupportedControlWidth(context);
height = getSupportedControlHeight(context);
layout = new RelativeLayout(context);
textView = new TextView(context);
textView.setText("Hello watch!");
textView.setTextSize(9);
textView.setGravity(Gravity.CENTER);
textView.setTextColor(Color.WHITE);
textView.layout(0, 0, width, height);
layout.addView(textView);
}
Since it is not activity, so it is n't possible to take by using getpreference. Anybody knows how?
"Since it is not activity, so it is n't possible to take by using getpreference. Anybody knows how?"
You can access the preferences through context:
context.getApplicationContext().getSharedPreferences(...);
A few pointers about using shared preferences:
SharedPreferences preferences = _context. getApplicationContext().getSharedPreferences("com.example.AppName", Context. MODE_MULTI_PROCESS);
Putting string in shared preferences:
_preferences.edit().putString(“OBJECT”, “object_name”).commit();
Retreaving string from shared preferences:
_preferences.getString(“OBJECT”, "default_name");
If you are just trying to pass a string between an Activity in your project and your ControlExtension you don't need to use SharedPreferences. The easiest way is to just register a dynamic BroadcastReceiver in your extension and broadcast an Intent from the Activity passing your string inside the Intent.
Hello Everybody,
    I have an app that a couple of classmates and I did for a class project. We are now continuing the app to improve and streamline it. Here is what I have so far:
SplashScreen
HomePage
Hole 1 - 18
ScorePage
AboutPage
Home Screen Hole 1 - 18 Score Page About Page
I have pretty much got it all figured out except for a few small things. The issue that I am working on right now though is:
Passing data from each Hole Page to the Score Page.
I know how to pass it from page to page and I could brute force it, because that is how I initially had it, but it looks sloppy and I would like to not do that if possible.
//Code (partial)
//(From Hole 1)
#Override
public void onClick(View v)
{
TextView tvScoreLbl = (TextView) findViewById(R.id.scoreLbl);
tvScoreLbl.setText(String.valueOf(count));
if(v == findViewById(R.id.btnAdd))
{
count++;
tvScoreLbl.setText(String.valueOf(count));
}
else if(v == findViewById(R.id.btnMinus))
{
count--;
tvScoreLbl.setText(String.valueOf(count));
}
else if(v == findViewById(R.id.btnPrev))
{
Intent i_prev = new Intent(Hole_01.this, HomePage.class);
startActivity(i_prev);
}
else if(v == findViewById(R.id.btnNext))
{
Intent i_pass = new Intent(Hole_01.this, ScorePage.class);
i_pass.putExtra("score1", tvScoreLbl.getText().toString());
Intent i_next = new Intent(Hole_01.this, Hole_02.class);
startActivity(i_next);
}
//(From ScorePage)
String score;
TextView tvScore1 = (TextView) findViewById(R.id.tvScore1);
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.scorepage);
Button btnHome = (Button) findViewById(R.id.btnHome);
btnHome.setOnClickListener(this);
score = getIntent().getExtras().getString("score1");
tvScore1.setText(score);
}
Thanks in advance.
The best answer depends on how long you need your data to persist.
If you need it to persist across a long period of time (days/weeks) then store the data to the internal or external storage using either SQLite or creating a custom object that represents all the data from the 'hole page' and serialize that object and write it to disk.
If you don't need the data to persist then I'd do as you currently are and continue passing the data as you are, from Activity to Activity. It may seem 'sloppy' to you but it is how you are supposed to pass data between Activities.
Perhaps creating an object for the data you want to pass and have it implement the Parcelable interface would make it less 'sloppy' in your eyes. Here's a link to a tutorial for Parcelable objects.
Another option is to use the global Application context as suggested already BUT be warned it comes with a big problem - if the app is killed in the background any data stored in the Application class is lost, so you'll have to account for that happening.
A DB is excessive if you're only storing a tiny bit of info, the Application context will lose data if the app is killed by the OS.
So if you want to persist data for a period of time, use serialization to write the object ( if it's just the score then a simple File IO stuff would do the job with no need for serialization). Or if you only need it to persist while the app is running (foreground or background) then pass the data between Activities.
Rather than passing data between all your Intents with putExtra why not use a little SQLite DB to store the result of each activity that the score screen could read.
SQLite Docs
Android Notepad Tutorial is good for SQLite example as well
Hold all the state in an Application Class.
Write to it as needed, from whatever Activity.
Read from it in the ScorePage Activity.
More details and example available here: (Using the Android Application class to persist data)
I want to pass an array from one Activity to another Activity,for example I need to pass an array from image_view Activity to Blackimage Activity.Please give solution to this problem in Android.
Using a Singleton is probably a bad idea here, especially given Android's kill-happy lifecycle and the high likelihood of leaking Context if you do it wrong. Android has a very simple and powerful built-in message-passing capability on Intents - use it! You should pass the array as an Extra on the Intent, either using the built-in putExtra methods that take Arrays of various Java builtins, or by making sure your array is made of Serializable objects and passing it to the Intent's putExtra method that takes any serializable object. Then you can simply get the extra out of the Intent in the second Activity's onCreate(), no messy singletons necessary.
Read up on making a singleton class, then you can call singleton.setArray(myArray) in one Activity, and singleton.getArray() in the next.
If they are both in the same application.
In addition to the singleton class, you might want to look at using the Android SharedPreferences to save/get any data to either save your settings or prevent loss of data if interrupted.
Also adding android:configChanges="keyboardHidden|orientation"> into the AndroidManifest will prevent your app from losing data if you rotate screens/slide open keyboard.
SharedPref Example
String m_myData[];
Boolean m_myBoolData[];
public static void saveSettings()
{
SharedPreferences.Editor editor = m_SharedPreferences.edit();
for(int ix = 0; ix < m_myData[].length; ix++
{
editor.putString("myKey" + ix, m_myData[ix]);
editor.putBoolean("myKey" + ix, m_myBoolData[ix])
}
}
public static void getSettings()
{
for(int ix = 0; ix < m_myData[].length; ix++
{
m_myData[ix] = m_SharedPreferences.getString("myKey" + ix, false);
m_myBoolData[ix] = m_SharedPreferences.getBoolean("myKey" + ix, false )
}
}
Passing it through the activity will be the best performance choice, as if you use preferenes or the Intent to pass on the array you will have to loop over the array to persist it and recover it from the Intent or Preferences.
Using the Application will allow you to pass on the array, but doing so, just like with a singletone will force you to handle it instance being destroyed as if you wont do it it wont be GCed even after the two activities died since the application will still keep a reference to it.