Why is getOnBackPressedDispatcher() method unresolved until 'androidx.navigation:navigation-ui' is added as a dependency? - android-navigation

I'm trying to customize onBackPress behaviour of JetPack Navigation. Although I found the solution I'm just curious what's going behind the scenes in the following scenario:
Initial state of my activity is
MyActivity extends androidx.appcompat.app.AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getOnBackPressedDispatcher().addCallback(...); // <--- Method is unresolved
}
}
How come that after I add the following dependency to build.gradle the getOnBackPressedDispatcher() method is being resolved:
implementation 'androidx.navigation:navigation-fragment:2.1.0'
implementation 'androidx.navigation:navigation-ui:2.1.0'
What's going behind the scenes? Does it have something with the Jetifier? Does it alter the classes based on declared dependencies or something similar?

implementation 'androidx.appcompat:appcompat:1.1.0'
Implement this dependency to its latest version, this will fix the problem.

Related

Is there a way to run JBehave from with in main method like Cucumber's Main.run() method

I would like to initiate running of the BDD stories from with a Java's main method. Just like cucucumber's Main.run(), is there a similar way to specify JBehave configuration settings to a method and run it.
TIA
It can be done via extension of JUnitStory/JUnitStories and adding main method:
import org.jbehave.core.junit.JUnitStories;
public class MyStories extends JUnitStories {
// add configuration here
public static void main(String[] args) throws Throwable {
new MyStories().run();
}
}
Full example including full sample configuration can be found in the official JBehave repository: org/jbehave/examples/executable_jar/MyStories.java

accessing Android native method from different project

I am working on an Android application that will call a .so file created by a different Android NDK application.
I have created the following folder structure in my project and copied over the .so files as seen below:
|--app:
|--|--src:
|--|--|--main
|--|--|--|--jniLibs
|--|--|--|--|--armeabi
|--|--|--|--|--|--libmylib.so
|--|--|--|--|--x86
|--|--|--|--|--|--libmylib.so
I call this library through my application via the following code:
static {
System.loadLibrary("mylib");
}
I then call the method from this shared object via the following code:
String str = stringFromJNI();
This does not work as the program looks for mangled function name as follows:
com.example.androidlibcall.MainActivity.stringFromJNI() where my .so function will be using a different package name and hence a different function name is generated.
I am not really sure what I need to do to call the functions from the external library, I assume I can create my own library and utilize dlopen() to load the external library and make calls to it, but was wondering if there are the other methods to achieve this or not.
My ultimate goal is to be able to create applications that can call pre-existing libraries that are on the mobile device, but since I am new to NDK/Android I am not sure what is the best method for this and have not found good examples to work with.
A lot of the pre-existing similar questions seem to be dealing with older versions of Android Studio that don't seem applicable anymore.
I am using the latest version of Android Studio (3.1.2) with Gradle 4.4 on Windows 7 machine.
Please advise.
Thanks!
Generally speaking, it's not a good idea to have native methods in application's MainActivity, but this should not worry us now that we are forging a workaround.
Assume that your new project has com.example.other.MainActivity.java, and you want to call the native method com.example.androidlibcall.MainActivity.stringFromJNI() from com.example.other.MainActivity.onCreate(). To do this, create a new Java class in your other app:
package com.example.androidlibcall;
public class MainActivity {
public static native String stringFromJNI();
}
and in your existing MainActivity class,
package com.example.other;
import static com.example.androidlibcall.MainActivity.stringFromJNI;
class MainActivity {
static {
System.loadLibrary("mylib");
}
}
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
…
String qq = stringFromJNI();
…
}
}
You see that com/example/androidlibcall/MainActivity.java contains no logic, no data, no code. It is only a wrapper that lets us easily use libmylib.so without rebuilding it.

How to inject properties when using Castle Windsor

I am new to IOC.
I've MethodProfilerAspectAttribute attribute which has to be applied on any method like this
[MethodProfilerAspectAttribute(5)]
public void MethodName(){}
Here is the implementation of MethodProfilerAspectAttribute
[Serializable]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class MethodProfilerAspectAttribute : OnMethodBoundaryAspect
{
public ILogger logger { get; set; }
public int x{get;set;}
public MethodProfilerAspectAttribute(int x)
{
this.x=x;
}
public override void OnSuccess(MethodExecutionArgs args)
{
logger.CustomLogging("logMe");
base.OnSuccess(args);
}
}
I want to resolve my ILogger dependency using Log4NetLogger which is registered and resolving constructor dependencies properly by using following :
container.Register(Component.For<ILogger>().ImplementedBy(typeof(Log4NetLogger)));
but unfortunately whatever I've tried for resolving property dependency, is not working.
Any help would be greatly appreciated.
The link you provided just describes property injection for components resolved from the container. Attributes are not resolved from the container, but instead are created by the CLR. You might be able to jigger a way to set attribute properties by providing a custom IContributeComponentModelConstruction implementation, but I'm not so sure. See answers for similar questions here, here, and here (from the creator of Windsor).
In any case, attributes is not where you want to put functionality. They should be minimal, just providing metadata. I see here you're trying to provide some sort of functionality across all method invocations. You may want to consider Windsor's interceptors to provide similar behavior.

Mule Issue : More than one JAXBContext

We are facing one issue in our Mule Adapter related to JAXB context, needed some opinion on the same
We are using xpath to evaluate some expressions in the choice blocks in our adapter like below for instance,
<choice doc:name="Choice">
<when expression="//env:abc/env:Body/ref:dataelement/ref:/ref:element" evaluator="xpath">
......
</when>
Now, this works perfectly fine in our application but the problem arises when one of other team uses this Adapter as a jar in their application.
When they try to use this adapter, they are getting below error,
Message : More than one object of type class javax.xml.bind.JAXBContext registered but only one expected.
Type : org.mule.api.registry.RegistrationException
Code : MULE_ERROR--2
JavaDoc : http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/registry /RegistrationException.html.
After debugging with the help of loggers etc, we narrowed down to the choice block used above which is causing this particular issue. Also, googled a bit and found one of the posts pointing out the same issue.
Also, to confirm we commented out the choice block having xpath expression and the flow went ahead but broke again where was xpath used in some other way.
https://www.mulesoft.org/jira/browse/MULE-5926
Can anyone please suggest any suitable workaround to resolve this issue?
I agree with you. It is an unresolved issue in Mule.
One solution we have implemented is not define the jaxb context in the config you are providing in the jar file.
Along with the jar file, give instructions to the end application using it, to include the JAXB packages in their JAXB Context object definition.
This way there will be only one JAXB context and it will work smoothly.
Hope this helps.
This is a bit late however the solution that worked was
<mulexml:jaxb-context name=“JAXB_Context“ packageNames=“org.example.test1:org.example.test2“ doc:name=“JAXB Context1“ />
Please note that there must be no space between package names.
Thanks to: http://dominikbial.de/quicktipp-working-with-more-than-one-package-name-in-a-jaxb-context-config-in-mule-esb/
As of now we cannot add more than one JAXBContext in mule. As an alternative you can write your custom transformer.
I implemented something like
public interface MyAppJaxbObj2XmlComponent<I,O> extends
MyAppComponent<I,O>,Callable {
public O marshal(I input) throws Exception;
}
Abstart transformer
public abstract class AbstractMyAppJaxbObj2XmlComponent<I,O> implements
MyAppJaxbObj2XmlComponent<I,O>{
private Class<I> inputType;
public AbstractMyAppJaxbObj2XmlComponent(){
this.inputType = (Class<I>) new TypeToken<I>(getClass())
{}.getRawType();
}
public AbstractMyAppJaxbObj2XmlComponent(Class<I> type){
this.inputType = type;
}
#Override
public Object onCall(MuleEventContext eventContext) throws Exception {
I input = eventContext.getMessage().getPayload(inputType);
O output = marshal(input);
return output;
}
}
Your flow transformer this will load your needed jaxb during startup.
#Component
public class MyFlowJaxbObj2XmlComponent extends
AbstractMyAppJaxbObj2XmlComponent<RequestPayloadType,String> {
#PostConstruct
public void init() {
//Load your schema during startup
}
}
You can also implement a fluid interface as an alternative for this.

Error - None of the constructors found with 'Orchard.Environment.AutofacUtil.DynamicProxy2.ConstructorFinderWrapper'

I have a custom module, Module1. In this module, I am referencing another custom module, Module2. Everything was working fine last week.
I did a fresh re-install of Orchard this morning. Since then, I have been getting this error.
None of the constructors found with 'Orchard.Environment.AutofacUtil.DynamicProxy2.ConstructorFinderWrapper' on type 'Module1' can be invoked with the available services and parameters: Cannot resolve parameter 'Module2' of constructor 'Void .ctor(...)'.
Any idea how to fix this error?
Thanks.
That means that an implementation of some interface could not be found. Several thing can have happened: a module may have failed to compile, or you forgot to make an interface derive from IDependency.
I know the post is quite old now, but just to link any possible mistake that could cause the described problem... here is my mistake.
I simply forgot to enable the referenced module from the dashboard.
Of course that didn't prevent me to add a project reference and module dependency, having the code compiling perfectly .
The point is, my referenced module doesn't contain any content type definition. It is just a module conceived to collect some functionality and common utilities. That's why I forgot to enable it.
Cheers.
You can get this error if you manually enabled your modules.
If so, fix it by deleting App_Data\cache.dat and then recycle the app pool.
I had the same issue. It seems that I referenced the concrete class and not the interface in my constructor.
public OrderService(
IRepository<Order> orderRepository,
ProductService productService,
ProductCategoryService productCategoryService
)
Instead of
public OrderService(
IRepository<Order> orderRepository,
IProductService productService,
IProductCategoryService productCategoryService
)
checklist is:
Interface derive from IDependency
Implementation derive from Interface
Constructor references the Interface
Build All and check if all referenced modules compile
Enable module in Admin panel
example:
public class myController : Controller{
private readonly IMyService _myService;
public myController(
IMyService myService
) {
_myService = myService;
}
}
public interface IMyService : IDependency
{
int GetOne();
}
public class MyService: IMyService
{
public MyService()
{ // init code }
public int GetOne()
{ return 1; }
}

Resources