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

来源:互联网 发布:淘宝美工一般学多久 编辑:程序博客网 时间:2024/06/13 15:10

虚幻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接入流程和内容基本如上。


原创粉丝点击