Use of super class - java

I'm trying to follow an Android tutorial for caching bitmaps and looking at the sample code confuses me.
The code defines some utility classes as ImageFetcher, ImageResizer, and ImageWorker. Fetcher extends Resizer and Resizer extends Worker.
When Fetcher is called in the tutorial it invokes this code.
public ImageFetcher(Context context, int imageSize) {
super(context, imageSize);
init(context);
}
The super class Resizer invokes this code
public ImageResizer(Context context, int imageSize) {
super(context);
setImageSize(imageSize);
}
And finally the super class Worker invokes this code
protected ImageWorker(Context context) {
mResources = context.getResources();
}
What I don't understand is what resizing has to do with fetching, what working has to do with resizing, and why these classes are arranged like this. I'm trying to emulate something like this for my own app and was looking at what would be considered a good example but it only confused me further. I naively thought that you could simply have a class that does the fetching, not extended from one that did resizing (since they seem completely separate actions to me).
Yes I am new to Java as well.

Related

Are there any downsides to using a static class with multiple static AsyncTasks?

I made a static class (NetworkUtils.java) with a few static AsyncTasks, each sending some data to server and retrieving a response.
It is working great (in a test environment) and it made the code very clean in the Activities:
NetworkUtils.SomeNetworkingTaskCallbackInterface callbacks =
new NetworkUtils.SomeNetworkingTaskCallbackInterface() {
#Override
public void onFinished(String result) {
}
#Override
public void onFailed() {
}
};
NetworkUtils.SomeNetworkingTask task = new NetworkUtils.SomeNetworkingTask(callbacks);
task.execute();
Now I am doing a little extra research if there is anything wrong with this approach. I've seen a lot of use-cases of nested static AsyncTasks, but I need them completely decoupled and modular, that's why I put them into a separate static class. I can't think of any downside. Can someone more experienced weigh in?
The only disadvantages I can think about is that you won't have any access to non static members of the parent class. If for example, your static Async Task object had an Activity parent class you wouldn't be able to call methods that require a context. That means you won't be able to start services, activities or broadcast events from the Async Task.
However, you could simply pass a context object to the static class to solve that. But then what happens when your Async Task takes long and your activity gets destroyed before it's onFinish is called? You're get an error as your context object is from a destroyed activity.

Is there a way to delegate the implementation of an interface to a different class?

I've been working on Xamarin for the past couple of years along with Android studio and I decided to create an application for a friend (full source code here https://github.com/nekrull/waiter don't be too harsh please :) )
The idea is that there is a base activity which exchanges fragments when a new screen should appear.
Fragments have everything that has to do with user interaction and the activity they are attached to handles the business logic.
To do this I have a base class CoreActivity/DataActivity which has some methods most Fragments use (like blocking the back button) and some helper methods (like calling a method on an attached fragment of a specific class) , a CoreInteraction that responds to this activity and
CoreFragment/AttachedFragment which is used as the base of all view fragments
so for example the view fragment would look like this:
public class GroupsFragment extends AttachedFragment<GroupsFragment.GroupsInteraction> {
//this is what we expect to be able to call in the parent
public interface GroupsInteraction extends CoreInteraction {
Group get_shown_group();
void new_group();
void select_parent();
}
}
which is basically a fragment that expects its attached activity to be able to respond to the interaction methods.
the activity fragment would look like this:
public class MainActivity extends DataActivity<MainData> implements
GroupsFragment.GroupsInteraction, (other interactions here) {
}
The problem is that since the application I'm working on has only one Activity with many small screens, the code inside the base activity will get big, that does not cause a problem with the application or compiling or anything else. But it makes it really hard to find what I'm looking for easily.
What I used to do in Xamarin is something like this:
public partial class MainActivity : DataActivity<MainData> {
}
for the initialization activity and then each interaction would get its own file like this:
public partial class MainActivity : GroupsInteraction {
}
It had the same effect (since the class is compiled as a single class) but the code would be tidy and easy to read.
Obviously there are no partial classes in Java, but is there a way to delegate the implementation of an interface to another class?
Something along the lines of saying "when you're invoking a method from interface a, invoke it from that class" without actually writing stuff like :
public Group get_shown_group() {
return new GroupHandler(this).get_shown_group();
}
public void new_group() {
new GroupHandler(this).new_group();
}
public void select_parent() {
new GroupHandler(this).select_parent();
}
Thanks in advance for any help you can provide
Something along the lines of saying "when you're invoking a method from interface a, invoke it from that class"
Taking you literally what you describe is plain delegation, a class does not implement some or any functionality itself, instead it wraps a class implementing the desired functionality, calling the methods of said wrapped class. You could even switch implementation at runtime, just changing the wrapped class as you go (assuming the classes share a common interface, of course). Of course that does not "spare" you from writing the delegations yourself.
class Wrapper implements GroupsInteraction {
private final GroupInteraction gi;
public Wrapper(GroupsInteraction gi) {
this.gi = gi;
}
Group get_shown_group() {
return this.gi.get_shown_group();
}
// ... other interface impls
}
Additionally, you should keep the GroupHandler as a member instead of creating a new Object each time, so
public Group get_shown_group() {
return new GroupHandler(this).get_shown_group();
}
becomes
public Group get_shown_group() {
return this.groupHandler.get_shown_group();
}
You can try Delegation Pattern
BaseActivity {
MyDelegateClass delegate;
void example() {
delegate.example();
}
}
P.S. both activity and delegate implements same interface
Details here

Getting Dagger Component without access to Application

I want to use injecting in classes like Adapter or custom object, which don't have access to MyApplication class which extends Application.
How can I get access to component?
Is it good approach to use static methods like below?
public class MyApplication extends Application {
private static MyComponent component;
#Override
public void onCreate() {
super.onCreate();
component = DaggerMyComponent.builder()
.appModule(new AppModule(this))
.helperModule(new HelperModule())
.build();
}
public static MyComponent getComponent(){return component;}
}
I think using static objects in this case would cause memory leaks.
What you might follow is "Inject everything" pattern shown in this great article.
What is it's essence? Try to inject the object that needs Component inside the object that is already injected. In this article Adapter and ViewHolder (any object) is injected into activity (and objects inside adapter too). This is what you are trying to achieve.
I also advise you to read all his articles about Dagger 2, as I haven't seen such a great and advanced tutorial on Dagger 2 features

Implementint View.isInEditMode()

I forked Apollo recently from CyanogenMod project for experimenting, this app uses custom views for theming mainly. I am usung AndroidStudio an this IDE requires custom views to implement View.isInEditMode() method to bypass context loading when editing layout.
So I have something like this:
public class CustomButton extends ImageButton
implements OnClickListener, OnLongClickListener {
private final SomeUtililtyClass mResources;
public CustomButton(final Context context, final AttributeSet attrs) {
super(context, attrs);
// Handle editing layout from IDE
if(!isInEditMode()) {
mResources = new SomeUtililtyClass(context);
// do more stuff
}
// some methods
}
Problem is that i have some methods that use mResources that is not always initialized giving me a Java compiler error.
There is an standard way to handle this or should I initialize mResources to null or an empty object?
It is necesary to remove the final modificator?
There's not really a standard way or tricks, it's up to you.
View.isInEditMode() returns true when your class is instantiated under the IDE (the class is really executed), so it's a run-time method rather than a compiler-known value.
In the case you propose, initializing to null and removing final would do it, seems simple. Or maybe,if you want to keep the final keyword, you can pass a NULL context tho the SomeUtilityClass constructor if isInEditMode() and make it just return without executing the conflicting operation.
In my experience, normally doing in the first line of the constructor
if (isInEditMode()) return;
is enough for most classes. But if your class does custom drawing (onDraw / draw / dispatchDraw) you'd need to check it there as well.
At the moment it looks like Eclipse doesn't process click handlers, but this can change in the future.

How to retrieve a context from a non-activity class?

I have found one answer that appears to say I should create a separate class and make a static MyApplication object and make a get method. Then any class can call MyApplication.get() to retrieve the context.
Is there any other cleaner way? This is my situation:
I have a class A and a class B. Class A contains an object from class B (let's call the object b). In class A I call, "b.play()". However, I get a null pointer exception because class B needs to pass a context to the MediaPlayer.create() method.
Until now I threw together a hack and from class A I called.... "b.play(this)" and simply passed the context to B. However that is pretty ugly and looks like a bad use of OOP.
Any thoughts?
This problem seem to arise a lot in Android development. One solution to obtaining a reference to a specific Context is subclassing the Application and grab a reference to the Context which you want.
public class MyApplication extends Application {
private Context context;
#Override
public onCreate() {
super.onCreate();
this.context = getApplicationContext() // Grab the Context you want.
}
public static Context getApplicationContext() { return this.context; }
}
This solution however requires that you specify the name of your subclass in your manifest.
<application
android:name=".MyApplication"
</application>
You can then use this anywhere in your application like this in non-activity classes.
MyApplication.getContext(); // Do something with the context! :)
If class B requires a Context to operate, then I don't see any problem having class A provide that to it (through a parameter on the play method, a parameter in a constructor, etc).
I don't think you are doing any poor OOP by providing class B the dependencies that it needs to do it's job.
Passing this around is a viable way of doing things, especially if this is the activity that creates the object in need of a Context. Sometimes, I'll put the Context into the constructor (like public MyObject(Context context){this.context = context;}), so that you don't need to send it every time. However, if your object is shared across multiple Activities, you should probably update the context it is looking at with the new Activity, though I haven't tested what happens if you use the old activity.
I've answered also here.
You can do that using ContextWrapper, as described here.
For example:
public class MyContextWrapper extends ContextWrapper {
public MyContextWrapper(Context base) {
super(base);
}
public void someMethod() {
// MediaPlayer.create(this, ...)
}
}

Categories