虚幻4中,android第三方类库的接入

xiaoxiao2021-02-28  102

虚幻4中安卓sdk的接入, 可以使用 APL (Android Programming Language) 进行第三方库的接入,首先创建一个NAME_APL.XML 文件,该文件包括了库文件的拷贝、权限的写入、activity java文件的修改和添加等一系列android打包和接口修改的内容。不再需要手动去修改代码或者Java层的文件和代码调用接口。

1.创建一个插件并在插件Source目录下创建一个NAME_APL.XML文件,在该插件模块Name.Build.cs文件中调用如下:

public class PluginModuleName : ModuleRules { public PluginModuleNamePluginModuleName(TargetInfo Target) { // Additional Frameworks and Libraries for Android if (Target.Platform == UnrealTargetPlatform.Android) { PrivateDependencyModuleNames.AddRange(new string[] { "Launch" }); string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory, BuildConfiguration.RelativeEnginePath); AdditionalPropertiesForReceipt.Add(new ReceiptProperty("AndroidPlugin", Path.Combine(PluginPath, "NAME_APL.XML"))); } } }

2.项目中加载该模块

包含头文件目录, 把插件Type改成Runtime(这个貌似很关键,之前没注意)
PublicIncludePaths.AddRange( new string[] { "PluginModuleName/Public", } ); PrivateIncludePaths.AddRange( new string[] { "PluginModuleName/Private", } ); PublicDependencyModuleNames.AddRange(new string[] { "PluginModuleName" }); PrivateIncludePathModuleNames.AddRange(new string[] { "PluginModuleName" });

3.APL_AML中文件结构说明

(1). proguardAdditions,代码混淆
<proguardAdditions> <insert> ########################################################################################## sdkname -dontwarn com.sdkname.** -keep class com.sdkname.** {*;} </insert> </proguardAdditions>
(2). prebuildCopies,目录文件拷贝
<prebuildCopies> <copyDir src="$S(PluginDir)/../../Libs" dst="$S(BuildDir)" /> </prebuildCopies>
(3). gameActivityImportAdditions,引用插入
<gameActivityImportAdditions> <insert> import com.sdkname.*; import com.sdkname.name.*; </insert> </gameActivityImportAdditions>
(4). gameActivityClassAdditions, 成员变量, 函数插入
<gameActivityClassAdditions> <insert> private AmazonIapManager AmazonManager; public void AndroidThunkJava_IapSetupServiceAmazon() { Log.debug("[JAVA] - AndroidThunkJava_IapSetupServiceAmazon"); AmazonManager = new AmazonIapManager(this); final AmazonPurchasingListener amazonPurchasingListener = new AmazonPurchasingListener(AmazonManager); PurchasingService.registerListener(this.getApplicationContext(), amazonPurchasingListener); if( AmazonManager == null ) { Log.debug("[JAVA] - Amazon Manager is invalid"); } } </insert> </gameActivityClassAdditions>
(5). gameActivity[funname]Additions, 在函数中出入内容
<gameActivityOnPauseAdditions> <insert> if(gvrLayout != null) { gvrLayout.onPause(); } </insert> </gameActivityOnPauseAdditions>
(6). resourceCopies, 文件拷贝,指定源和目标
<resourceCopies> <log text="Copying GoogleVR runtime files to staging" /> <isArch arch="armeabi-v7a"> <copyFile src="$S(EngineDir)/Source/ThirdParty/GoogleVR/lib/android_arm/libgvr.so" dst="$S(BuildDir)/libs/armeabi-v7a/libgvr.so" /> </resourceCopies>
(7).androidManifestUpdates修改AndroidManifest.xml文件
<androidManifestUpdates> <!-- Add features --> <addFeature android:name="android.hardware.sensor.accelerometer" android:required="true" /> <if condition="bSupportDaydream"> <true> <addFeature android:name="android.hardware.vr.high_performance" android:required="true" /> </true> <false> <addFeature android:name="android.hardware.vr.high_performance" android:required="false" /> </false> </if> <!-- Add intents --> <loopElements tag="activity"> <setStringFromAttribute result="activityName" tag="$" name="android:name" /> <setBoolIsEqual result="bGameActivity" arg1="$S(activityName)" arg2="com.epicgames.ue4.GameActivity" /> <if condition="bGameActivity"> <true> <!-- Check for existing intent filter --> <setBool result="bHasIntentFilter" value="false" /> <loopElements tag="intent-filter"> <setBool result="bHasIntentFilter" value="true" /> </loopElements> <!-- If no intent filter found, add a new one --> <if condition="bHasIntentFilter"> <false> <setElement result="newIntentFilter" value="intent-filter" /> <addElement tag="$" name="newIntentFilter" /> </false> </if> </true> </if> </loopElements> </androidManifestUpdates>
(7). soLoadLibrary, 在GameActivity.java中指定so库先于libUE4.so加载
<soLoadLibrary> <loadLibrary name="gvr" failmsg="GoogleVR library not loaded and required!" /> </soLoadLibrary>

4.虚幻4中jni的接口调用

if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { // Populate some java types with the provided product information jobjectArray ProductIDArray = (jobjectArray)Env->NewObjectArray(ProductIds.Num(), FJavaWrapper::JavaStringClass, NULL); jbooleanArray ConsumeArray = (jbooleanArray)Env->NewBooleanArray(ProductIds.Num()); jboolean* ConsumeArrayValues = Env->GetBooleanArrayElements(ConsumeArray, 0); for (uint32 Param = 0; Param < ProductIds.Num(); Param++) { jstring StringValue = Env->NewStringUTF(TCHAR_TO_UTF8(*ProductIds[Param])); Env->SetObjectArrayElement(ProductIDArray, Param, StringValue); Env->DeleteLocalRef(StringValue); ConsumeArrayValues[Param] = IsConsumableFlags[Param]; } Env->ReleaseBooleanArrayElements(ConsumeArray, ConsumeArrayValues, 0); static jmethodID Method = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_IapQueryInAppPurchasesAmazon", "([Ljava/lang/String;[Z)Z", false); FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, Method, ProductIDArray, ConsumeArray); // clean up references Env->DeleteLocalRef(ProductIDArray); Env->DeleteLocalRef(ConsumeArray); }

5.虚幻4代码如果需要调用jni, 则必须包含模块 “Launch”

if (Target.Platform == UnrealTargetPlatform.Android) { PrivateDependencyModuleNames.AddRange(new string[] { "Launch" }); }

暂时理解到虚幻4的sdk接入流程和内容基本如上。

转载请注明原文地址: https://www.6miu.com/read-41225.html

最新回复(0)