小编gre*_*gko的帖子

有没有人比较用Xamarin C#和Java编写的Android应用程序的性能基准(代码和结果)?

我遇到Xamarin声称他们在Android上的Mono实现和他们的C#编译应用程序比Java代码更快.有没有人对不同Android平台上非常相似的Java和C#代码执行实际基准来验证此类声明,是否可以发布代码和结果?

2013年6月18日新增

由于没有答案,也找不到其他人做的基准,所以决定自己做测试.不幸的是,我的问题仍然是"锁定",所以我不能将其作为答案发布,只编辑问题.请投票重新打开这个问题.对于C#,我使用了Xamarin.Android Ver.4.7.09001(测试版).源代码,我用于测试和编译的APK包的所有数据都在GitHub上:

Java:https://github.com/gregko/TtsSetup_Java

C#:https://github.com/gregko/TtsSetup_C_sharp

如果有人想在其他设备或模拟器上重复我的测试,我也有兴趣了解结果.

我的测试结果

我将我的句子提取器类移植到C#(来自我的@Voice Aloud Reader应用程序),并对英语,俄语,法语,波兰语和捷克语的10个HTML文件进行了一些测试.所有10个文件的每次运行都执行了5次,下面发布了3个不同设备和一个模拟器的总时间.我只测试了"Release"版本,没有启用调试.

HTC Nexus One Android 2.3.7(API 10) - CyanogenMod ROM

Java:总计时间(5次运行):12361 ms,文件读取总计:13304 ms

C#:总计时间(5次运行):17504 ms,文件读取总计:17956 ms

三星Galaxy S2 SGH-I777(Android 4.0.4,API 15) - CyanogenMod ROM

Java:总计时间(5次运行):8947 ms,文件读取总计:9186 ms

C#:总计时间(5次运行):9884 ms,文件读取总计:10247 ms

三星GT-N7100(Android 4.1.1 JellyBean,API 16) - 三星ROM

Java:总计时间(5次运行):9742 ms,文件读取总计:10111 ms

C#:总计时间(5次运行):10459 ms,文件读取总计:10696 ms

仿真器 - 英特尔(Android 4.2,API 17)

Java:总时间(5次运行):2699 ms,文件读取总数:3127 ms

C#:总计时间(5次运行):2049 ms,文件读数总计:2182 ms

仿真器 - 英特尔(Android 2.3.7,API 10)

Java:总计时间(5次运行):2992 ms,文件读取总计:3591 ms

C#:总计时间(5次运行):2049 ms,文件读取总数:2257 ms …

c# java android xamarin dot42

536
推荐指数
6
解决办法
5万
查看次数

Genymotion Android模拟器 - adb访问?

我在Windows 7 PC上为Oracle VirtualBox(http://www.genymotion.com/)下载了Genymotion Android模拟器,使用Google Apps设备创建了一个虚拟Jelly Bean.如何启用ADB访问权限?在系统设置/开发人员选项中,我已启用"USB调试",但输入"adb devices"会显示已连接设备的空列表.尝试为此VM添加USB端口并重新启动VM,但它没有帮助.

格雷格

android virtualbox emulation adb genymotion

41
推荐指数
4
解决办法
11万
查看次数

AAPT失败,错误代码为-1073741819

构建项目会从AAPT引发以下错误.我重建了这个项目,但它仍然失败了.我找不到任何关于此错误代码实际意味着什么的引用.我在使用ActionBarSherlock v4.1.0的IntelliJ中使用Java 6和Android工具r19.

I/O error: Command
"C:\android-sdk-windows\platform-tools\aapt.exe package -m --auto-add-overlay --extra-packages com.actionbarsherlock -J C:\Users\Ollie\.IntelliJIdea11\system\compiler\project6.b9f5599b\.generated\aapt\Project.9617c193\production -M C:/Users/Ollie/Documents/Dropbox/Tech/project6/Source/project6/AndroidManifest.xml -S C:/Users/Ollie/Documents/Dropbox/Tech/project6/Source/project6/res -S C:/Users/Ollie/Documents/Dropbox/Tech/project6/Source/actionbarsherlock/res -I C:\android-sdk-windows\platforms\android-14\android.jar"
execution failed with exit code -1073741819
Run Code Online (Sandbox Code Playgroud)

在我从项目向ActionBarSherlock库项目添加依赖项之后,此构建失败开始发生.如果我删除该依赖项,项目构建正常.如果我将其添加回来,它会再次失败.

android intellij-idea actionbarsherlock

21
推荐指数
3
解决办法
1万
查看次数

Android NDK - 使两个本机共享库相互调用

尝试从jni文件夹和子文件夹中的源代码构建两个共享库,例如mod1mod2(Android NDK编译到libmod1.solibmod2.so),然后让mod1从mod2调用一个函数.关于如何使构建工作的大量答案,但随后运行时动态链接无法正常工作,应用程序在启动时崩溃.

决定发布这个问题并立即回答,以便整个过程的Q和A在一起,并希望其他人不会浪费一天再研究它.

java-native-interface android build shared-libraries android-ndk

18
推荐指数
1
解决办法
7983
查看次数

如何使用asama/await与Xamarin或Dot42在C#中实现Android回调?

如何使用Xamarin for Android使用async/await在C#中实现回调?这与Android的标准Java编程相比如何?

c# android async-await xamarin dot42

12
推荐指数
1
解决办法
1万
查看次数

Android NDK UnsatisfiedLinkError - 一个令人惊讶的原因

2013年7月7日更新: 问题现在已经解决,但错误的原因是非常意外的,所有这些错误的常见嫌疑人在开始时都被淘汰了,我学到了一些新东西.请参阅下面的答案.


我非常绝望.有一个带有本机库的Android应用程序,我称之为方法.在我测试的所有系统上都没有问题,并且该程序在Google Play中没有任何问题报告,成千上万的用户使用.现在,HTC One手机显然是新的ROM - Android版本4.2.2.用户声称它是官方版本,从官方频道升级.当他们尝试启动我的应用程序时,它崩溃了,堆栈跟踪说:

java.lang.UnsatisfiedLinkError:找不到本机方法...

我知道的方法名称在那里,并且在他们安装了Android 4.1时在同一台设备上工作得很好.我在Android 4.2.2中在模拟器中测试它(没有这个特定的设备)并且没有问题.此外,用户尝试卸载并重新安装具有相同结果的应用程序.即使向他们发送私人版本,没有任何ProGuard/Dexguard保护也无济于事.

还有什么可以导致Android上的java.lang.UnsatisfiedLinkError?或者我应该假设这个HTC ROM只是错误?有没有其他人在使用Android 4.2.2的HTC One上遇到过类似的问题?

编辑2013年7月24日

在下面的评论中,另一位开发人员建议系统可能在查找我的本机库时遇到麻烦.我通过从设置中完全删除本机库文件来对Genymotion 4.2.2模拟器进行实验.在这种情况下错误信息是不同的,得到:

W/System.err:引起:java.lang.UnsatisfiedLinkError:无法从loader dalvik.system.PathClassLoader加载cld [dexPath =/data/app/com.hyperionics.avar-2.apk,libra ryPath =/data/app-lib/com.hyperionics.avar-2]:findLibrary返回null

在我从HTC One用户使用Android 4.2.2获得的堆栈跟踪消息中,我看到以下错误消息:

引起:java.lang.UnsatisfiedLinkError:找不到本机方法:com.hyperionics.avar.CldWrapper.detectLangNative:(Ljava/lang/String;)[Ljava/lang/String;

对我来说,系统似乎根据需要找到libcld.so文件,但是找不到它需要的方法.为什么???我知道方法就在那里,根据需要导出,而其他所有运行Android 4.2.2的设备和系统都可以找到它.只有带4.2.2的HTC One在那里失败了......

2013年7月25日更新

开始获得50个代表的赏金.因为我没有HTC One而且卡住了.接受一个答案,或者指出解决问题的方法 - 并且回答者将测试我的代码mod.显示它的工作原理 - 或证明这是HTC One最近的Android 4.2.2 ROM中的一个错误.相关应用是https://play.google.com/store/apps/details?id=com.hyperionics.avar

2013年7月31日更新

赏金的最后一天,仍然没有答案,没有建议......到目前为止,所有这些错误报告我来自欧洲,报告的品牌是"htc_europe"或"vodafone_fr".也许这个错误仅限于欧洲(法国+德国)...如果有人将HTC One和Android更新到4.2.2,如果错误发生在其他国家或其他提供商,我会感兴趣.

格雷格

android android-ndk unsatisfiedlinkerror

12
推荐指数
1
解决办法
5589
查看次数

Android - 为不同的处理器架构构建单独的APK

有没有一种简单的方法可以为不同的处理器架构为Android构建单独的APK文件,使用旧的ANT或新的Gradle构建过程?我这样做的方法是构建一个包含所有支持的本机库的"胖"APK,然后将它们拆分为单独的APK,如我在此处解释的那样.然而,似乎应该有一个更直接的方法来做到这一点......

android native build android-ndk apk

11
推荐指数
2
解决办法
8842
查看次数

Android"O"(Oreo,8)媒体按钮问题

我在文字转语音应用程序中使用的耳机处理媒体按钮的代码在Android API 22到25下运行良好(在旧版本的Android中,它们由其他现在已经折旧的方式处理).然而,在Android 8"Oreo"下,无论是公共测试版还是最终版,它都无效.这是相关代码:

服务启动时,我创建MediaSessionCompact对象:

        mSession = new MediaSessionCompat(getApplicationContext(), "my.package.name._player_session");
        mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
        mSession.setActive(true);
        mSession.setCallback(myMediaSessionCallback);
        PlaybackStateCompat state = new PlaybackStateCompat.Builder()
                .setActions(ACTION_PLAY_PAUSE | ACTION_PLAY | ACTION_PAUSE |
                        ACTION_SKIP_TO_NEXT | ACTION_SKIP_TO_PREVIOUS |
                        ACTION_FAST_FORWARD | ACTION_REWIND
                )
                .setState(PlaybackStateCompat.STATE_PAUSED, 0 /*PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN*/, 1f)
                .build();
        mSession.setPlaybackState(state);
Run Code Online (Sandbox Code Playgroud)

当然有会话媒体回调定义:

private MediaSessionCompat.Callback myMediaSessionCallback = new MediaSessionCompat.Callback() {
    @Override
    public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
        // The log output below never appears on "Oreo", nothing comes here.
        Log.d(TAG, "callback onMediaButtonEvent() Compat");
        MediaButtonIntentReceiver.handleIntent(mediaButtonIntent.getAction(), (KeyEvent) mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT));
        return true;
    }

    @Override
    public void onSkipToNext() …
Run Code Online (Sandbox Code Playgroud)

android bluetooth android-8.0-oreo media-buttons

11
推荐指数
1
解决办法
3011
查看次数

以编程方式测试是否在Android 10+中禁用了旧版外部存储访问

是否有一个简单的API调用可以告诉我在Android 10或更高版本上运行的应用程序是否必须使用范围存储访问权限,即是否禁用了常规文件访问(又称为“旧版外部存储”)?请注意,即使AndroidManifest.xml中的应用程序也声明了:

  android:requestLegacyExternalStorage="true"
Run Code Online (Sandbox Code Playgroud)

由于将来Google的政策更改,文件访问仍可能会被拒绝,因此测试该值是没有用的。我发现的唯一方法是测试外部存储根目录是否可读,为此,应用程序必须首先请求存储许可,如果禁用了旧存储,则该存储对其他任何东西都没有用。

public static boolean mustUseScopedStorage() {
    // Impractical must first ask for useless Storage permission...
    File exSD = Environment.getExternalStorageDirectory();
    return !exSD.canRead(); // this test works only if Storage permission was granted.
}
Run Code Online (Sandbox Code Playgroud)

我想我曾经看过一种新的API可以检测到这一点,但是现在找不到该文章了...

android scoped-storage legacy-external-storage

8
推荐指数
1
解决办法
281
查看次数

Android - 使用 Google Scoped Storage API 访问本机 C/C++ 代码中的文件

我需要在原生 C/C++ 代码中的 Android 应用程序中按文件名打开文件。本机代码是我不想修改的第 3 方库,但它们通常需要文件名作为读/写文件的参数。使用 Google 的“范围存储”API 并在 Android 10 或更高版本中禁用对文件的本机访问,这是一个真正的问题。

一个众所周知的解决方案是获取文件描述符并使用“proc/self/fd/FD_NUMER”技巧,例如:

       ParcelFileDescriptor mParcelFileDescriptor = null;

       String getFileNameThatICanUseInNativeCode(Context context, DocumentFile doc) { 
           try {
                Uri uri = doc.getUri();
                mParcelFileDescriptor =
                        context.getContentResolver().openFileDescriptor(uri, "r");
                if (mParcelFileDescriptor != null) {
                    int fd = mParcelFileDescriptor.getFd();
                    return "/proc/self/fd/" + fd;
                }
            }
            catch (FileNotFoundException fne) {
                return "";
            }
        }

        // Don't forget to close mParcelFileDescriptor when done!
Run Code Online (Sandbox Code Playgroud)

将此传递给本机 C/C++ 代码有效,但前提是文件位于手机主存储中。如果用户尝试打开插入手机插槽的外部 SD 卡上的文件,则不起作用 - 以这种方式打开的文件没有读取权限。我只能获取文件描述符 int 号并使用 fdopen(fd)。但这将需要修改 3rd 方库(开源或许可)的源代码,并且每次更新这些库的原始源时都会令人头疼。

有没有更好的解决这个问题的方法?不,我不想听到添加的解决方案 …

java-native-interface android scoped-storage

8
推荐指数
2
解决办法
2858
查看次数