当前位置: 首页 > 知识库问答 >
问题:

在本地codenameone android构建中包含cn1lib?

鄢翰藻
2023-03-14

我目前正在考虑将一个我开始用react-native开发的应用移植到CodenameOne。为此,我仍然在检查它的可行性和工作量(因为我必须将一些本机库绑定从react-native移植或开发到codenameone,因为codenameone忽略了我的一些需求,比如Socket.io支持)。免费的codenameone构建云服务仅限于1MB的应用程序,我必须在本地进行测试构建(只有几个测试类和使用谷歌地图cn1lib,我的测试应用程序已经超过了1MB的限制)可悲的是,codenameone没有关于如何执行本地构建的免费文档,实际上我在互联网上找不到关于如何执行本地构建的任何指导(我只在一篇博客文章中找到了一些关于如何执行本地iOS构建的基本和不推荐的指导,但没有针对Android的指导)。所以我得自己想办法...在花了一些时间深入研究gradle配置参数后,我终于成功地构建了一个基本的codenameone应用程序localy,该应用程序可以在我的android测试设备上运行。但问题是,当我添加一个外部cn1lib(谷歌地图原生cn1lib https://github.com/codenameone/codenameone-google-maps)时,我的应用程序在打开依赖于这个lib的屏幕时会出现错误。在android错误日志中,我可以找到这样一条消息:

D/MyApplication(  551): [EDT] 0:0:0,99 - Exception: java.lang.ClassCastException - com.codename1.googlemaps.InternalNativeMapsImpl cannot be cast to com.codename1.system.NativeInterface
W/System.err(  551): java.lang.ClassCastException: com.codename1.googlemaps.InternalNativeMapsImpl cannot be cast to com.codename1.system.NativeInterface
W/System.err(  551):    at com.codename1.system.NativeLookup.create(Unknown Source)
W/System.err(  551):    at com.codename1.googlemaps.MapContainer.<init>(MapContainer.java:171)
W/System.err(  551):    at com.codename1.googlemaps.MapContainer.<init>(MapContainer.java:151)
W/System.err(  551):    at com.tbdlab.testapp.MyApplication.start(MyApplication.java:207)
W/System.err(  551):    at com.tbdlab.testapp.MyApplicationStub.run(MyApplicationStub.java:183)
W/System.err(  551):    at com.codename1.ui.Display.processSerialCalls(Unknown Source)
W/System.err(  551):    at com.codename1.ui.Display.mainEDTLoop(Unknown Source)
W/System.err(  551):    at com.codename1.ui.RunnableWrapper.run(Unknown Source)
W/System.err(  551):    at com.codename1.impl.CodenameOneThread$1.run(Unknown Source)
W/System.err(  551):    at java.lang.Thread.run(Thread.java:818)

我不明白为什么InternalNativeMapsImpl不能转换成NativeInterface,因为我查看了我编译的apk的dex文件,并且google maps cn1lib中所有必要的类(用于android)都正确地包括在内(因此我有com.codenameone.googlemaps.internalnativemapscom.codenameone.googlemaps.internalnativeMapscom.codenameone.googlemaps.InternalNativeMapsImpl和.Lifecyclelistener...)。我解压缩了它们,代码是正确的(无论如何,我没有使用任何模糊方法,所以没有真正的原因为什么编译后的代码会与源代码不同)。在使用cn1lib构建本地codenameone时,我可能缺少一些东西。

那么,是否已经有人成功地使用执行本机绑定的cn1lib进行本地构建了呢?如果是,确切的程序是什么?我真的希望有人能提供帮助,因为,在这一点上,我正在认真考虑坚持使用react-native(我很满意,并意识到它不是完全本地的事实),或者跳入flutter(或kotlin native),即使我仍然认为codenameone比这些其他解决方案提供了许多优势(但不能在开发阶段执行本地构建对我来说是完全不可能的)

共有1个答案

韶弘壮
2023-03-14

如前所述,在我的一些测试中(我使用我需要的全套cn1libs+一些自定义libs),我已经超过了1MB的限制(服务器为此拒绝了我的测试构建)。因此,在开发阶段使用免费构建云服务器对我来说不是一个选择(无论如何,如果我不确定我是否可以在必要时完全独立,我不会使用解决方案。为了构建我的发布版本,我肯定会订阅并使用云buid服务器,因为它比使用本地服务器方便得多,此外,我没有Mac电脑(我只有一台测试iphone),当我想构建一些iOS时,需要借用一台;).但我想确保,如果由于任何原因,您的服务丢失,我仍然能够生成我的构建。此外,我不认为在我的应用程序开发阶段支付订阅费有什么意义(这可能需要我几个月的时间),尤其是因为我不确定我是否会使用codenameone作为最终解决方案(我仍然必须检查它将需要多少工作量来调整我已经拥有的react-native的一些libs),这就是我试图进行本地构建的原因。

关于socket.io库,我已经开始创建一个cn1lib,它将使用本机解决方案(https://github.com/socketio/socket.io-client-java for android,https://github.com/socket.io-client-swift for iOS,原始的socket.io lib for javascript)。这实际上不是一个问题,它只是给出一个库的例子,如果我想从React-Native切换,我必须用codenameone创建库。

关于cn1lib如何工作,我已经搞清楚了,我在我的android项目中包含了CN1Google-Maps lib的所有必要类(因此我在项目中包含了main.zip、nativeand.zip和stubs.zip的内容),并检查了我生成的apk的.dex文件,它们实际上正确地打包在其中,正如前面所说的那样。所以我的问题似乎不是我忘记在我的项目中包含cn1lib的某个类,而是其他一些东西。错误消息为:exception:java.lang.ClassCastException-com.codename1.GoogleMaps.InternalNativeMapsimpl不能强制转换为com.codename1.System.NativeInterface,因此它不引用未找到的类,而是引用转换异常...我真的不知道是什么引起了这个问题。我从这里获得了codenameone核心类https://github.com/codenameone/codenameone/tree/master/codenameone/src/https://github.com/codenameone/codenameone/tree/master/ports/android http://github.com/codenameone/codenameone-skins

把它们包括在我的项目中,所以我想我没有错过一个。当构建一个不使用cn1lib的项目时(就像一个简单的“hello word”应用程序),它在我的android测试设备上编译和运行都很好。问题是,当我的应用程序试图创建一个googlemap视图时,它返回了cast异常(然后默认尝试创建一个html浏览器mapview,但在这里失败了,因为它缺少一些html文件)。因此,这可能是一个配置问题(可能是编译器作为本机类文件使用的java版本的问题,在cn1lib main.zip文件中已经编译过了吗?)下面是我使用的gradle构建文件:

buildscript {
        repositories {
            jcenter()
            maven { url "https://plugins.gradle.org/m2/" }
            google()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.0.1'
            classpath 'me.tatarka:gradle-retrolambda:3.2.0'
        }
    }


    allprojects {
        repositories {
            jcenter()
            google()
        }
    }

    apply plugin: 'com.android.application'
    apply plugin: 'me.tatarka.retrolambda'


    android {
        compileSdkVersion 26
        buildToolsVersion '26.0.2'
        dexOptions {
            // Prevent OutOfMemory with MultiDex during the build phase
            javaMaxHeapSize "4g"
        }
        lintOptions {
            checkReleaseBuilds false
        }

        defaultConfig {
            applicationId "com.tbdlab.testapp"
            minSdkVersion 15
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
            multiDexEnabled true
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //my proguard files are actually empty so no obfuscation is performed. I checked it in the generated apk
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_7//.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_7//.VERSION_1_8
        }
    }
    dependencies {
        compile fileTree(include: ['*.jar'], dir: 'libs')
        androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
                exclude group: 'com.android.support', module: 'support-annotations'
            })
        compile 'com.google.android.gms:play-services:9.4.0' //compile 'com.google.android.gms:play-services-maps:11.8.0'
        compile 'com.android.support:multidex:1.0.1'
    }

下面是我的AndroidManifest.xml文件,其中包含了CN1Lib中定义的所有权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
<!--- Permissions requiered by the google maps cn1lib -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>

<application android:allowBackup="true"  android:icon="@drawable/icon" android:label="MyApplication" android:name="android.support.multidex.MultiDexApplication">
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="...masked_it_but_put_my_correct_key_here..."/>
<activity  android:label="MyApplication" android:launchMode="singleTop" android:name="com.tbdlab.testapp.MyApplicationStub" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>
<receiver android:name="com.codename1.impl.android.LocalNotificationPublisher"/>
<service android:exported="false" android:name="com.codename1.impl.android.BackgroundFetchHandler"/>
<activity android:name="com.codename1.impl.android.CodenameOneBackgroundFetchActivity" android:theme="@android:style/Theme.NoDisplay"/>
<activity android:name="com.codename1.location.CodenameOneBackgroundLocationActivity" android:theme="@android:style/Theme.NoDisplay"/>
<service android:exported="false" android:name="com.codename1.location.BackgroundLocationHandler"/>
<service android:exported="false" android:name="com.codename1.location.GeofenceHandler"/>
<service android:exported="false" android:name="com.codename1.media.AudioService"/>
<activity android:excludeFromRecents="true" android:exported="false" android:name="com.google.android.gms.auth.api.signin.internal.SignInHubActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<provider android:authorities="com.tbdlab.testapp.google_measurement_service" android:exported="false" android:name="com.google.android.gms.measurement.AppMeasurementContentProvider"/>
<receiver android:enabled="true" android:name="com.google.android.gms.measurement.AppMeasurementReceiver">
    <intent-filter>
        <action android:name="com.google.android.gms.measurement.UPLOAD"/>
    </intent-filter>
</receiver>
<service android:enabled="true" android:exported="false" android:name="com.google.android.gms.measurement.AppMeasurementService"/>
<activity android:name="com.google.android.gms.ads.AdActivity" android:theme="@android:style/Theme.Translucent"/>
 类似资料:
  • 我想在构建时将salesforce的Enterprise.jar文件包含在我的项目中,使用gradle,有没有人可以帮助我在项目中包含src/main/resources文件夹中存在的本地jar文件。

  • 但是当我进行构建时,它无法编译一些引用webapp/WEB-INF/lib文件夹的jar的类。我不能将这些JAR作为依赖项包含在pom.xml中。 如何告诉maven在构建类和创建WAR时也包含WEB-INF/Lib JAR?

  • 我目前正在尝试将APK纳入我的AOSP 10版本。为此,我在< code>packages/apps下创建了一个新的模块文件夹,并将我的APK和一个Android.mk文件放入其中。然后,我将模块添加到PRODUCT_PACKAGES变量中。当< code>packages/apps下的模块是一个真正的文件夹时,这非常有用。然而,当我通过符号链接替换is时,该应用程序不会出现在新版本中。我的And

  • 问题内容: 在我的Android应用程序中,当执行引用从属.jar中的代码的代码时,出现提示。我的项目包括一个Android模块以及一个仅Java库模块,这是jar依赖项所在的位置。我正在使用gradle 1.10构建项目。这是我的项目布局: 主项目为空白,而主项目如下所示: Android应用看起来像: 该库是: 一切都编译和打包,没有错误,并且我在IDE(IntelliJ 13)中看不到任何错

  • 如本指南所述,我使用的是命令生成包含graalvm本机映像的zip文件。我正面临此线程中描述的问题,因此希望通过将传递给我的命令来包含资源,如下所示: 不幸的是,它失败了。我怎么能把这个传递给gradle任务?

  • 问题内容: 目前,我正在使用Android,试图避免使用Eclipse(对此我有非理性的仇恨)。 我需要包含一个外部文件(用于我的),并且不知道如何链接它以… 我已经阅读了文件,但是向XML 添加或节点并不能解决问题。 希望有人能帮助我! 问题答案: 只需将其放在目录中即可。从那里开始,其他所有工作都得到了照顾- 无需修改Ant脚本。例如,这是一个示例项目,显示了以这种方式集成BeanShell解