NineOldAndroids for MonoDroid - xamarin.android

I am trying to use NineOldAndroids to enable backwards compatibility with pre-3.x devices, but I am encountering the following build error:
.../NineOldAndroids/obj/Debug/generated/src/Com.Nineoldandroids.Animation.AnimatorSet.cs(83,83):
Error CS0508:
Com.Nineoldandroids.Animation.AnimatorSet.SetDuration(long)': return
type must beCom.Nineoldandroids.Animation.Animator' to match
overridden member
`Com.Nineoldandroids.Animation.Animator.SetDuration(long)' (CS0508)
(NineOldAndroids)
but the signature in generated code looks like this:
public override global::Com.Nineoldandroids.Animation.AnimatorSet SetDuration (long p0)
and the class signature of AnimatorSet looks like this:
public sealed partial class AnimatorSet : global::Com.Nineoldandroids.Animation.Animator {
The problem is, since AnimatorSet is inherited from Animator, I'm not sure why it should be a problem.
Are there any examples of binding NineOldAndroids for MonoDroid that you're aware of or know how to fix this?

These error messages are because C# doesn't support Covariant Return Types while Java ≥1.5 does.
Add these lines to Transforms/Metadata.xml:
<attr path="/api/package/class[#name='AnimatorSet']/method[#name='setDuration']" name="managedReturn">Com.Nineoldandroids.Animation.Animator</attr>
<attr path="/api/package/class[#name='ValueAnimator']/method[#name='setDuration']" name="managedReturn">Com.Nineoldandroids.Animation.Animator</attr>

Related

Xamarin Dependency Injection fails - crash while trying to get platform specific implementation

I've got a Xamarin Forms interface that defines a Bluetooth controller. I'm following the usual technique when trying to create an Android specific implementation of this (I will also do an iOS one when I get this working).
I define my interface as follows :
namespace ArduinoRobotController.Models
{
public interface BluetoothControllerInterface
{
List<string> GetPairedDevices();
..
Then I have my platform specific implementation like this :
[assembly: Xamarin.Forms.Dependency(typeof(BluetoothControllerInterface))]
namespace ArduinoRobotController.Droid.Implementations
{
public class BluetoothController : BluetoothControllerInterface
{
..
Then finally back in one of my view models, I have this code to get the platform specific instance I need :
BluetoothControllerInterface bt = Xamarin.Forms.DependencyService.Get<BluetoothControllerInterface>();
It builds and runs, but crashes on the line above. The error states :
System.MissingMethodException: Default constructor not found for type ArduinoRobotController.Models.BluetoothControllerInterface at SystemRuntimeType.CreateInstanceMono
.. etc.
I've tried lots of different ways around doing this, including calling to register the implementation in normal code rather than as [assembly etc. Any help on this really appreciated.
your registration needs to point to the concrete class, not the interface
[assembly: Xamarin.Forms.Dependency(typeof(BluetoothController))]

Error when using MvxAppCompatActivity

I am writing an application with Xamarin.Android with MvvmCross. I want my Activity to inherit from MvxAppCompatActivity so that I can use fragments. Here is my base class:
public class BaseActivity<TViewModel> : MvxAppCompatActivity<TViewModel> where TViewModel : MvxViewModel
{
public new TViewModel ViewModel
{
get { return base.ViewModel; }
set { base.ViewModel = value; }
}
}
I get this error on the OnCreate of my Activity:
Failed resolution of: Landroid/support/v7/appcompat/R$drawable; Didn't
find class "android.support.v7.appcompat.R$drawable" on path:
DexPathList...
But if I change MvxAppCompatActivity to MvxActivity it works fine...why?
I downloaded your solution and tried to build the Android project. It fails with 18 occurrences of the same error:
error: No resource identifier found for attribute 'loginButtonBackgroundColor' in package ...
So after a little inspection of your solution, I did the following steps to solve your issue:
1) In login_screen.axml I saw you had this line:
xmlns:[YOURNAMESPACE]="http://schemas.android.com/apk/res/[YOUR PACKAGE]"
Which is unnecessary. After removing it, and changing the lines [YOURNAMESPACE]:loginButtonBackgroundColor=... to local:loginButtonBackgroundColor=... the build succeeds.
2) I saw some layout files are located inside the /drawable folder (button_round_corner.xml, input_box.xml and login_button.xml). I moved them to the /layout folder and fixed the issues the change produced (only two).
3) Made Setup class inherit from MvxAppCompatSetup.
4) Added a RegisterAttribute over the LoginButton control. So the class definition looks like this:
using Android.Runtime;
...
namespace Xxx.Droid.Components
{
[Register(nameof(LoginButton))]
public class LoginButton : FrameLayout, IMvxNotifyPropertyChanged
{
...
}
}
And that's it! Probably (2) was not necessary, but leaving it here just in case.
It could be several things but it is probably the lack of some android support packages. Mainly the lack of Xamarin.Android.Support.Design gives that error. So check if you have that added and if not add it and it should solve your problem.
If it doesn't it's highly likely you lack some other android support packages

Specflow calling steps within steps causes "No matching step definition" error

I am following the technique outlined here
using a step defined like
[Given("some base scenario has happened")]
public void SomeBaseScenarioHasHappened()
{
Given("some condition");
And("some action");
When("some result");
}
from a scenario like
Scenario: Some dependant scenario
Given some condition
And some base scenario has happened
When some other action
Then some other result
However the step
When some other condition
produces the following error
-> No matching step definition found for the step. Use the following code to create one:
[When(#"some other condition")]
public void Whensome other condition()
{
ScenarioContext.Current.Pending();
}
I can work around the problem by having the base scenario only use Given
[Given("some base scenario has happened")]
public void SomeBaseScenarioHasHappened()
{
Given("some condition");
Given"some action");
Given("some result");
}
however this is not what I should have to do.
Am I missing something?
Why cant the base scenario be called using an AND ?
In Specflow there are only 3 types of steps. Given, When and Then. When you use a step with And in your scenario description SpecFlow looks at the previous type of step and assumes that your And step is of the same type.
So when you write this
Scenario: Some dependant scenario
Given some base scenario has happened
And some other condition
When some other action
Then some other result
Specflow looks for step which have bindings:
Given("some base scenario has happened")
Given("some other condition")
When("some other action")
Then("some other result")
Notice there is no And binding?
So your solution is to to ensure that in your composite step you must avoid using And and just use the same binding (or one of them if they have multiple) that the original step had. Your final solution should look something like this:
[Given("some condition")]
public void SomeCondition()
{
...
}
[When("some action")]
public void SomeAction()
{
...
}
[Then("some result")]
public void SomeResult()
{
...
}
[Given("some base scenario has happened")]
public void SomeBaseScenarioHasHappened()
{
Given("some condition");
When("some action");
Then("some result");
}
[Given("some other condition")]
public void SomeOtherCondition()
{
...
}
[When("some other action")]
public void SomeOtherAction()
{
...
}
[Then("some other result")]
public void SomeOtherResult()
{
...
}
You can't use And in the composite steps because no steps are actually bound with an And, there is no such binding - The only bindings are Given, When or Then. The And and But keywords are only used when generating the unit tests that are run, the steps using those keywords are still bound to a Given, When or Then step ultimately.
In a scenario definition the things are processed in order and you can easily tell what an And step actually is based on the step it appears after, so when specflow generates the step bindings it knows what step type to use (either a Given, When or Then). When you are calling a a step from within another step you are explicitly calling one of those step bindings and you have to call it with the binding that it is bound with. So if it was bound with a Given binding like this:
[Given("some other condition")]
public void SomeOtherCondition()
{
...
}
then you have to call it like this from the code:
Given("Some other condition");
but you could refer to it like this in a scenario:
Given some condition
And some other condition
because specflow knows when it generates the unit test that the And some other condition is actually calling a Given bound step
This question has been previously answered correctly above.
I just came across the same error "No matching step definition found for one or more steps".
The reason that I had this issue, was that I had forgotten to put the attribute [Binding, Scope(Feature = "My Feature")] just above my steps c# code class which links methods to feature file, which is needed to match "Feature: My Feature" at the top of my feature file.
I just taught that I would document it here to help someone else that was seeing the same error but for the different reason that I outlined.
Possible solutions
Use Given instead of And
Scenario: Some dependant scenario
Given some base scenario has happened
Given some other condition
When some other action
Then some other result
or
Tag the step with more than one binding, e.g.
[Given(#"some other condition")]
[When(#"some other condition")]
public void Whensome other condition()
{
but this won't always make semantic sense, so use this only when it really does make sense.
try verifying if your sentence has empty spaces. i.e: Given some description(empty space)
so, in the method will appear like: [Given("some description ")]

Monodroid binding change variable name

I try to bind BugSense 3.0.5 to MonoDroid. I create a new Java Binding Library project, add the bugsense3.0.5.jar to the Jars-folder. I build it, and get the following error:
'Crash': member names cannot be the same as their enclosing type
The auto generate code:
[global::Android.Runtime.Register ("com/bugsense/trace/models/Crash", DoNotGenerateAcw=true)]
public partial class Crash : global::Java.Lang.Object, global::Java.IO.ISerializable {
[Register ("CRASH")]
public const int Crash = (int) 1;
So I need to rename the global variable "Crash" in the Metadata.xml- but how do I do that?
I have try:
<attr path="/api/package[#name='com.bugsense.trace.models']/class[#name='Crash']/field[#name='Crash']" name="managedName">mCrash</attr>
But it fails: matched no nodes
Fixed it renaming the class instead
<attr path="/api/package[#name='com.bugsense.trace.models']/class[#name='Crash']]" name="managedName">Crashed</attr>
You should always look for original fields name in java.
As i know it is lowerCamelCase. And it is probably hidden into setter/getter so you should search for /method[#name='getCrash']

Resolving a type without registering first - prism 4 and Untiy

First of all I would like to remark I am new with the concept of prism, DI and containers. I am looking on one of the code samples provided with the Prism Library:
The code simply injects a view with the "Hello World" string (in a TextBlock element) to a region in the shell.
When the application starts-up, it creates a new BootStrapper instance, which creates and initializes the shell:
public class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<Shell>();
}
protected override void InitializeShell()
{
base.InitializeShell();
Application.Current.RootVisual = (UIElement)this.Shell;
}
protected override void ConfigureModuleCatalog()
{
base.ConfigureModuleCatalog();
ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;
moduleCatalog.AddModule(typeof(HelloWorldModule.HelloWorldModule));
}
}
My question refers to the method CreateShell(). I couldnt find nowhere in the supplied code (including not in a configuration file or any xaml file...) where do they register the type Shell, and even if it was registered - the supplies Shell class doesnt implement any interface... what is the meaning of resolving a specific type?
the Shell implementation:
public partial class Shell : UserControl
{
public Shell()
{
InitializeComponent();
}
}
This looks like a magic to me, so I tried to create my own type (MyType) and resolve it the same way:
Container.Resolve<MyType>();
By setting a breakepoint inside MyType constructor, I saw that it DID resolved MyType. Can somebody please explain to me how does it work?
These couple of threads should answer your question:
http://compositewpf.codeplex.com/Thread/View.aspx?ThreadId=230051
Does unity just make clasess with out needing anything registered?
Additionally, if you are eager to get more detail into how Unity can do this, simple download Unity 2.0 and open the source code that is provided with the installer.
I hope this helps.
Thanks,
Damian
You do not need to register a type you want to resolve. You need to register the dependencies of a type, that you want to resolve. In this case, the Shell doesn't need any dependencies, so you can resolve it simply. But for an example (not really), if your shell getting an interface IService as a parameter, then you must register IService, before you resolve Shell.
Otherwise you will get Dependency Resolution Failed Exception. In Prism 4.1 it will be swallowed silently due to TryResolve.

Resources