I'm using common code in my Activity like this:
abstract class CommonCode extends Activity {
//Common Code here...
}
then in my "Activity" I extend CommonCode instead of Activity and it all works fine.
My problem arise when I try to use commoncode in a PreferenceActivity, I tried:
abstract class CommonCode extends Activity {
class CommonCodePreferences extends PreferenceActivity {
}
//Common Code here...
}
but it isn't right.
How can I do it?
May I suggest that you prefer composition over inheritance and do something like this:
abstract class CommonCode {
Activity parent;
public CommonCode(Activity activity) {
parent = activity;
}
}
class MyActivity extends Activity {
CommonCode commonCode;
public MyActivity() {
commonCode = new CommonCode(this);
}
}
This is a little more code to write in each activity, but it has a lot of advantages:
It can also easily handle PreferenceActivity and other classes
It is easier to test and mock
I usually have one each since you can't mess with the existing hierarchy of the base classes.
For example, I have an ActivityBase, ServiceBase, ListActivityBase, etc. If you want to have common code that they all use, I would suggest using composition - each of your base classes has a single instance of your CommonCode class or something to that effect. Another possibility is to use static methods and/or use a custom Application class (requires declaring the custom Application class in the manifest in the name attribute of the application element)
Related
There is an asynckTask and 2 methods,which are being called by 2 activities.
i Want to keep the AsyncTask class and the methods inside myApplication class
http://developer.android.com/reference/android/app/Application.html
( which was needed anyway,had some states of app to be maintained).
One other way is to have those methods in each activity and the asyncTask as independent class.
what is the best way?
How about having a base activity class for that?
Something like:
public class BaseActivity extends Activity {
protected void myMethod() {
// do what ever
}
}
Then just extend this BaseActivity to have that method in your activities.
I'm trying to understand concept of MvP design pattern. I mean, I get it, its quite easy. The main problem is optimal implementation. I tried to make my own BaseActivity, BasePresenter and BaseView just to extract part of a joint from all of my activities, I've done this this way:
BaseActivity
public abstract class BaseActivity<T extends BasePresenter<? extends IBaseView>> extends FragmentActivity implements IBaseView {
protected T presenter;
private ActivityConfig activityConfig;
#Override
final protected void onCreate(Bundle savedInstanceState) {
activityConfig = getConfig();
super.onCreate(savedInstanceState);
presenter = createPresenter();
setContentView();
initLibraries();
prepareView(savedInstanceState);
addFragments();
}
protected abstract ActivityConfig getConfig();
protected abstract T createPresenter();
protected abstract void prepareView(Bundle savedInstanceState);
protected abstract void addFragments();
private void setContentView(){
View root = View.inflate(this, activityConfig.layoutId, null);
setContentView(root);
}
private void initLibraries() {
ButterKnife.bind(this);
Timber.plant(new Timber.DebugTree());
}
#Override
public BaseActivity getCurrentContext() {
return this;
}
#Override
public T getPresenter() {
return presenter;
}
}
BasePresenter
public abstract class BasePresenter<T extends IBaseView> {
public abstract void loadData(boolean refresh);
}
BaseView
public interface IBaseView {
BaseActivity getCurrentContext();
BasePresenter getPresenter();
}
It works fine but I feel like this is bad designed so I want to use Mosby instead. The problem is that all of the tutorials don't touch aspect of base classes, they just use Mosby's ones as base (with is bad I suppose? couse I have to duplicate my code (Butterknife.bind() for example). So can you guys give me some good designed quickstart classes for Mosby MVP or give me some tips how should I divide my project? Thanks!
So I see two possibilities:
You could extend from Mosby's MvpActivity as your base class and add your staff like initView(), initLibraries() etc. So that BaseActivity<P extends BasePresenter<? extends BaseView>> extends MvpActivity<P> implements BaseView. Then MyFooActivity extends BaseActivity<FooPresenter>. So you include Butterknife once in BaseActivity and it should work. However, you might have to duplicate that code like Butterknife.bind()` for Fragments, as Activity and Fragments obviously don't have the same super class. I will show you how to solve that above.
Do the other way around: Integrate Mosby's functionality into your BaseActivity. Mosby is build with the principle of "favor composition over inheritance". So what does this actually mean? Mosby offers a ActivityMvpDelegate. As the name already suggests this delegate does all the work of instantiating Presenter etc. But instead of inheriting from MvpActivity you use this delegate and invoke the corresponding delegate methods. Actually Mosby's MvpActivity is doing exactly that if you have a look at the source code. So instead of extending from Mosby'sMvpActivity you simply use MvpActivityDelegate in your BaseActivity.
So what about duplicating code like Butterknife.bind() i.e. in Activity and Fragment. Well, Mosby can share his code like instantiating Presenter etc. between Activity and Fragment because both use the mosby delegate.
So you could apply the same principle: You could put the shared code into a delegate and call the delegate from both, activity and fragments.
The question is: is it worth i.e. Butterknife.bind() is just one single call. You would also have to make one single call yourDelegate.doSomething() ...
But if you have to reuse "critical code" between activity and fragments then favor composition like Mosby does.
If you know that you are only working with Activites then extending from Mosby's MvpActivity would also be a good option as described in 1. solution.
I just wanted to add to sockeqwe's first answer.
It is perfectly fine to create your own base class where it makes sense. It's also pretty straightforward.
For example, I needed to create a base Fragment with some default behavior. All you need to do is duplicate the base generic type signature and pass it along to the base class.
For example:
public abstract class MyBaseFragment<V extends MvpView, P extends MvpPresenter<V>> extends MvpFragment<V, P>
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.
I want to use different AsyncTaskLoaders (different in their return type) in my Activity, what's the best way to implement the callback methods?
This won't work:
public class MyActivity extends Activity implements
LoaderManager.LoaderCallbacks<MyPojo>,
LoaderManager.LoaderCallbacks<MyOtherPojo>
Eclipse says
The interface LoaderCallbacks cannot be implemented more than once with different arguments
So what do I do? My idea is to make the Activity
implements LoaderManager.LoaderCallbacks<Object>
then check in the callback methods what type of object it is but that doesn't seem too elegant. Is there a better way?
What about creating an inner class for each callback?
public class MyClass extends Activity {
private class Callback1 implements LoaderManager.LoaderCallbacks<MyPojo> {
...
}
private class Callback2 implements LoaderManager.LoaderCallbacks<MyOtherPojo> {
...
}
}
In my android project, I have many activities and some of them already extend other stuff like map activity or BroadcastReceiver.
How do I create a function that I can call from any activity, because I don't want to have to repeat any code in multiple activities.
thanks.
If I have useful functions that perform little helpful tasks that I want to invoke from several Activities, I create a class called Util and park them in there. I make them static so that I don't need to allocate any objects.
Here is an example of part of one such class I wrote:
public final class Util {
public final static int KIBI = 1024;
public final static int BYTE = 1;
public final static int KIBIBYTE = KIBI * BYTE;
/**
* Private constructor to prevent instantiation
*/
private Util() {}
public static String getTimeStampNow() {
Time time = new Time();
time.setToNow();
return time.format3339(false);
}
}
To use these constants and methods, I can access them from the class name, rather than any object:
int fileSize = 10 * Util.KIBIBYTE;
String timestamp = Util.getTimeStampNow();
There's more to the class than this, but you get the idea.
You can extend the Application class, then in your activities call the getApplication method and cast it to your application class in order to call the method.
You do this by creating a class that extends android.app.Application:
package your.package.name.here;
import android.app.Application;
public class MyApplication extends Application {
public void doSomething(){
//Do something here
}
}
In your manifest you must then find the tag and add the android:name="MyApplication" attribute.
In your activity class you can then call the function by doing:
((MyApplication)getApplication()).doSomething();
There are other ways of doing something similar, but this is one of the ways. The documentation even states that a static singleton is a better choice in most cases. The Application documentation is available at: http://developer.android.com/reference/android/app/Application.html
You could create a static method or an object that contains this method.
You can create a class extending Activity, and then make sure your real activities are subclasses of that activity, instead of the usual built-in one. Simply define your common code in this parent activity.
Shachar
Create a new Java class BaseActivity with abstract Modifiers and extends it with AppCompatActivity.
Move all your methods under Java class BaseActivity.
package com.example.madbox;
public abstract class BaseActivity extends AppCompatActivity {
protected void YourClass() {
}
}
Extends your Activities with BaseActivity but not AppCompatActivity.