Android: Where is the constructor of AppCompatAcitivity? - android

I'm a beginner in Kotlin (and Android for the matter) and I saw that the first opening line of the MainAcitivty class is:
class MainActivity : AppCompatActivity() {
The braces after AppCompatAcitivty mean that this class has a constructor right? I searched inside this class and didn't find any constructor, so where is the constructor of AppCompatActivity?
Is it hidden in a super class that AppCompatActivity itself extends from? If so how can I track it?
Thanks in advance

If no constructor is defined in Java, the class defaults to having an implicit constructor with no arguments and an empty initializer. It's the same in Kotlin...your class definition here for MainActivity has no constructor defined, so it implicitly has a constructor with zero arguments (although you can still define an initializer, but don't do this for an Activity--see below). If you subclassed MainActivity (provided it was marked open, you would have to call the implicit constructor like this:
class MyOtherActivity: MainActivity()
Also in Java, the default implicit constructor automatically passes back to the super constructor. If you follow the inheritence of AppCompatActivity all the way back up to Activity, you'll see that none of the classes have a defined constructor, so they are all empty.
Activities in Android must always have a single no-argument constructor because the OS instantiates them by reflection. You will never instantiate an Activity directly. Do your set-up in the lifecycle callbacks.

It means the MainActivity extends the AppCompatActivity class. This is a classic inheritance. See example here.: https://kotlinlang.org/docs/tutorials/kotlin-for-py/inheritance.html
But of course, it has a constructor, a default one.

Related

no more than one class can extend AsyncTask in an Android project?

Is there any case such that: both class A and class B can extend AsyncTask at the same ? Or else, should it be one class C that extends AsyncTask?
Any number of classes can extend AsyncTask at the same time (or any other class). Extending means that the new class inherits fields and methods of super-class and can override super-class methods. The same applies to AsyncTask as well.

Calling functions provided by the Activity class from anywhere

How do I call the functions provided by Activity class from a class that does not extend Activity? Theoretically, yes, if I don't extend Activity I cannot directly use the functions provided by it. But is there a workaround provided for this? If not, are there replacements or alternative ways for these functions?
For example,
If my class extends Activity, I can call setContentView() to instantiate my layout xml file. But if my class extends some other class and doesn't extend Activity, then I can use the LayoutInflater to do the task. But what about other functions like registerReceiver() ? How do I get the functionality of 'registerReceiver()' from any other class , obviously I wouldn't want every such class to extend Activity. Static access by "Activity.function_name" is also not possible as these functions are not static.
Certain services can be accessed from anywhere. For example 'println()' or Log.e(),System functions can be called from anywhere, whenever needed. Is there a similar way for other critical functions?
Conclusion:
Pass Context to destination class. For accessing some functions however, type-casting the passed Context to Activity is required.
Both Changdeo's and BT's answers are correct.
Thanks.
Although I have not found any documentation explicitly stating why, in every case where I have ever needed to do this, simply passing the Activity's Context is sufficient.
For a Context called contextActivity passed into any function, the following will allow access to these member functions you require:
((Activity) contextActivity).<anyMemberFunction>
Or if you need these functions in multiple cases it might be simplest just to do the following:
Activity myActivity = (Activity) contextActivity;
From there you can access these Activity member functions whenever you like by using:
myActivity.<desiredFunction>;
As I mentioned, I have never found any case where this hasn't worked, but also no solid documentation saying this will always work. This is the trick I have seen consistently used though. If anyone has more to add, please do.
For Ex
Class XYZActivity extends Activity
{
......
......
MyClass myClass = new MyClass(this);
// OR you can pass just context
// MyClass myClass = new MyClass(getContext());
}
Class MyClass
{
Context context;
Myclass(Context context)
{
this.context = context;
context.registe....//Or any function
}
}

Passing context to a standard java class using getApplicationContext causes Force Close

I am working on an android app and am currently having a problem with passing contexts to a standard Java class from a ListFragment.
I have a class called Common and in the constructor I pass the context so I can do various common tasks, such as displaying an alert dialogue, so that I can keep reusing the code instead of having to write the code out each time for every alert dialog box I need. To initialise the class in a standard activity I am using.
Common common = new Common(this);
The code above works fine if this is done in a class that extends an Activity. However, if I want to do the same sort of thing but in a class that extends a ListFragment, this doesn't work, so I use the following code in order initialise the class
Common common = new Common(getActivity().getApplicationContext());
When the above code is executed in the ListFragment, when a function is used to display a Yes/No alert dialogue I get a force close with the exception
FATAL EXCEPTION: main
android.view.WindowManager$BadTokenException: Unable to add window
--token null is not for an application
Below is the code for the constructor for the class
public Common(Context context)
{
this.context = context;
}
Just to reiterate, all of the functions within the Common class, including the Yes/No dialogue work fine without problems if the Common class is initialised from a class that extends Activity using the this argument passed to the constructor. Its only if I getActivity().getApplicationContext() as an argument passed to the constructor that I get this error.
As a test I have also changed one my classes that extends an activity and used the getApplicationContext instead of using this, and I get the same error, so its not necessarily specific to me using a ListFragment.
Thanks for any help you can provide.
You can not use ApplicationContext in your case. Instead use just getActivity(). Activity is a Context so your Common class constructor will be satisfied.
But your Common class should really have Common(Activity a) constructor instead.

"No enclosing instance of type" error while calling method from another class in Android

Colleagues, I have the such question:
1. In my first class I have the
public class parseYouTubeAndYahoo extends AsyncTask<String, Void, List<VideoDataDescription>>
to parse data from internet. But I need to call execute() method of this class from another class. While trying to right such code:
new MainActivity.parseYouTubeAndYahoo().execute("someURL");
I have the next error message from Eclipse
No enclosing instance of type MainActivity is accessible. Must qualify the allocation with an enclosing instance of type MainActivity (e.g. x.new A() where x is an instance of MainActivity).
and really this problem is shrouded in fog for me. So, how to call this method from another class?
In terms of the actual error here, if parseYouTubeAndYahoo class is a non-static inner class inside of your Activity, then you need an instance of the enclosing class in order to instantiate the inner class. So, you'll need:
MainActivity myActivity = new MainActivity();
MainActivity.parseYouTubeAndYahoo asyncTask = myActivity.new parseYouTubeAndYahoo();
However....
You really shouldn't be instantiating non-static inner classes of your Activities from outside of the Activity because in order to instantiate a non-static innner class, you have to actually instantiate the enclosing class, which, in this case, is the Activity. Activities are meant to be started, not instantiated via new. If you have an AsyncTask that you'd like to use in different places, then create a new top-level class that extends from AsyncTask.
(For an example of creating reusable AsyncTasks, see: https://github.com/levinotik/ReusableAsyncTask)
Note that the syntax you've tried to use WOULD work if you needed to grab a static nested class. This is because in such a case, the outer class is really just acting as a namespace, but the nested class, because its static, does not actually need a reference to an instance of the outer class. Thus:
OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();
is the proper syntax for getting an instance of a static nested class.
I guess your parseYouTubeAndYahoo class is an inner class in class MainActivity, in Java, you should instaniate an object of the inner class by new MainActivity().new parseYouTubeAndYahoo(), so call that method like this new MainActivity().new parseYouTubeAndYahoo().execute("someURL");
I also guess MainActivity extends the Activity class, so I think the answer should be this.new parseYouTubeAndYahoo().execute("someURL"); when you just call this method inside your MainActivity class.
It would be easier just to place AsuncTask into another file as a separete class.
But if you really want to have is an inner class, then either it has to be static or you need to obtain a reference to its parent class first, which could be done like this:
in onCreate of MainActivity:
static MainActivity activityInstance = getContext();
New method in MainActivity:
public static MainActivity getActivityInstance(){
return activityInstance;
}
Then in another activity you can get the instance and access its public methods
MainActivity instanceOfMainActivity = MainActivity.getInstance();
Then
new instanceOfMainActivity.parseYouTubeAndYahoo().execute("someURL");
Reference the context of activity to other class and use it.
Like that: public oneofconstructer(Context ctx, .....)

How to call method of another class in android

I have two different class(class A and Class B). i want to use the method of Class A in Class B. i normally used object for class A and called method in class B. but unfortunately i am getting Force close error. Is that any thing different to call a method of another class in android. I referred many articles in stackoverflow. but i cant understand properly. pls help me to find out the solution.
You should not create object like this, you should use context to call object like as below
((Class A) contextObject).function();
it runs perfectly on my system,
earlier class A and class B both are extending Activity and now only A extends Activity and B extends A and now B can call functions of A
this works for me:-
public class A extends Activity
{
functionOfA(){}
}
public class B extends A
{
//calling function of class A
functionOfA();
}
In case of Android, class which extends Activity will maintain its life cycle methods. if method which is defined in different class other current running activity may be killed or in pause state. so it is suggested that if method which is reusable in application should in different class for example (AppManager singleton class) rather than being in single activity class
u have to create constructor of class A
& in class B make an obj to class A
initialize it with
ClassA obj=new classA();
obj.method_A();
hope this will help
As I said in my comment, you shouldnt instantiate activities.
If your method uses some method that are called from a Context object, you can create a new class ( Class NewClass) that accepts a context parameter and implements your methods in it.
So this way, you can call your class from any activity:
NewClass nc = new NewClass(this);
Look up for some example of how to use a database in Android. It uses the same way.

Categories

Resources