Please I would like to understand this situation.
If I rotate my Android application a few times and I look into the memory dump I find more than one instance of my Activity.
That looks like a leak.
But if I force garbage collection just before getting the memory dump (by pressing the button in android Studio) I find only one instance of my Activity.
I am very inclined to think I don't have a leak.
Please does anybody have a definitive answer?
Shouldn't helped you the parameters added to your Activity like:
android:configChanges="keyboardHidden|orientation"
After that, you could handle logic of orientation changes by yourself in the onConfigurationChanged method.
Or the second solution (couldn't completely imagine the structure of your project) should be using the launchMode parameter in AndroidManifest.xml
Related
I have an app where I use Butterknife, and recently I found a fragment where I had failed to call unbinder.unbind() in the fragment's onDestroyView(). I fixed the problem but it made me start thinking.
What kind of errors can this cause and why? I don't have a particular error right now but I would like to know what to watch out for in the future, and the website for the library doesn't specify the problems this could cause.
Imagine you have a retained fragment and you have initialized a view using #BindView.
An orientation change happens, which results in destroying activity instance, but not this fragment, because this fragment is a retained fragment, which means, that the field that you have initialized is still there (not null) and is holding a strong reference to the view of the previous activity, which results in leaking of the activity.
Although this might take for some small amount of time (because eventually you are going to perform another ButterKnife.bind() in onViewCreated(), right? But who knows, maybe you won't), still it is better to release resources as soon as you do not need them and let the GC do its job.
I've also thought about this question some time ago and other than this I couldn't come up to another scenario where unbind() would be strongly necessary.
Right now I'm developing a game in Android (OpenGL ES 1.1) and I'm seeing that whenever I create a new SurfaceView (GLView) its thread is created. That's ok. The problem comes when I want to finish the Activity that holds the SurfaceView (and go back to the menu). It seems that the activities are not released because each GLThread is referencing it. This may finish with an OOM error.
Some MAT pictures:
The first picture: the MarkitActivity represents each single instance of the Activity that deals with SurfaceView.
The second picture: The list of all the activities in memory.
The Third Picture: What is holding the Activities from GC.
If any code is needed I will post it. Nevertheless I have already tried the following things:
->Weak reference of the Activity Context to the renderer and to the surfaceview.
->Application Context instead of Activity Context (in normal and weak mode).
->Trying to stop (in a hard way) the thread (interrupt) and waiting for join (Which the program does it, but the thread does not care, it is still there...)
->Trying without debugging, just in case in debugger mode the values changes (the MAT pictures are without debugger).
->Trying the Activity as singleInstance mode. Weird results and errors everywhere.
->onPause and onResume are correctly controlled for the view.
Any hint, idea, question or help will be really appreciated. Thanks in advance!
Carlos.
I had a similar problem with threads (but not using OpenGL), and end up solving it using a simple trick.
Before exting activity (in onPause() or onStop(), try nulling the thread like this:
myThread = null;
It seems that it makes the Thread GC collectable, and therefore you activity becomes also collectable.
It worked for me, as well as for some people with similar problems to whom I gave the same suggestion.
Regards.
I have an app that will never require more than one instance of an activity. I want it so that when the user comes back to a screen it is in the same state as they left it except for a few places where it doesn't make sense. I've worked out saving the persisted data with onpause onstop updates. However to keep the screen looking the way it did when they left it i use intents specifically setting the flags to Intent.FLAG_ACTIVITY_REORDER_TO_FRONT|Intent.FLAG_ACTIVITY_SINGLE_TOP then startActivity. It seems to work great but does it make sense? Is there a smarter way? Pitfalls doing it this way etc... any feedback will be greatly appreciated.
android:launchMode = "singleTask"
add the above line for every activity in the manifeast file. Adding these launch relaunch the activity instead of creating the activity again.
Refer this link
i already read the question Activity restart on rotation Android . But it does not really help me.
I've two activities. The Second gets updated from an Async_Task, which holds a few Threads which i cannot just restart.
The Problem i got is, that rotating my Device forces an Activity-restart, which means i loose my Reference to the Async_Task.
Is there any possibility to pass Objektreferences from one activity to another?
Thanks for help!
Make your reference static, or see: http://developer.android.com/guide/topics/resources/runtime-changes.html#RetainingAnObject
I have been going gaga to figure this out.
Although I have read a lot that on Orientation Change, Android kills an activity and starts it as a fresh one, and the only way to handle this is to save all the stuff inside onSaveInstanceState() and try to restore it inside onCreate().
But my activity does a lot and different kind of network activities at different times and if the orientation is changed when the network activity is being performed, I'll have to handle a lot of different and complex scenarios.
Is there any simple way to just point Android that this activity doesn't need to be redrawn at all when the orientation is changed so that it automatically saves all the data and re-uses it?
I wonder if there's any thing like that.
Yes, you can add attribute android:configChanges="orientation" to the activity declaration in the AndroidManifest.xml file.
EDIT:
The purpose of the android:configChanges attribute is to prevent an activity from being recreated when it's really necessary. For example the Camera application uses this attribute because it the camera preview screen mustn't be recreated when an orientation change happens. Users expect the camera preview to work without any delays when they rotate their devices and camera initialization is not a very fast process. So it's kind of a native behavior for the Camera application to handle orientation changes manually.
For most applications it doesn't really matter if an activity is recreated or not during orientation changes. But sometimes it's more convenient to persist an activity during this process because of slow activity creation, asynchronous tasks performed by an activity or some other reasons. In this case it's possible to tweak an application a little and to use the android:configChanges="orientation" attribute. But what is really important to understand when you use this tweak is that you MUST implement methods for saving and restoring a state properly!
So to sum up this answer, the android:configChanges can allow you to improve the performance of an application or to make it behave "natively" in some rare cases but it doesn't reduce the amount of code you have to write.
But my activity does a lot and different kind of network activities at different times and if the orientation is changed when the network activity is being performed, I'll have to handle a lot of different and complex scenarios.
Then move that logic out of the activity and into a service.
Yes, you can add attribute
android:configChanges="orientation" to
the activity declaration in the
AndroidManifest.xml file.
IMHO, it's better to declare
android:configChanges="orientation|keyboard|keyboardHidden"
About the blog post you gave the link in another answers. I guess here is the answer:
If your application doesn't need to
update resources during a specific
configuration change and you have a
performance limitation that requires
you to avoid the Activity restart,
then you can declare that your
Activity handles the configuration
change itself, which prevents the
system from restarting your Activity.
I spoke as well with an android developer about this problem. And he meant following. If you don't have different layouts for landscape and portrait orientation, you can easy use configChanges.
I solved my problem by adding this to my activity in my manifest file
android:configChanges="keyboardHidden|orientation|screenSize"
Just answered this question earlier: Android - screen orientation reloads activity
In your case you want to completely prevent Android from killing your Activity. You'll need to update your manifest to catch the orientation change, then implement the orientation change callback to actually do whatever you need to do (which may be nothing) when an orientation change occurs.
if you are doing a lot of networking inside Asynchronous task maybe you should use onRetainNonConfigurationInstance()
ans then get the data back in your onCreate() method like this tutorial or this
add android:configChanges="orientation" to your activity in manifest and add this code in your activity class and check..i hope it will help for you.
#Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
setContentView(R.layout.main);
}
this method will be called when orientation is changed nothing else if u don't want to change anything let it be blank
android:screenOrientation="portrait" in the activity tag in the manifest will lock your orientation.
Check this link for more inforation.