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();
Related
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 :)
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());
Ok I am a complete newb when it comes to java classes. I have a public method that dynamically displays some Linearlayouts with some stuff in them. For instance this method (public void methodA)is in ClassA.java, then I want to call methodA from inside ClassB.java. Both of the classes extend Activity and the methodA is being called in the OnCreate method.
ClassA.java
public class ClassA extends Activity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
methodA();
}
public void methodA() {
//Do Stuff
/* This uses:
* Package Manager
* Buttons using(this)
* Linear Layouts using(this)
* TextViews using(this)
* findViewById()
* startActivity
*/
}
}
ClassB.java
public class ClassB extends Activity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
methodA(); //How do I do this
}
}
It is clear to me that the method is specific to the first activity, which means that it shouldn't be called in the second one. You can either reimplement the method in the second activity or, if these activities are similar (don't do this if they aren't!), you have two options:
Inherit the second activity from the first one.
Merge these two activities into one and use different intents to launch them and act accordingly.
The second method is easier to maintain, so I would prefer it over the first one in simpler cases.
Craete instance of class A in class B and then you can invoke MethodA from class B
public class ClassB extends Activity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//MethodA(); //How do I do this
ClassA a=new ClassA ();
a.MethodA();
}
}
I want to know if Android support the possibility to make a container with some static components and just include my activities in it.
I have a sliding menu with some onClickListener events and I don't want to set these events for each activity.
If I understood you correctly, you have some functionality that is common to several Activities, and you don't want to repeat the same code in all of them. Instead, you want to do that in one place.
One way to achieve this is to create a superclass activity, place your common code in that activity, and then extend it with your other activities. For example,
public class BaseActivity extends Activity implements OnClickListener {
private Button button;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button) findViewById(R.id.my_button);
button.setOnClickListener(this);
}
...
#Override
public void onClick(View view) {
int id = view.getId();
switch(id) {
case R.id.my_button:
// perform action
break;
}
}
}
Then you extend it as
public class Activity1 extends BaseActivity {
/...
}
public class Activity2 extends BaseActivity {
/...
}
public class Activity3 extends BaseActivity {
/...
}
I am not exactly sure I understand your question, can you perhaps elaborate some more? maybe even post some sample code that you are using currently.
From what I can tell you should be able to achieve what you want by making your own CustomActivity
public class CustomActivity extends Activity {
//put your slidingmenu stuff here
}
Then inside all of the other Activities where you want to use that shared piece do it like this:
public class AnotherActivity extends CustomActivity {
//...
}
with extends CustomActivity instead of the usual extends Activity
This is how i solved the problem:
First thing i did is creating my main class wich will host common code.
for example :
public abstract class main extends activity(){
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutResourceId());
// Your common code here
}
protected abstract int getLayoutResourceId();
}
Then all what you need is to extend this class in your activity:
public class HelloActivity extends main{
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_hello);
super.onCreate(savedInstanceState);
//make sure to put setcontentview before super.oncreate
}
#Override
protected int getLayoutResourceId() {
return R.layout.activity_hello;
}
}
All the activities needs to be registered in the Manifest. For the common things, e.g. Slide menu, you can use Fragment for the slide menu.
This is an example of using outer class
public class MyActivity extends Activity implements OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylayout);
findViewById(R.id.myid).setOnClickListener(this));
}
public void onClick(View v){...}
}
This is an example of anonymous classes
public class MyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylayout);
findViewById(R.id.myid).setOnClickListener(new OnClickListener() {
public void onClick(View v){...}
}));
}
}
Performance and efficiency are slightly a more important consideration in Android. Something considered to be half baked optimization effort, sometimes makes sense in android.(like we should not use enum but java int enum pattern). So to the answer to your question is.
If you have to register multiple onClick listeners, Implement interface and use switch case within it.
If you have to register only one on click listener, use anonymous class. (Android developers prefers anonymous class, whenever possible. Limiting the scope ;))