In android IPC using binder, when we create an aidl file, build will automatically generate a stub class extending binder and override all the aidl methods right?.
In the service class implementation for the aidl methods , have seen instantiating the stub class generated instead of extending the stub class.Since stub class is abstract , how can it be instantiated?
The question was generic related to interface instantiation. As we know interface can not be instantiated but code like below:
interface in = new in() {
public void test(){
return "ok";
}
}
is possible as I am defining what the instance need to be done.
Related
im using frida , and would like to know how to change the (implementation) of sayHi method if the banana class is loaded dynamically
Class banan_dynamically_loaded
{
Public void sayHi()
{
console.log("hi");
}
}
And i know about reflection and hooking the dexclassloader class and overload the Loadclass method, but that only allow me to invoke the method sayHi not changing it's implementation
I have an interface method in a library which is being called by a method in the same library. The implementations are in the applications which include the library. The implementations are different for every application. In order to call the interface method, the calling method must instantiate the interface with its implemented class. But since the calling method is in the library, it has no access to the classes in the applications. The calling method is started by a background service and not by the application.
The interface in the library:
public interface InterfaceA {
void methodA();
}
The class in the application which implements the interface:
public class ClassA implements InterfaceA {
#Override
public void methodA() {
// do something
}
}
The method in the library which calls the interface method:
public void callInterface() {
InterfaceA ia;
ia.methodA(); // how to get this to work?
}
How do I call the interface method from the library without any access to the interface implementations in the applications? I cannot instantiate the interface from my library as the implementation classes are in the application which the library has no access to.
You don't need to do anything to get it to work if you have an instance of the interface:
public void callInterface(InterfaceA ia) {
ia.methodA();
}
And then add this parameter to the library methods which call this method, and so on. When applications call this method, they can pass their implementations.
Or if you really need to instantiate the interface inside the method, add another interface:
public void callInterface(Supplier<InterfaceA> iaSupplier) {
InterfaceA ia = iaSupplier.get();
ia.methodA();
}
See https://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html.
The calling method is started by a background service and not by the application.
And what starts the background service? You need to add some way for the application to pass the implementation to it.
Alternately, you could use SPI (https://docs.oracle.com/javase/tutorial/ext/basics/spi.html) but it may be overkill.
public void callInterface() {
InterfaceA ia;
ia.methodA(); // how to get this to work?
}
Above should result in compilation problem.
The library function should take as parameter the Interface InterfaceA in method as shown in another answer Or If it is a stateless implementation then pass it while using the Class that contain this method.
I am having problems injecting a generic type interface. Not sure how to do this or google it since I don't know the exact terms to search for. Sorry if i'm completely wrong just getting started with dagger.
Basically I have a use case class
public class LoadConversations<C extends IConversation>
extends UseCase<List<C>, LoadConversations.Type> {
private final IConversationRepository<C> messageRepository;
#Inject LoadConversations(#NonNull IConversationRepository<C> messageRepository) {
this.messageRepository = messageRepository;
}
....
public enum Type {
ALL, NEWER, OLDER
}
}
With IConversationRepository being an interface.
public interface IConversationRepository<C extends IConversation> {
Observable<List<C>> conversations(LoadConversations.Type params);
}
IConversation being a blank interface and ConversationModule where i provide the IConversationRepository.
Im having problems injecting with the following code. Am i missing something or doing something completey wrong. Thanks in advance.
Trying to provide as follows:
#Provides IConversationRepository<Conversation> provideConversationRepository(
ConversationRepository conversationRepository) {
return conversationRepository;
}
And I'm trying to inject this to my presenter as
private final LoadConversations<Conversation> loadConversations;
#Inject public ConversationListPresenter(LoadConversations<Conversation> loadConversations) {
this.loadConversations = loadConversations;
}
Implementation of ConversationRepository
public class ConversationRepository implements IConversationRepository<Conversation> {
#Override public Observable<List<Conversation>> conversations(LoadConversations.Type params) {
....
}
}
Error Log:
Error:(15, 10) error: com.rbttalk.android.data.repository.ConversationRepository cannot be provided without an #Inject constructor or from an #Provides-annotated method.
com.rbttalk.android.data.repository.ConversationRepository is injected at
com.rbttalk.android.di.module.sub_modules.ConversationModule.provideConversationRepository(conversationRepository)
com.rbttalk.android.domain.repository.IConversationRepository<com.rbttalk.android.domain.models.Conversation> is injected at
com.rbttalk.android.domain.usecase.conversation.LoadConversations.<init>(arg0, …)
com.rbttalk.android.domain.usecase.conversation.LoadConversations<com.rbttalk.android.domain.models.Conversation> is injected at
com.rbttalk.android.ui.main.conversation.ConversationListPresenter.<init>(loadConversations)
com.rbttalk.android.ui.main.conversation.ConversationListPresenter is injected at
com.rbttalk.android.ui.main.conversation.ConversationListFragment.userListPresenter
com.rbttalk.android.ui.main.conversation.ConversationListFragment is injected at
com.rbttalk.android.di.component.ConversationComponent.inject(conversationListFragment)
You're very close! The error message says it all:
com.rbttalk.android.data.repository.ConversationRepository cannot be provided without an #Inject constructor or from an #Provides-annotated method.
Note that this is not IConversationRepository; you've provided a binding for that with your #Provides method (which you can eventually consider converting to a #Binds method). However, that #Provides method has a parameter, ConversationRepository, which effectively asks Dagger to create an instance of that concrete ConversationRepository type for you. You've made that binding correctly, but now Dagger needs to instantiate ConversationRepository for you, and it simply doesn't know how.
You'll need to create an #Inject-annotated constructor for ConversationRepository using the annotation type javax.inject.Inject, even if it just looks like this:
#Inject ConversationRepository() {}
This allows Dagger to know that yes, it is safe to call that constructor. (This differs from Guice, which was willing to call a public parameterless constructor including the default constructor provided by Java.) Though you are welcome to accept injector-provided parameters in that annotated constructor (which might be nice if your repository has dependencies, because then you can keep the fields final), you may also choose to simply annotate some fields with #Inject and let the injector populate those after creation.
I am trying decouple a third party library's abstract class. I want to expose a new abstract class which will be exposed to the users rather than the library provided class.
I initially tried using an adapter but that stills add the import for the third party lib in the adapter class.
I added code below explaining my new approach.
// third party lib
abstract class ThirdParty<S> {
public abstract S doAction(S s);
}
// my goal here is to expose a different abstract class which is decoupled from third party lib
// exposed to other modules, rather than exposing the third party lib
abstract class ExposedAbstractClass<S> {
public abstract S doAction(S source);
// get hold of type using guava lib
private final TypeToken<S> typeToken = new TypeToken<S>(getClass()) { };
public Class<S> getSourceClass() { return (Class<S>) typeToken.getClass()
}
// internal class
class Builder<S> extends ThirdPartyLib<S> {
ExposedAbstractClass exposed;
public Builder(ExposedAbstractClass exposed) {
this.exposed = exposed;
}
#Override
public S doAction(S s) {
return (S) exposed.doAction(s);
}
}
//my approach breaks here when i try to invoke builder
class InvokeThirdParty {
public void invoke (ExposedAbstractClass exposed) {
Class type = exposed.getSourceClass();
Builder<type> builder = new Builder(exposed); //doesn't work since Class is runtime type, and T is compile time type
}
}
Any guidance in terms of which design pattern to follow here would be very helpful.
I agree with GuaravJ answer, you could isolate the third party dependency and use an Adaptor or Bridge pattern to invoke the third party library from there. I believe this would be an adequate decoupled solution.
However, it would seem your intent is to remove the import, hence the dependency?
As an alternative, how about implementing Reflection on the ThirdParty class?
Java is compatible with Reflection-oriented-programming. This lets you inspect and examine classes and invoke their methods dynamically at runtime. It would eliminate the dependency and the import statement for the ThirdParty class.
In general terms, with Reflection, you have to locate the class and inspect its methods. In this case I'm assuming knowledge of the doAction() method from ThirdPartyClass.
A simple Java reflection example following the idea of your code excerpt:
Not using reflection
// import ThirdPartyLibrary statement somewhere here
// Instantiating object with concrete class that implements methods from ThirdParty. From your code now, it would be "Builder".
ThirdParty<S> thirdPartyObject = new ThirdPartyImp<S>();
// Invoking doAction method which returns an S object
S foo = thirdPartyObject.doAction();
Using reflection
// Inspect the class finding it using its path and instantiating an object
ThirdParty<S> thirdPartyObject = Class.forName("classpath.to.ThirdPartyImp").newInstance(); // Using a concrete class to instantiate.
// Finding the doAction method. This is assuming we have knowledge that a method with this name exists. Reflection could go as deep as not knowing the methods and having some control structure inspecting them.
Method doAction = thirdPartyObject.getClass().getDeclaredMethod("doAction", new Class<?>[0]);
// Do action is invoked and it returns an object S.
S foo = thirdPartyObject.invoke(thirdPartyObject);
Further reading and notes
Oracle Java official documentation on reflection
Java Reflection example tutorial
Wikipedia Reflection (Computer Science) definition and examples
I have an abstract class that a child class extends. My abstract class has an #Activate method, so does the child class. When OSGi creates my service, it invokes the child class activate method but never the abstract class's activate. Is there any way to force the abstract class's activate to be called by OSGi rather than having the child class manually call the parent activate method?
Here is some code to help elaborate on what I am asking.
#Component(componentAbstract=true, inherit=true)
#Service(value=ISomeInterface)
public abstract class AbstractHello implements ISomeInterface{
#Activate
public void activate(){
System.out.print("Hello ");
}
}
#Component
#Service(Value=ISomeInterface)
public class World extends AbstractHello{
#Activate
public void activate(){
System.out.println("World!");
}
}
The result of the code above would be "World!", rather than "Hello World!".
Initially I thought maybe the child activate method name was clobbering the abstract activate method of the same name. The result is the same even if the abstract class's activate method is given a unique name. Is there any way to have OSGi call the abstract class's activate method for me?
The DS annotation processors only look at the concrete class decorated with #Component. Super classes are not examined. Since the annotation processing is done at build time, super types may come from imported packages which are not chosen until runtime.
Also, the annotation processor generates component description XML from the annotations. So there can only be one activate="methodName" attribute in the XML. If you need the superclass' method called, then you need to call it from the subclass' method.
This has nothing to do with Apache Felix and OSGi, this is caused by poor understanding of Class Inheritance and Method Overriding in Java.
Your World class extends AbstractHello class and overrides its activate() method. If you want the AbstractHello.activate() method to be called then you must call it in
// Annotations excluded for readability.
public class World extends AbstractHello {
public void activate() {
super.activate();
System.out.println("World!");
}
}
OSGi can't help here.
UPDATE
Since the base class is abstract, and you don't have an instance of it, you can't call its method. Neither can OSGi container.