如何从Android应用程序调用单声道为Android类? [英] How to call Mono for Android class from within Android application?

查看:213
本文介绍了如何从Android应用程序调用单声道为Android类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个相当简单的活动中为单声道Android项目:

I have created a fairly simple Activity in Mono for Android project:

[Activity(Label = "AndroidApplication1", MainLauncher = true, Icon = "@drawable/icon")]
public class Activity1 : Activity
{
    private string value = "intitial";

    [Export]
    public string GetString()
    {
        return value;
    }

    [Export]
    public void SetString(string newValue)
    {
        value = newValue;
    }
}

活动只能作为概念验证的,因此它的简单。现在,我想可以称之为从正常的,基于Java的Andr​​oid应用程序的方法GetString的()。

The activity should only serve as a proof-of-concept, hence its simplicity. Now, I'd like to be able to call the method GetString() from the "normal", Java-based Android application.

Xamarin的文档,我读过有关Java来管理的互操作,这似乎是我在寻找什么。如果我理解正确的话,当单声道为Android应用程序编译,它产生被称为Android的调用包装(ACW)的Java类。我应该就能够调用来自基于Java的Andr​​oid应用程序,这些遗弃化武的方法。

In Xamarin's docs, I've read about Java to Managed interop, which seems to be exactly what I'm looking for. If I understand it correctly, when Mono for Android app compiles, it generates Java classes that are referred to as Android Callable Wrappers (ACW). I should be then able to call methods on these ACWs from Java-based Android application.

现在的问题是,究竟我该参考之用单声道为Android应用程序( APK 的文件),基于Java的Andr​​oid应用程序?

The question is, how exactly do I reference compiled Mono for Android application (the apk file) from the Java-based Android app?

这就是我现在卡住,无法找到任何具体的例子。有类似的问题上所以这里(<一href="http://stackoverflow.com/questions/7279012/how-to-call-a-net-class-from-a-java-class-in-mono-from-android">this 之一和这个)和一些blogposts,但他们只是归结为使用遗弃化武。 但是究竟怎么了?也许我缺少明显的东西在这里,是没有Android的家伙。

This is where I'm now stuck and was unable to find any concrete examples. There are similar questions here on SO (this one and this one) and some blogposts, but they just boil down to "use ACWs". But how exactly? Maybe I am missing something obvious here, being no Android guy.

我已经试过是动态加载的 DEX 的文件,我从我的单猛拉Android版的的apk 的。我简单地把它在存储卡上,然后试图用 DexClassLoader 从基于Java的Andr​​oid应用程序加载它(我跟着这个的博客文章)。该ACW类被发现,但是当我试图创建它的实例,我得到了以下错误:

What I've tried is to dynamically load the dex file that I yanked from my Mono for Android apk. I've simply put it on the storage card and then tried to use DexClassLoader from Java-based Android app to load it (I've followed this blog post). The ACW class was found, but when I tried to create its instance, I got the following error:

没有找到实现原生LMNO /安卓/运行; .register(Ljava /朗/字符串; Ljava /朗/班; Ljava /朗/字符串;)

No implementation found for native Lmno/android/Runtime;.register (Ljava/lang/String;Ljava/lang/Class;Ljava/lang/String;)

我想,我必须以某种方式包括单声道的Andr​​oid运行的基于Java的应用程序,但我不知道怎么样。

I suppose that I have to somehow include Mono for Android runtime to the Java-based app, but I have no idea how.

编辑: 这是code我试图加载的 DEX 的有:

This is the code I am trying to load the dex with:

DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
    optimizedDexOutputPath.getAbsolutePath(),
    null,
    getClassLoader());

try {
    Class<?> classActivity1 = cl.loadClass("androidapplication1.Activity1");

    // the following line throws the exception
    Object a = classActivity1.newInstance();

    Method getStringMethod = classActivity1.getMethod("GetString");
    Object result = getStringMethod.invoke(angel);

    result = null;
} catch (Exception e) {
    e.printStackTrace();
}

EDIT2: 我现在读<一href="http://stackoverflow.com/questions/6814478/using-c-sharp-library-with-mono-for-android-from-java-$c$c">here它应该是可以直接开始写在单声道为Android从Java活动。它仍然是我不清楚如何引用单声道为Android从Java和谷歌搜索产生不相关的内容。现在确实难住了。

I am now reading here that it should be possible to directly start activities written in Mono for Android from Java. It is still not clear to me how to reference the Mono for Android from Java and Googling yields no relevant hits. Really stumped now.

推荐答案

如果我理解正确,你现在要做什么,这是不是真的有可能。当你得到该错误消息意味着,在一个单声道为Android应用程序中的活动依赖于单声道运行时才能正常工作。的调用包装上没有其自身有用在这种情况下,因为它是该调用到单声道运行时只是一个薄的Java包装类。实际上,你可以看到生成调用包装自己,如果你看后你建立你的项目的OBJ /调试/安卓/ src文件夹。例如:

If I'm understanding correctly what you're trying to do, this isn't really possible. As the error message you got implies, an Activity within a Mono for Android application relies on the Mono runtime in order to function properly. The callable wrapper isn't useful on its own in this case, since it's just a thin Java wrapper class that calls into the Mono runtime. You can actually see the generated callable wrappers yourself if you look in the obj/Debug/android/src folder after you build your project. For example:

package androidapplication9;


public class Activity1
    extends android.app.Activity
    implements
        mono.android.IGCUserPeer
{
    static final String __md_methods;
    static {
        __md_methods = 
            "n_onCreate:(Landroid/os/Bundle;)V:GetOnCreate_Landroid_os_Bundle_Handler\n" +
            "";
        mono.android.Runtime.register ("AndroidApplication9.Activity1, AndroidApplication9, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", Activity1.class, __md_methods);
    }


    public Activity1 ()
    {
        super ();
        if (getClass () == Activity1.class)
            mono.android.TypeManager.Activate ("AndroidApplication9.Activity1, AndroidApplication9, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", "", this, new java.lang.Object[] {  });
    }


    public void onCreate (android.os.Bundle p0)
    {
        n_onCreate (p0);
    }

    private native void n_onCreate (android.os.Bundle p0);

    java.util.ArrayList refList;
    public void monodroidAddReference (java.lang.Object obj)
    {
        if (refList == null)
            refList = new java.util.ArrayList ();
        refList.add (obj);
    }

    public void monodroidClearReferences ()
    {
        if (refList != null)
            refList.clear ();
    }
}

不过,由于Android的方式工作,你可以有一个Java应用程序启动为以单定义以同样的方式,你会开始外部Java活动Android应用程序的活动。这依赖于这两个应用程序被安装,当然,但将导致单声道的Andr​​oid应用程序和Mono运行时实际上启动了运行该活动。

That said, due to the way Android works, you could have a Java application start an activity that is defined in a Mono for Android application in the same way you'd start an external Java activity. This relies on both applications being installed, of course, but would result in the Mono for Android application and Mono runtime actually starting up to run that activity.

修改

更新回答您在您的评论提出的问题。该 ExportAttribute 基本上只是给你更多的控制在被遗弃化武如何产生的,允许你指定一个特定的方法或字段应该是present在ACW什么名字也应该有。当你要使用的东西,像一个机器人,这很有用。onclick属性中的布局,例如,在默认情况下,ACW将不包含你要引用的方法

Updating to answer the questions you posed in your comment. The ExportAttribute basically just gives you some more control in how the ACW gets generated, allowing you to specify that a particular method or field should be present in the ACW and what name it should have. This can be useful when you want to use things like an android:onClick attribute in a layout, for example, where by default the ACW wouldn't contain the method you want to reference.

您不能得到一个单声道的Andr​​oid应用程序上下文之外多大用处了一个ACW以来的单声道运行时不会present。 code用C#编写的单声道运行时的顶部被执行,并没有转化成Java编译背后之类的东西时的情景。在运行时,有那么两种运行时会并排的Dalvik(Android的运行时)和单声道,以及调用包装有没有让这两个通信来回。正因为如此,即使是单声道为Android类库仍然依赖于单声道运行,所以你不能单独使用运行它。

You can't get much use out of an ACW outside of the context of a Mono for Android application since the Mono runtime wouldn't be present. Code written in C# is executed on top of the Mono runtime, and not translated into Java behind the scenes during compilation or anything like that. At runtime there are then two runtimes going side by side, Dalvik (Android's runtime) and Mono, and the callable wrappers are there to allow the two to communicate back and forth. Because of that, even a Mono for Android class library would still depend on the Mono runtime, so you cannot use it independently of that runtime.

此图显示了该架构的样子,并且运行时如何相互关联的:

This diagram shows what the architecture looks like, and how the runtimes relate to each other:

希望这有助于澄清事实!

Hope this helps clear things up!

这篇关于如何从Android应用程序调用单声道为Android类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆