Is there a way to replace the default Activity class with own implementation extending from this class using roboguice?
For instance an activity like this:
public class MyActivity extends Activity
{...}
would replace the default Activity class and would become the base activity for all other derived activities.
Yes. The easiest way is to have your base activity extend from RoboActivity.
Eg.
class MyBaseActivity extends RoboActivity { ... }
And then have all of your activities extend from MyBaseActivity.
However, if for some reason you don't wish to extend from RoboActivity, you can easily add injection to your own activities by doing the following:
class MyBaseActivity extends Activity {
public void onCreate(Bundle b) {
super.onCreate(b);
RoboGuice.getInjector(this).injectMembersWithoutViews(this);
}
public void onContentChanged() {
super.onContentChanged();
RoboGuice.getInjector(this).injectViewMembers(this);
}
}
Take a look at RoboActivity's source for more details. As long as you don't need events, the changes required are quite simple.
Related
I have one activity with a webview in it.
When the user interacts with the webview, it does this through the JavaScriptInterface so both the app and webview can interact with each other.
I believe the class is by default static, so I've found not too much can be done without it extending MainActivity.
public class JSInterface extends MainActivity {
private MainActivity mainActivity;
JSInterface(Context context, MainActivity mActivity) {
mainActivity = mActivity;
}
#JavascriptInterface
public void someMethod() {
mainActivityMethod(webViewData);
}
// other methods
}
In my MainActivity I have:
WebView webView = findViewById(R.id.webView);
JSInterface JSInterface = new JSInterface(this, this);
//other methods called by JSInterface, e.g.
#Override
public void mainActivityMethod(String webViewData) {
// do something with data
}
So I've found by extending to MainActivity from JSInterface, I can call normal (non-static) methods from MainActivity which is very much a necessity.
If I don't extend it to MainActivity, it seems to be a static class and I get this error when trying to call MainActivity methods or reference anything not static:
Non-static method someMethod() cannot be referenced from a static context.
It works as it is, but I feel like this isn't the best way to go about it.
Am I right?
What would be the 'best' way to do this? Or other ways, as best is subjective.
I feel like this isn't the best way to go about it
Never create a subclass of Activity unless you are going to start it with startActivity().
What would be the 'best' way to do this?
One option is simple composition, getting rid of the improper inheritance:
public class JSInterface {
private MainActivity mainActivity;
JSInterface(MainActivity mActivity) {
mainActivity = mActivity;
}
#JavascriptInterface
public void someMethod() {
mainActivity.something(webViewData);
}
// other methods
}
Another is a nested class. In this sample activity, Locater is a nested class inside of my GeoWebOne activity, and therefore Locater can call methods and access fields in GeoWebOne. The simple composition approach is a better answer, though a nested class will work.
I have an activity A which contain 7 fragment. For communication between fragment to activity and fragment to fragment, My activity explictly declare Fagment interface of all the 7 fragment.
The Syntax is like
class A extends Activity implements B.onInteraction, C.onInteraction, D.OnInteration .... {
}
This becomes long and i don't like explicity declaring it in on top of activity.
The other solution i can think of is define a method setOnInteractionListener() in each fragment and pass anonymous class to it like.
class B extends Fragment {
public void setOnFragmentInteractionListener(OnFragmentInteraction listener) {
}
}
By this way i don't need to override onAttach() of fragment and i don't need to explicty declare fragment interface on top.
My Question is: Is this a good way of doing things? What are the cons of using anonymous class here. Is there any better approach to do this or i should stick to explictly declaring interface while creating activity.
I'm not sure if I understand the question cause I'm a beginner. In my oppinion can create an interface for all your fragments:
public interface ActivityListener {
void onCall(Fragment fragment);
}
your activity:
public class MainActivity extends AppCompatActivity implements ActivityListener {
#Override
public void onCall(Fragment fragment) {
switch (fragment.getTag()) {
case YOUR_TAG:
Log.d("listener", "called");
break;
}
}
}
in your fragment use onAttach() method to get the interface.
I prefer to use EventBus (especially https://github.com/greenrobot/EventBus, someone prefer http://square.github.io/otto/) to communicate between Fragments and Activity.
You need to register (and unregister) the listener (activity, for example, or another fragment) and create a method with onEvent(<CustomEventclass> event);
EventBus.getDefault().register(this); //and unregister
And just post the event from the fragment like
EventBus.getDefault().post(<CustomEventClass> instance);
Making BaseFragment and pass the listener is also a normal way. This is just a developer choice.
I'm using Roboguice to inject my dependencies but it's not workink. I have a class that extends RoboActivity and my attribute still null.
public class SplashActivity extends RoboActivity {
#Inject
private PropertyReader propertyReader;
#Inject
Vibrator v1;
}
Should i do some aditional config?
Thank in advance.
Edit: it only works if i do RoboGuice.injectMembers in every class that i have objects to injects. Can i do it only one time for the whole app?
You should use the injected non view fields after the activity onCreate. InjectMembers runs in super.onCreate(savedInstanceState) you dont have to call it.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
v1.vibrate();
}
view fields should be used after onCreateView() is called.
I've created some animations for activity transition. But the code for overriding each activity's transition is kind of boilerplate code, how can I overcome this, meaning writing the code once and being applied to every activity?I'm guessing something with inheritage ?
class BaseActivity extends Activity {
public void transition {
overridePendingTransition(R.anim.push_down_in, R.anim.push_down_out);
}
}
class SubActivitiy extends BaseActivity {
public void applyTransition {
transition();
}
}
I'm writing an application in which i have a set of code which i want to be available in all of my Activities and ActivityGroups. However, to achieve this, I have extended my activities as:
//custom Activity
public abstract class BaseActivity extends Activity
//custom ActivityGroup
public abstract class BaseActivityGroup extends ActivityGroup
//implemented activities in my app
public class PickUser extends BaseActivity
//and
public class Home extends BaseActivityGroup
Now the thing is, whatever the custom code i write in BaseActivity, I have to write the same in BaseActivityGroup too (as in current implementation). This is prone to code-sync problems and i believe not a good technique.
So, how can i make my extensions in such a way that I only write custom code in BaseActivity and my BaseActivityGroup extends ActivityGroup - which is conceived from BaseActivity class?
If i observe how android does this, so the ActivityGroup in android extends Activity class. And I also want to write my custom ActivityGroup class (known as BaseActivityGroup) that actually extends BaseActivity (which is an extended Activity).
Any ideas/suggestions?
First of all ActivityGroups are bad and should not be used. They are deprecated and it is preferred to use a single activity with multiple fragments.
If you must use an activitygroup you are probably best of by implementing a delegate pattern.
Create a delegate that handles all the common methods such as onCreate, onResume and use that in the bases. In this example I save a reference to the activity in the delegate. This circular referencing might not be the pretties. An alternative is to pass on the activity to the methods in the delegate.
public class ActivityDelegate() {
private Activity mActivity;
public ActivityDelegate(final Activity activity) {
mActivity = activity;
}
public void onCreate(final Bundle savedInstanceState) {
// Do stuff.
}
}
public abstract class BaseActivity extends Activity {
private ActivityDelegate mDelegate = new ActivityDelegate(this);
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDelegate.onCreate(savedInstanceState);
}
...
}
public abstract class BaseActivityGroup extends ActivityGroup {
private ActivityDelegate mDelegate = new ActivityDelegate(this);
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDelegate.onCreate(savedInstanceState);
}
...
}
Add an extra final class, called Base.
This one will only contain methods to be called by the other Base classes, such as for instance:
public static boolean createOptionsMenu(final Menu menu,
final MenuInflater inflater) {
inflater.inflate(R.menu.main_menu, menu);
return true;
}
Then, in your BaseActivity and BaseActivityGroup classes, you would call:
#Override
public final boolean onCreateOptionsMenu(final Menu menu) {
return Base.createOptionsMenu(menu, getMenuInflater());
}
Hope it helps!
Just Extend everything to BaseActivity including BaseGroupActivity as everything is a child of Activity in android
you can put your login in a separate file under a method. now call the same method from both BaseActivity and BaseActivityGroup if you need activity instance in file . pass context through constructor