I have a custom component which extends LinearLayout, I need to execute certain statements when Layout is destroyed or removed. (or about to be removed)
One way is to check for onPause() or onDestroy() of an activity and call methods of the custom component. But I want to remove that overhead from the activity.
So that custom component itself can handle when layout is detached. But I dint find the suitable method to override (to detect the event) when layout is removed. Is there a way to handle this, or we need to use onPause() and onResume() method of activity ?
I had success overriding the onAttachedToWindow() and onDetachedFromWindow() methods:
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
// View is now attached
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
// View is now detached, and about to be destroyed
}
You can have your custom view listen to its own eventss. I suggest using View.OnAttachStateChangeListener and listening to onDetach event.
#Override
void onViewDetachedFromWindow(View v) {
doCleanup();
}
It is dangerous to rely on the "destruction" of a layout to execute statements, as you're not directly in control of when that happens. The accepted way and good practice is to use the activity's lifecycle for that.
But if you really want to tie your component to that lifecycle, I suggest your component implements an interface (something like Removable), and do something like that in your base activity classe (that all your activities extend):
protected Set<Removable> myRemovableItems = new HashSet<Removable>();
#Override
public void onPause() {
super.onPause();
for (Removable removable : myRemovableItems) {
removable.remove();
}
}
The interface:
public interface Removable {
void remove();
}
Then each time you add one of your custom component from an activity, you add the component to the internal set of Removable of the activity, and its remove method will be automatically called each time the activity is paused.
That would allow you to specify what to do when onPause is called within the component itself. But it wouldn't ensure it's automatically called, for that you'll have to do it in the activity.
Note: you can use onStop instead of onPause depending on when you want the removal to occur.
Related
I tried several times to invoke Resume method of MainActivity from the Fragment,
calling simply onResume(); nothing in result.
code for resume method
protected void onResume() {
all.clear();
outgoing.clear();
incoming.clear();
getFromSdcard();
super.onResume();
}
I want to call this method from fragment.
Enhancing #cricket_007 response :
You can invoke onResume from the parent Activity, but just like you have seen, onResume has protected access blocking you from calling it.
There is a small visibility workaround that allows you to do it.
1 - Implement this method on your activity
public void myOnResume(){
this.onResume();
}
2 - Then on your fragment you can invoke
public void myFragmentMethod(){
// make sure to double check casts (to YourActivity) like these before invoking
((YourActivity) getActivity()).myOnResume();
}
Conclusion and recommendation : Even though it is not recommended that you implement it this way, it can be done like I said.
In my opinion, what you should do is :
1 - Have all the functionalities of your onResume() method inside a proper method of your own (you name it!) like :
public void clearData() {
all.clear();
outgoing.clear();
incoming.clear();
getFromSdcard();
}
2 - Then you could just separate all these functionalities from onResume() and still have them invoked like
protected void onResume() {
super.onResume();
clearData();
}
3 - Invoke it on your fragment like (previously shown)
public void myFragmentMethod(){
// make sure to double check casts (to YourActivity) like these before invoking
((YourActivity) getActivity()).clearData();
}
Let me know how it went.
Regards,
You are calling the Fragments onResume()
You can try getActivity().onResume(), but you really should make a method to do whatever code you need rather than explicitly call lifecycle methods.
Create an Interface
interface OnParentActivityResumed {
fun onActivityResumed()
}
implement the interface in the fragment
class MyFragment: Fragment(), OnParentActivityResumed{
override fun onActivityResumed() {
//[YOUR CODE WHEN PARENT ACTIVITY RESUMED]
}
}
on parent activity onResume add
override fun onResume() {
super.onResume()
myFragment.onActivityResumed()
}
I'm brand new using Event Bus from otto lib, So far I created a Event Bus Singleton class, which I'm using in several parts of my code. Now I'm working on a fragment view, But I still have a question, regarding:
When is the best time to register/unregister my event bus?
In a couple of posts I read that onStart() and onStop(), but without any specific reason why.
public class SomeFragment extends Fragment {
#Override
public void onStart() {
super.onStart();
EventBusSingleton.register(this);
}
#Override
public void onStop() {
super.onStop();
EventBusSingleton.unregister(this);
}
}
If I follow the same approach as in the activities doing the call onResume() and onPause() works fine as well.
public class SomeFragment extends Fragment {
#Override
public void onResume() {
super.onResume();
EventBusSingleton.register(this);
}
#Override
public void onPause() {
super.onPause();
EventBusSingleton.unregister(this);
}
}
What could be the potential risk(if exist) from each call way?
onPause()/onResume() is called when your activity does not have the focus anymore but could still be visible (think a dialog or alert on top of your activity).
onStop()/onStart() is called when your activity is not visible anymore.
Which one to use depends your use case. I believe it's not really a problem to have callbacks executed while in the paused state so I would just put the register/unregister in onStop()/onStart() but if you really want to make sure, you can put them in onPause()/onResume().
My problem was what my fragmets had two instances for bad coding, y delete de uneccesary instance and it solve the problem
I have an Activity that assigns an object to a field in an Activity's onCreate() and access that object in onDestroy(). The field isn't assigned anywhere else.
My problem is that I have 2 crash reports indicating that the field is null in onDestroy. The only options I can think of are:
A) onDestroy() is being called before onCreate() or
B) This is some sort of Mono bug and onDestroy() is actually running in
a different instance of the .NET activity.
Here is a cut down example.
public sealed class MainActivity : Activity{
private _disposable;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
_disposable = new Disposable();
}
protected override void OnDestroy()
{
// NRE exception here ( _disposable is null )
if(_disposable.Guard())
{
...
}
base.OnDestroy();
}
}
Ignoring the fact that this is a Xamarin Android app, I really want to know if the A) case possible? Should I rule it out completely and assume the bug is somewhere else OR is it possible for onDestroy() to be called before onCreate() and I should guard against it.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
notify("onCreate");
}
#Override
protected void onPause() {
super.onPause();
notify("onPause");
}
#Override
protected void onResume() {
super.onResume();
notify("onResume");
}
#Override
protected void onStop() {
super.onStop();
notify("onStop");
}
#Override
protected void onDestroy() {
super.onDestroy();
notify("onDestroy");
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
notify("onRestoreInstanceState");
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
notify("onSaveInstanceState");
}
I'm if right, these are the methods to handle the life cycle of an activity. My question is, do you need to put these methods in each class if you want to handle your app life cycle properly, or just in the main class?
They have to be implemented once per activity. The code of one activity won't be used in anotherone unless the second is a subclass of the first.
As an additional note, only onCreate must be implemented, the others are optional.
You only need to override the methods that you want to use.
If you don't need to perform any special functions in onDestroy(), for example, you don't need to override it in any of your Activities.
A good way to identify whether or not you need it is to look at what you have in those methods. If all you are doing is calling super, then you don't need to include that method in your Activity because the default behavior will work just fine for you.
If you want your app to develop some certain behavior that can be applied to some specific part of the life cycle you have to put those methods in each class Activity. Because of the inheritance that a class have if you want some specific behavior through all the app I recommend you to use the Application class that modifies all the subsequent Activities the only problem is that not all the normal methods of an activity life cycle are available.
Here is some reference about lifecycle in Application class:
https://www.inkling.com/read/programming-android-mednieks-1st/chapter-11/life-cycle-methods-of-the
The best example of the method you always have to override is onCreate() because here is where you add all the normal start up behavior of the views and logic in your activity.
If you are not very well acquainted with android life cycle I do not recommend you to override these methods because they can lead you to strange behavior in your app, that is for my personal experience.
I would like to know, why OnCreate() is called only once at the start of an activity?
Can we call OnCreate() more than once in the same activity?
If yes, than how can we call it? can anyone give an example?
Thanks a lot!!!
Why would you want to called it again? unless the activity is reconstructed, which is called by system. You cannot call OnCreate manually , it is the same reason why you won't call setContentView() twice. as docs:
onCreate(Bundle) is where you initialize your activity. Most
importantly, here you will usually call setContentView(int) with a
layout resource defining your UI, and using findViewById(int) to
retrieve the widgets in that UI that you need to interact with
programmatically.
Once you finish init your widgets Why would you?
UPDATE
I take some words back, you CAN do this manually but I still don't understand why would this be called. Have you tried Fragments ?
Samplecode:
public class MainActivity extends Activity implements OnClickListener {
private Button btPost;
private Bundle state;
private int counter = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
state = savedInstanceState;
btPost = (Button) findViewById(R.id.btPost);
btPost.setOnClickListener(this);
Toast.makeText(getBaseContext(), " " + counter, Toast.LENGTH_LONG)
.show();
}
#Override
public void onClick(View v) {
counter++;
this.onCreate(state);
}
}
onCreate() method performs basic application startup logic that should happen only once for the entire life of the activity .
Once the onCreate() finishes execution, the system calls the onStart() and onResume() methods in quick succession.
The initialization process consumes lot of resources and to avoid this the activity once created is never completely destroyed but remains non visible to user in background so that once it is bring back to front , reinitialization doesn't happen .
Where you want to call onCreate manually.
Then just do this.
finish();
Intent intent = new Intent(Main.this, Main.class);
startActivity(intent);
finish() calls the current stuff.
And if you are doing somethong getExtra in this activity then do this,
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString("key",your_variable);
super.onSaveInstanceState(outState);
}
And add this to your onCreate()
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
if(savedInstanceState != null)
{
your_variable= savedInstanceState.getString("key");
}
}
Why would you want to call onCreate more than once? You will be re-creating the activity. If this is what you need for whatever reason then finish the activity and use an intent to create a new instance of that activity. Otherwise, you have two instances of the activity at the same time. Hope that helps but if that doesn't make sense then add more information as to what you want so we have context
OnCreate is basically use to create your activity (UI). If you have already created your activity then you need not create it again as you have already created.
It is basically used to initialize your activity and to create user interface of your activity. Activity is a visual part which you can use again and again so.. I think your problem is not to recreate activity but to reinitialize all components of your activity. For that purpose you can create a method initialize_act() and call it from anywhere...
#OnCreate is only for initial creation, and thus should only be called once.
If you have any processing you wish to complete multiple times you should put it elsewhere, perhaps in the #OnResume method.
Recently i realized that onCreate is called on every screen orientation change (landscape/portrait). You should be aware of this while planning your initialization process.
Recreation can be suppressed in AndroidManifest.xml:
<activity
android:configChanges="keyboardHidden|orientation"
android:name=".testActivity"
android:label="#string/app_name"></activity>