onResume for android annotations - android

I am using android annotations and have some code that I need to execute in the onResume() function in my activity.
Is it safe to just override the onResume function from the android annotation activity (ie with #EActivity)?

Yeah, you should use these lifecycle methods just like with plain Android activities. There is one thing though: injected Views are not yet available in your onCreate method, this is why #AfterViews exist:
#EActivity(R.layout.views_injected)
public class ViewsInjectedActivity extends Activity {
#ViewById
Button myButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// myButton is not yet available here
}
#AfterViews
void setupViews() {
// myButton is first available here
myButton.setText("Hello");
}
#Override
protected void onResume() {
super.onResume();
// just as usual
}
}

Yeah. Just call super.onResume() and then add your code.
I'd do it just like their on create example here: https://github.com/excilys/androidannotations/wiki/Enhance-activities

You can bind your custom class with lifecycle component of android. It holds life cycle information of android component so that your custom class observe lifecycle changes.
public class MyObserver implements LifecycleObserver {
#OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void connectListener() {
...
}
#OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void disconnectListener() {
...
}
}
myLifecycleOwner.getLifecycle().addObserver(new MyObserver());

Related

When do views get injected when using the AndroidAnnotations library?

I am wondering when #ViewById-annotated views are injected in AndroidAnnotations. Basically, I want to know if it is safe to access one of these views during onResume? I assume they are injected during onCreate but would like confirmation.
Thank you.
The easiest way to figure out exactly when injection happens is to inspect the code that AndroidAnnotations generates. For your examples, I made a simple Activity and Fragment as below:
#EActivity(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
#ViewById(R.id.textView)
TextView textView;
#AfterViews
public void activityTestMethod() {
}
}
#EFragment(R.layout.fragment_main)
public class MainFragment extends Fragment {
#ViewById(R.id.imageView)
ImageView imageView;
#AfterViews
public void fragmentTestMethod() {
}
}
and then ran ./gradlew app:assembleDebug to force AndroidAnnotations to generate the corresponding classes MainActivity_ and MainFragment_. Let's look at MainActivity_ first (irrelevant code omitted):
public final class MainActivity_
extends MainActivity
implements HasViews, OnViewChangedListener
{
#Override
public void onCreate(Bundle savedInstanceState) {
OnViewChangedNotifier previousNotifier = OnViewChangedNotifier.replaceNotifier(onViewChangedNotifier_);
init_(savedInstanceState);
super.onCreate(savedInstanceState);
OnViewChangedNotifier.replaceNotifier(previousNotifier);
setContentView(R.layout.activity_main);
}
private void init_(Bundle savedInstanceState) {
OnViewChangedNotifier.registerOnViewChangedListener(this);
}
#Override
public void setContentView(int layoutResID) {
super.setContentView(layoutResID);
onViewChangedNotifier_.notifyViewChanged(this);
}
#Override
public void onViewChanged(HasViews hasViews) {
this.textView = hasViews.internalFindViewById(R.id.textView);
activityTestMethod();
}
}
The sequence of events that results in our views being bound and our #AfterViews methods being called is as follows:
In onCreate, the MainActivity_ instance is registered as an OnViewChangedNotifier.
onCreate calls setContentView.
setContentView calls notifyViewChanged, which triggers a (synchronous) call to onViewChanged.
onViewChanged binds all fields annotated with #ViewById, then calls all methods annotated with #AfterViews.
Therefore, #ViewById-annotated views are bound and available for use after onCreate has been called, and #AfterViews-annotated methods will be executed at the end of onCreate and before any other Activity lifecycle method.
The story is similar for MainFragment_:
public final class MainFragment_
extends com.stkent.aatest.MainFragment
implements HasViews, OnViewChangedListener
{
#Override
public void onCreate(Bundle savedInstanceState) {
OnViewChangedNotifier previousNotifier = OnViewChangedNotifier.replaceNotifier(onViewChangedNotifier_);
init_(savedInstanceState);
super.onCreate(savedInstanceState);
OnViewChangedNotifier.replaceNotifier(previousNotifier);
}
private void init_(Bundle savedInstanceState) {
OnViewChangedNotifier.registerOnViewChangedListener(this);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
onViewChangedNotifier_.notifyViewChanged(this);
}
#Override
public void onViewChanged(HasViews hasViews) {
this.imageView = hasViews.internalFindViewById(R.id.imageView);
fragmentTestMethod();
}
}
The sequence of events that results in our views being bound and our #AfterViews methods being called is as follows:
In onCreate, the MainFragment_ instance is registered as an OnViewChangedNotifier.
onViewCreated calls notifyViewChanged, which triggers a (synchronous) call to onViewChanged.
onViewChanged binds all fields annotated with #ViewById, then calls all methods annotated with #AfterViews.
Therefore, #ViewById-annotated views are bound and available for use after onViewCreated has been called, and #AfterViews-annotated methods will be executed at the end of onViewCreated and before any other Fragment lifecycle method.
In both our examples, all view binding is performed in a lifecycle method that occurs much earlier than onResume, so you are safe to access them there :)

Notify when onPause() called in any activity of an application

I think this question may simple but I didn't find any solution for this,
I there any way in Android that if any one of an activity calls onPause() I need to show Toast message or any notification kind of thing need to show. Generally I want to get notified when activity calls onPause() but I need it in one place since I may have some 15 activity I don't want to add it in all the activity.
ex:If I have activity when any one of the activity calls onPause I need to get notified but that notification code should be in one place and we should not add any line of code onPause() Is it possible to do this.
Thanks.
Create a baseActivity, which has for example :
open class BaseActivity : AppCompatActivity() {
override fun onPause() {
super.onPause()
Toast.makeText(this, "notified", Toast.LENGTH_SHORT).show()
}
}
Then you can extends this in your activities and handle the on pause call in BaseActivity
If your minSdkVersion >= 14, you can use Application.ActivityLifecycleCallbacks: ActivityLifecycleCallbacks
You have to define a custom Application class and you can register for this callbacks afterwards:
public class MyApplication extends Application {
private class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
#Override
public void onActivityCreated(final Activity activity, final Bundle savedInstanceState) {
//nothing to do
}
#Override
public void onActivityDestroyed(final Activity activity) {
//nothing to do
}
#Override
public void onActivityPaused(final Activity activity) {
// TODO Do your stuff, e.g. show toast.
}
#Override
public void onActivityResumed(final Activity activity) {
//nothing to do
}
#Override
public void onActivitySaveInstanceState(final Activity activity, final Bundle outState) {
//nothing to do
}
#Override
public void onActivityStarted(final Activity activity) {
}
#Override
public void onActivityStopped(final Activity activity) {
}
}
private final LifecycleCallbacks callbacks;
public void onCreate() {
super.onCreate();
callbacks = new LifecycleCallbacks();
application.registerActivityLifecycleCallbacks(callbacks);
}
}
Create a BaseActivity which contain all the methods you want to use in all other activities.
Then extend every activity with BaseActivity to call onPause() method.

How to know when activity is paused/resumed from inner view?

From a view (a custom status bar) I need to know when the activity is paused and resumed. Is it possible?
Is it possible?
Yes and very easily.
Declare a interface and provide its implementation via your inner view to the outer activity.
Call the respective delegate in the onResume and onPause of activity to notify your inner view.
Simple. Hope this helps :)
Something like this
class MyActivity extends Activity {
public interface ActivityLifeCycleLister{
onResumeCalled();
}
public ActvityLifeCycleLsistener listener;
public void setActivityLifeCycleListener(ActvityLifeCycleLsistener listener) {
this.listener = listener;
}
#Override
public void onResume(){
super.onResume();
if(listener != null) {
listener.onResumeCalled();
}
}
class MyInnerView extends View {
// Some init method
void init() {
MyActivity.setActivityLifeCycleListener(new ActivityLifeCycleListener() {
void onResumeCalled() {
// Do whatever here
}
});
}
}
}
This approach can be used for all the components of your application who wants to listen life cycle events.
You can just create two methods onResume() and onPause() of your custom View (you can call this two methods whatever you want). Then in your activity you will have override onResume and onPause and call customView.onResume() and customView.onPause().

Making an object listen to Activity lifecycle events?

One of the classes I've written needs to react when the following Activity events occur:
onStart()
onPause()
onResume()
onStop()
I can react to those on the Activity itself:
public class Activity extends ApplicationContext
{
protected void onCreate(Bundle savedInstanceState);
protected void onStart();
protected void onRestart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();
}
From the Activity I could tell the object in question that a certain event has occurred, but I don't like this idea: it requires the developer to implement the logic outside my object/class. Ideally I would like the object to be responsible for registering these events and set itself as a listener, independent of the Activity.
Any ideas? Thanks in advance.
API level 14 has Application.ActivityLifecycleCallbacks.
Before that, afaik, sorry, no.
If you wish to offer your class to others, you will need to either provide abstract classes that extend the most common Activities, or have them put certain calls in their own Activity's lifecycle methods, like
protected void onPause() {
super.onPause();
yourClassInstance.onPause();
}
May as well make it more general, and create abstract NotifyingActivity classes that accept NotifyingActivity.LifecycleListener's, and make your class implement such a listener and register itself in its constructor.
Leverage ActivityLifecycleCallbacks that has been introduced since API level 14.
This is what the interface looks like now.
public interface ActivityLifecycleCallbacks {
void onActivityCreated(Activity activity, Bundle savedInstanceState);
void onActivityStarted(Activity activity);
void onActivityResumed(Activity activity);
void onActivityPaused(Activity activity);
void onActivityStopped(Activity activity);
void onActivitySaveInstanceState(Activity activity, Bundle outState);
void onActivityDestroyed(Activity activity);
}
What you need to do is simply to implement the interface methods and register it on your application.
public class MyApplication extends Application implements ActivityLifecycleCallbacks {
#Override
public void onCreate() {
super.onCreate();
this.registerActivityLifecycleCallbacks(this);
}
//implement call back methods.
}
You can use this library that does exactly what you're trying to do, without having to write code in your activity or in your base activity.
And is very simple to use:
ActivityListener.bind(mActivity).with(mCallback);
Maybe it helps someone

#Override on my own methods?

I have a setup similar to what you see below. I have just noticed that "YourClass" is actually implementing some of my logic from "MyClass." Ugh. I tried to throw an #Override above setupViews() in "YourClass" but it won't compile stating, "The method setupViews() of type DataManagerActivity must override a superclass method"
Code changed. It was an example. I just typed the wrong thing. Same question. How can I keep YourClass that extends MyClass from implementing setupViews() from MyClass?
public class MyClass extends Activity {
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setupViews();
...
}
private void setupViews() {
....
}
}
public class YourClass extends MyClass {
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setupViews();
...
}
private void setupViews() {
....
}
}
#Override instructs the compiler to fail unless the method underneath it overrides a method in the superclass (the one you extend from) or one of the interfaces it implements.
Edit: sorry I may have misinterpreted what you meant. The reason why you can't override setupViews() is that it's private in MyClass so that you cannot access or override it from any subclasses.
If that's what you want, then you want your method to be protected - as in, accesible and overrideable in subclasses of the class it's defined in, but not accessible from outside.
Edit 2': so bottom line:
If you want setupViews() to be overridable in subclasses (such as YourClass), make it protected. Otherwise, make it private.
I think you want to use
this.setupViews();

Categories

Resources