Is it possible to invoke a method from abstract class? - android

I have the Abstract class as following:
AbstractFilePickerFragment.java
public abstract class AbstractFilePickerFragment<T> extends ListFragment
implements LoaderManager.LoaderCallbacks<List<T>>
....
....
public void GoBackToPreviousDirectory() {
currentPath = getParent(currentPath);
refresh();
}
}
OtherActivity.java
private AbstractFilePickerFragment<T> mAbstractFilePickerFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_ACTION_BAR);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
//THIS LINE SAYS "Cannot instantiate the type AbstractFilePickerFragment"
mAbstractFilePickerFragment = new AbstractFilePickerFragment();
}
public void GoBackToPreviousDir_onClick(MenuItem item) {
mAbstractFilePickerFragment.GoBackToPreviousDirectory();
}
}
Does anyone if it is possible to invoke the GoBackToPreviousDirectory from AbstractFilePickerFragment class???
I know a static method would work, but I can't make a static method for this situation.
Thank you so very much for the help

No. First, you do not invoke methods from classes. You invoke object methods as object is instance of class. Abstract class cannot be instantiated.

In order to call a non-static method, you have to instantiate the class.
Abstract classes cannot be instantiated, by definition. So Answer is NO
If you still need to access the method, You will have to create a class that extends the abstract class and implement all of the methods in the class. Then you can instantiate the extended class within your program and call the method.

Related

How to get context in moxy presenter android

How do I can get activity context from Moxy presenter?
At first sight it's very easy...: 1. Add Context getMvpActivity (); into MvpView interface and implement it in Acivity.
2. And in a presenter call getViewState().getMvpActivity().
But Moxy don't allow to add the non-void methods to MvpView interface.
Pls help me.
P.S. I need context in the Presenter to init App Component(activity is a param for static getter).
Thanks. Sorry for some grammar mistakes.
Right solution is not using activity context in the presenter. Because, in case of activity recreation, this context will leak (because presenter will be still alive). You able to use application context. You can pass it through presenter's constructor.
Solved this problem with adding a Activity context as a param into onViewCreated().
Like this:
//presenter super class
public void onViewCreated (Activity activity) {
//init component here
//this.component = ...
injectPresenter ();
}
protected PresenterComponent getComponent () {
return this.component;
}
protected abstract void injectPresenter ();
//presenter child class
#Override
public void onViewCreated (Activity activity) {
super.onViewCreated(this);
}
#Override
protected void injectPresenter () {
//you can name "inject" different ways
//in your presenter component interface
getComponent().inject(this);
}
//activity class
#Override
protected void onCreate () {
//P.S.(for beginners) variable presenter is the object of class
//which extends Presenter super class
presenter.onViewCreated(this);
}

can a singleton class extend Activity

I am using a singleton class to store global variables for the entire project. Also, to host some common functions which several classes/Activities may use, such as launching an alertBuilder window. But in order to do that... I need my singleton to extend Activity like this:
public class dataBaseObject extends Activity {
I tried to extend application, but that won't allow me to do this:
View view = context.getLayoutInflater().inflate(layoutType, null);
therefore, can someone tell me if there are any hidden pitfalls of extending Activity for a singleton ?
It doesn't make sense for an Activity class to be a singleton, because instances of Activity are instantiated by the android system.
What you can do is make an abstract class that extends Activity, like this
public abstract class AbstractActivity extends Activity {
public static final int EXAMPLE_CONSTANT = 345;
public final void exampleMethod() {
...
}
// This may not be needed
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
....
}
}
Then you can make all of your activity classes extend AbstractActivity. You do not need to declare an abstract class like this in manifest.xml.
An alternative solution is to make all of your utility methods have a parameter that is an Activity or a Context and pass this to these methods.

android passing data from class to activity

I have been looking for a long time for a simple way to pass data (string type) from class to activity.
I found some tutorials about passing data from activity to class but is it possible to do the opposite, passing data from class to activity ?
if you import the class in your activity (which is also a class by the way) you can easily access the classes attributes.
example: MyClass.java
package edu.user.yourappname;
public class MyClass {
public string infoToPass = "whatever";
}
MyActivity.java
package edu.user.yourappname;
import edu.user.yourappname.MyClass
public class MyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
String myString = MyClass.infoToPass;
}
}
i have no IDE to type this in atm it might contain some errors :S but i hope you get the idea.
if you need more specific help you have to provide a code sample.
also, what do you want to achieve exactly? maybie there's a different approach.
cheers!
Create Interface and implement that in your activity. Pass the activity instance in your class and and call that instance with interface method whenever you like.
To be more clear, create an interface and use it as following:
public interface SomeInterface{
public void passValue(String value);
}
public SomeActivity extends Activity implements SomeInterface{
// place any code you want in your activity, onCreate, onResume, etc.
private void someMethod(){
// Wherever in your activity, initialize your class with your activity.
SomeClass someClass = new SomeClass(this);
someClass.someMethod();
}
public void passValue(String value){
// do whatever you want with your value
}
}
public class SomeClass{
private SomeInterface someInterfaceInstance;
public SomeClass(SomeInterface someInterfaceInstance){
this.someInterfaceInstance = someInterfaceInstance;
}
public void someMethod(){
// Some code...
someInterfaceInstance.passValue("Hello World!");
// Some more code...
}
}
Here is a easy way of doing it -
By defining static variables
In your class, make the String whose value you want to pass public static like this -
public static String pass;
And then in you activity, you can directly access it since it's a public variable like this -
String receive = className.pass;

Android - OnClick Listener in a separate class

Is it possible to make a secondary class to hold the OnClick Listener? Meaning not being created in the Activity class?
I just find that putting OnClick listeners in the main activity class is just messy and I would rather have them in separate classes. Thanks
Sure, that's possible. Just create a class that implements View.OnClickListener and set that as listener to the View. For example:
public class ExternalOnClickListener implements View.OnClickListener {
public ExternalOnClickListener(...) {
// keep references for your onClick logic
}
#Override public void onClick(View v) {
// TODO: add code here
}
}
And then set an instance of above class as listener:
view.setOnClickListener(new ExternalOnClickListener(...));
The parameterized constructor is optional, but it's very likely you'll need to pass something through to actually make your onClick(...) logic work on.
Implementing a class anonymously is generally easier to work with though. Just a thought.
Instead of putting the onCLicklistener in a separate class, why dont you try to define onClickListener outside onCreate()??
For e.g: like this
onCreate()
yourViewName.setOnClicklistener(listener):
Outside onCreate()
private OnClickListener listener = new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
};
Yes you can. However, making the listener an inner class has one advantage - it can access the fields and variables of your activity class directly. If you make it a separate class, and your listener actually need to access 5 views, your listener constructor might look like this:
MyListener listener = new MyListener(context, button, textView1, textView2, ratingBar, imageView);
Which is kinda bulky too. If your listener is simple, go ahead and make it a separate class. Otherwise, its up to you for readability.
Let me share how I code it using MVP. It's the best way to make clean code. Remember each class must have an interface to control it. I will show you the simplest one.
Suppose you want to Toast a text onClick and control it from another class. Here's how it works. Creating interfaces is for nothing but to connect with each other and you can review the code easily.
Create an interface for that MainActivity class.
public interface MainActivityView {
void showToast();
}
Create another interface for the Presenter class.
public interface IMainPresenter<V extends MainActivityView> {
/*Generic Type is to make sure it comes from MainActivity class only and to avoid other class to access it.*/
void onAttach(V mainView);
void onButtonClick();
}
Remember interfaces are nothing but to override method for each class.
Create a Presenter class
public class MainPresenter<V extends MainActivityView> implements IMainPresenter<V> {
private V mainActivityView;
#Override
public void onAttach(V mainActivityView) {
this.mainActivityView=mainActivityView;
}
public V getView() {
return mainActivityView;
}
#Override
public void onButtonClick() {
getView().showToast(); //This is the method from MainActivity controlling with this class
}
}
I'll skip, activity_main.xml layout because there's just a button with id="#+id/buttonId." In MainActivityClass,
public class MainActivity extends AppCompactActivity implements MainActivityView {
Button btn;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainPresenter mainPresenter = new MainPresenter();
mainPresenter.onAttach(this);
btn = findViewById(R.id.buttonId);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mainPresenter.onButtonClick(); //Here, check No.3 again!
}
});
}
#Override
public void showToast() {
Toast.makeText(this, "Hello", Toast.LENGTH_SHORT).show();
}
}
All I want to tell you is that. If you create objects in a class, it cannot make unit testing. That's why you're not seeing any new objects calling in android. So, you can use a singleton pattern (Here is Lazy Type) in Presenter class. I'll remove its interface and Generic to see it clearly.
public class MainPresenter {
private static final MainPresenter mainPresenter = new MainPresenter();
MainPresenter() {}
public static MainPresenter getInstance() {
return mainPresenter;
}
//Some methods here can be get it once you create an object with getInstance();
}
And so you can get its methods from MainActivity like this.
Instead of creating objects like this...
MainPresenter mainPresenter = new MainPresenter();
You can get it like this...
MainPresenter mainPresenter = mainPresenter.getInstance();
More example for singleton pattern can be found here,
https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples
Finally, using static is not a very good choice because it uses memory space whether you use it or not. And so, you can create objects within Application Layer get it with a Typecasting. I'm sure you don't need to unit test that Application layer.
public class AppLayer extends Application {
private MainPresenter mainPresenter;
#Override
public void onCreate() {
super.onCreate();
mainPresenter = new MainPresenter();
}
public MainPresenter getMainPresenter() {
return mainPresenter;
}
And you need to give a class name within Application in manifest.xml
<application
android:name=".AppLayer"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
</application>
And you can get it with a Typecast in MainActivity like this!
MainPresenter mainPresenter = ((AppLayer)getApplication()).getMainPresenter();
For further studies, I suggest you learn ButterKnife, Dagger 2 and SOLID Principles. It will help you to create clean coding. Have fun!
You can do it. But just think that you will not have a reference to the activity, neither to it's attributes, including all the views. (unless you make them public or accessible with getters methods).
Also, be extra carefull with storing references to the activity or any members on the listener, since they might avoid the garbage collector from getting the listener memory back.
public class CommonClick {
public static void commonClick(final AppCompatActivity context){
context.findViewById(R.id.appbar).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
}

How to access the variables that are in void onCreate class from another class (both are under activity subclass)?

I am trying to access some of the onCreate class variables from another class that is under activity class, for example
..Acivity class(..)
Class onCreate(..){
Final int intItemNo = 0;
}
Class testing(){
//some commands here, will need access to the intItemNo above.
}
};
Place the variable definition outside of the onCreate Class. I am assuming this code is from an activity class so onCreate is really a method not a class. It does not change the answer though. If it is not, onCreate is not a good name for class as it conflicts with an android method.
public class1 extends Activity {
Final int intItemNo;
public void onCreate(..){
intItemNo = 0;
}
Class testing(){
intItemNo = 1;
}
}

Categories

Resources