i am building an android application but i have some questions about
the memory usage.
Most of the data i need and use are string arrays stored in the xml strings file. I used arrays because firstly the biggest array will have up to 30 items and secondly there won't be any updating or deleting or inserting items through the app.
All the custom adapters i created are following googles' guidlines (the fast way - using the holder class)
As the user switches between the activities, depending on the selections he makes different arrays are loaded in the listviews.
Does android clears the memory each array allocates if its not in use? should i do that?
I ve used MAT also to check how the app uses memory and to check for leaks etc..and i thing that everything is fine. I also use a few png icons/images.
The app gets 5MB when it starts, goes up and down up to 8.5-9MB as the user plays around.
Thanks in advance for any help!
It's possible the Android OS will kill your Activities (without focus) on the stack if memory is needed. When your Activity is killed in this way, onSaveInstanceState(Bundle outState) is called. You should save your string array here.
When onCreate(Bundle savedInstanceState) is called in your Activity, if savedInstanceState is not NULL, then it means your Activity was previously killed by the OS and you need to repopulate your string array from that bundle.
ex:
String [] stringArray;
...
protected void onCreate(Bundle savedInstanceState)
{
if (savedInstanceState != null)
{
stringArray = savedInstanceState.getStringArray("some_key");
}
}
protected void onSaveInstanceState (Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putStringArray("some_key", stringArray);
}
This is described in more detail here: http://developer.android.com/reference/android/app/Activity.html
Related
Is there any simple way to save the whole activity instance and restoring it ?
After spending 1 hour of searching all corners of internet, I ended up here. I still don't know how to make this.
Yes, I know how to save current instance using onSaveInstanceState and onRestoreInstanceState
but no one in the internet explained it with a large complex coding like dynamically created views, many textviews and calculations,etc. Everyone explaining this with only one or two textViews and I was like "How someone can create an app with only few TextViews!?!" like below:
onSaveInstanceState()
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(TAG, "onSaveInstanceState");
final EditText textBox =
(EditText) findViewById(R.id.editText);
CharSequence userText = textBox.getText();
outState.putCharSequence("savedText", userText);
}
onRestoreInstanceState()
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.i(TAG, "onRestoreInstanceState");
final EditText textBox =
(EditText) findViewById(R.id.editText);
CharSequence userText =
savedInstanceState.getCharSequence("savedText");
textBox.setText(userText);
}
I can totally understand this above method. But What to do if we complete a quite complicated coding and want to save & restore the state I have completed all my complex coding stuff and landed in this problem.
I'm sure there will be a simple way to achieve this. Please understand my problem. Help me.
If I understand correctly, you want to save the current state of the page even the page changes, if this is the case, it can be solved by data binding as follows:
1.enable data binding in Gradle
2. in XML file put your layout into layout tag
<layout>
...// your activity view layout
</layout>
then define it in your activity :
private lateinit var binding: FragmentNameBinding
4.add this expression in onCreate or onCreateView(for fragment)
if (!(::binding.isInitialized)) {
//initialize you layout file and what ever you want
}
//then initialize what you want to not change after the layout
changed and back to it
I need to save the state of listview when the application closes (after turning the screen). SQL does not want to use. I know that there are standard methods: SharedPreferences, onSaveInstanceState. My code is:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//-----------listitem------------
ListView listView = (ListView) findViewById(R.id.listView1);
catnames = new ArrayList<String>();
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, catnames);
listView.setAdapter(adapter);
listView.setAdapter(adapter);
}
And put Adapter
catnames.add(0, name);
adapter.notifyDataSetChanged();
Maybe I should not use ArrayAdapter? Help please ...
I want to save catnames)
ps application extends SherlockActivity.
You need to use the SQLite datababse to persist the data. When the application closes, save the data to the database. When the application starts, retrieve the data from the database. All you need to learn is simple SQL :)
This should give you a head start: http://www.vogella.com/tutorials/AndroidSQLite/article.html
Update:
If you are looking to use onSavedInstanceState() then you need to use Bundles which are, in simple terms, key-value pairs.
Once you get your adapter to populate the data, just use the setSelection() or the smoothScrollToPosition() to go to the element you want. This implies that you current position of the list when your screen goes off. For that, you need the getFirstVisiblePosition() method. This will be saved in your Bundle and this is what you will use when your screen comes back on.
I'm basically trying to save an array of Bitmaps between states.
My fragment's onSaveInstanceState:
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArray(SELECTED_IMAGES_ARRAY_BUNDLE, galleryAdapter.getImageBitmaps());
}
And in it's onCreateView I retrieve the array as so:
savedInstanceState.setClassLoader(Bitmap.class.getClassLoader());
Bitmap[] savedSelectedImages = (Bitmap[]) savedInstanceState.getParcelableArray(SELECTED_IMAGES_ARRAY_BUNDLE);
This WORKS regularly, EXCEPT when the Android OS does some memory management, kills off my process if it's running in the background, and later tries to restore it when I come back to it.
This is the error I get:
AndroidRuntime(4985): Caused by: java.lang.ClassCastException: android.os.Parcelable[] cannot be cast to android.graphics.Bitmap[]
I thought it was something to do with not properly setting the classLoader, but I tried everything and can't seem to get it to work
Hi It is not recommended to put the Bitmap in a bundle that cost extra processing time. And consumes lot of memory.. Highly recommended to pass the path or save the image in the External storage and and bundle the absolute path to the image file....check this question in SO Bundle Bitmap .
You can do something like this.Where p is your parcelable list. And finally convert list of bitmaps back to an array.
List<Parcelable> pList = Arrays.asList(p);
ArrayList<Bitmap> bList = new ArrayList<Bitmap>();
for(Parcelable px : pList){
bList.add((Bitmap)px);
}
I am having 2 activities:
1st Activity contains 2 arrays which are filled up with the data by making call to a webservice. And both the arrays are used to display data in ListView. On clicking on any List Item, i am opening new activity Activity-2, here i am posting data related with that selected List-item.
But i am facing trouble when i return from Activity-2 to Activity-1 , it agains goes to fetch data from Webservice into Array(Instead of, It should go for fetching data if there is anything posted from 2nd activity otherwise it should get preserved arrays value). So my question is how do i preserve value of both the arrays so that i remains preserve the same value. so it does not have to go for fetching again and again.
(I think i need to use the "Save activity state" kind of concept, but i didnt have implemented such concept yet, so please if you know such then pls let me know for the same.)
Update:
I have added "(Instead of, It should go for fetching data if there is anything posted from 2nd activity otherwise it should get preserved arrays value)"
You can put them the values you retrieved in the Bundle passed to onSaveInstanceState:
#Override
protected void onSaveInstanceState(Bundle outState) {
// Put your values into outState
outState.putStringArray("my.project.str.array", stringArray);
outState.putStringArrayList("my.proj.str.array.list", strArrayList);
// read the documentation on Bundles to see complete
// list of values you can put in
super.onSaveInstanceState(outState);
}
And then you can retrieve them back via onRestoreInstanceState.
EDIT: You can put in more than one string array or string array list or whatever value, as long as the keys are different for each.
I am experiencing a problem that when the Android device wakes up from sleep, the Activity would take forever to get redrawn (and I have to terminate it most of the time). I am not sure why, but when I comment out the code below, where it retrieves an object from the database based on id stored in the bundle, the problem goes away.
I am not sure why the db transaction is causing an issue. Any ideas?
Secondly, is it better to store the object in a bundle instead of storing its id and retrieving it from db in onCreate?
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.track_act);
/*
final Bundle extras=getIntent().getExtras();
long actId=extras.getLong("activity_id");
System.err.println("actId is "+actId);
Data.Activity act=DBManager.getActivity(actId, this);
*/
}
Are you getting nothing in LogCat related to this problem?
It looks like your getActivity method is a static method. Could there be some problems associated with that static reference after waking up from sleep?