Kanzi application framework (appfw) から Kanzi Android framework (droidfw) への移行¶
これらの手順に従って、Kanzi アプリケーションを Kanzi application framework (appfw) から Kanzi Android framework (droidfw) に移行してください。
例えば、Coinのサンプルアプリケーションを Kanzi application framework (appfw) から Kanzi Android framework (droidfw) に移行するには:
Quick Start ウィンドウで Projects をクリックし、Examples タブを選択します。Coin の例の横にある
をクリックします。
<KanziWorkspace>/Examples/Coinでアプリケーションのコピーを作成します。Kanzi Studio で、Kanzi Studio プロジェクト
Tool_project/Coin.proj.kzmを開きます。メインメニューで、File > Export > Export KZB を選択します。
Android Studioで、
Application/configs/platforms/android_gradleディレクトリのプロジェクトを開きます。app/build.gradleで:アプリケーション
minSdkを26以上に設定してください。これは Kanzi Android framework (droidfw) に必要な最小SDKバージョンです。アプリケーションを Kanzi Android framework (droidfw) を使用するように構成します。置き換え
dependencies { ... implementation 'com.rightware.kanzi:kanziruntime@aar'
以下に置き換えます。
dependencies { ... implementation 'com.rightware.kanzi:kanziruntime-droidfw@aar'
kzjavaライブラリを依存関係として追加します。dependencies { ... implementation 'com.rightware.kanzi:kzjava@aar'
アプリケーションの Java 言語レベルを 11 以上に設定してください。
android { ... compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 }
app/src/main/res/layout/main.xmlで、ビュータイプを変更します。com.rightware.kanzi.KanziView
終点
com.rightware.kanzi.KanziSurfaceView
アプリケーションのアクティビティにおいて
app/src/main/java/com/rightware/kanzi/coin/Coin.java:onCreate(Bundle icicle)からアクティビティライフサイクルの登録を削除します。Kanzi Android framework (droidfw) はビューのライフサイクルコールバックを自動的に追跡します。mView = findViewById(R.id.kanzicontent); mView.registerLifecycle(getLifecycle());
onCreate(Bundle icicle)でkzbファイルをロードし、このKanziSurfaceViewでロードしたいプレハブを設定します。このプロジェクトでは、デフォルトでプレハブStartupPrefabを使用します。Kanzi application framework (appfw) では、ネイティブアプリケーションコードがkzbファイルをロードしましたが、Kanzi Android framework (droidfw) では、ネイティブアプリケーションコードは使用されていません。
mView = findViewById(R.id.kanzicontent); mView.setKzbPathList(new String[]{"Coin.kzb.cfg"}); mView.setStartupPrefabUrl("kzb://coin/StartupPrefab");
画面の向き変更の処理方法を変更します。
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mView.setOrientation(newConfig.orientation); }
終点
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mView.handleOrientationChange(newConfig.orientation); }
CMake構成
Application/CMakeLists.txtでは、リプレイス (Replace)
if(ANDROID) target_link_libraries(Coin -Wl,--whole-archive Kanzi::kzappfw -Wl,--no-whole-archive)
以下に置き換えます。
if(ANDROID) target_link_libraries(Coin -Wl,--whole-archive Kanzi::kzdroidfw -Wl,--no-whole-archive)
kzinteropとkzjavaライブラリをアプリケーションにリンクします。置き換えtarget_link_libraries(Coin Kanzi::kzui Kanzi::kzcoreui)
以下に置き換えます。
target_link_libraries(Coin Kanzi::kzui Kanzi::kzcoreui Kanzi::kzinterop Kanzi::kzjava)
アプリケーションは現在 Kanzi Android framework (droidfw) を使用しており、Androidデバイスで実行できます。
アプリケーションコードの移行¶
Kanzi application framework (appfw) から Kanzi Android framework (droidfw) にアプリケーションを移行した後、そのアプリケーション内のC++コードは使用されなくなります。アプリケーションの既存のC++コードをJavaアプリケーションまたはプラグインコードに移行するか、機能をC++ Kanzi Engine プラグインにリファクタリングすることができます。Java APIは完全な Kanzi Engine APIを実装していないため、アプリケーションコードの移行方法はアプリケーションの機能に依存します。
すべてのcppファイルを1つを除いて削除することができます。アプリケーションをビルドするには、CMakeは1つのcppファイルを必要とします。そのファイルが空であっても構いません。例えば、Application/src/coin.cpp の内容を削除します。
例えば、Javaを使用してCoinの例でフレーム時間を Text Block ノードに表示するには、次のようにします。
app/src/main/java/com/rightware/kanzi/coin/Coin.javaのアプリケーションアクティビティで、Coinクラスにメソッドを追加します。void updateFrameTime(Duration duration) { TextBlock2D frameTime = mView.getRoot().lookupNode("#FrameTime"); frameTime.setText("Frame time: " + duration.toMillis() + " ms"); }
onCreate(Bundle icicle)で、メインループスケジューラタスクを追加して、メソッドを毎フレーム実行します。KanziRuntime.Reference runtimeRef = KanziRuntime.acquire(this); mView.addListener(new KanziViewListener() { @Override public void onStartupPrefabLoaded(View view, Domain domain) { runtimeRef.get().getDomain().getMainLoopScheduler().appendTask( MainLoopScheduler.UserStage, "Update Frame Time", TaskRecurrence.Recurring, duration -> updateFrameTime(duration)); } });
これが変更を加えたときの app/src/main/java/com/rightware/kanzi/coin/Coin.java の外観です。
package com.rightware.kanzi.coin;
import android.content.res.Configuration;
import android.os.Bundle;
import androidx.fragment.app.FragmentActivity;
import android.view.View;
import android.view.WindowManager;
import com.rightware.kanzi.Domain;
import com.rightware.kanzi.KanziRuntime;
import com.rightware.kanzi.KanziView;
import com.rightware.kanzi.KanziViewListener;
import com.rightware.kanzi.MainLoopScheduler;
import com.rightware.kanzi.TaskRecurrence;
import com.rightware.kanzi.TextBlock2D;
import java.time.Duration;
public class Coin extends FragmentActivity
{
private static final String TAG = "Coin";
private KanziView mView = null;
@Override
protected void onCreate(Bundle icicle)
{
setContentView(R.layout.main);
mView = findViewById(R.id.kanzicontent);
mView.setKzbPathList(new String[]{"Coin.kzb.cfg"});
mView.setStartupPrefabUrl("kzb://coin/StartupPrefab");
// Force the screen to stay on when this app is on front (no need to clear).
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
KanziRuntime.Reference runtimeRef = KanziRuntime.acquire(this);
mView.addListener(new KanziViewListener() {
@Override
public void onStartupPrefabLoaded(View view, Domain domain) {
runtimeRef.get().getDomain().getMainLoopScheduler().appendTask(
MainLoopScheduler.UserStage,
"Update Frame Time",
TaskRecurrence.Recurring, duration -> updateFrameTime(duration));
}
});
super.onCreate(icicle);
}
void updateFrameTime(Duration duration)
{
TextBlock2D frameTime = mView.getRoot().lookupNode("#FrameTime");
frameTime.setText("Frame time: " + duration.toMillis() + " ms");
}
@Override
protected void onDestroy()
{
super.onDestroy();
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
mView.handleOrientationChange(newConfig.orientation);
}
}
トラブルシューティング¶
Kanzi アプリケーションを Kanzi application framework (appfw) から Kanzi Android framework (droidfw) に移植する際に遭遇する可能性がある最も一般的な問題のいくつかを以下に示します。
エラー:
<KanziWorkspace>\Projects\CoinPort\Application\configs\platforms\android_gradle\app\src\main\java\com\rightware\kanzi\coin\Coin.java:21: error: cannot find symbol mView.registerLifecycle(getLifecycle()); ^ symbol: method registerLifecycle(Lifecycle) location: variable mView of type KanziView理由: Kanzi Android framework (droidfw) にはこのAPIがありません。アクティビティのライフサイクルコールバックを手動で登録する必要はありません。
解決策: この呼び出しを削除できます。
エラー:
7961-7961/com.rightware.kanzi.coin E/AndroidRuntime: FATAL EXCEPTION: main Process: com.rightware.kanzi.coin, PID: 7961 java.lang.NoSuchMethodError: No static method metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; in class Ljava/lang/invoke/LambdaMetafactory; or its super classes (declaration of 'java.lang.invoke.LambdaMetafactory' appears in /apex/com.android.art/javalib/core-oj.jar) at com.rightware.kanzi.KanziViewAdapter.handleAttachedToWindow(KanziViewAdapter.java:274)理由: あなたのアプリケーションは、Kanzi Android framework (droidfw) の最小Java言語バージョン要件を満たしていません。
解決策:
app/build.gradleで、compileOptionsのsourceCompatibilityとtargetCompatibilityをJavaVersion.VERSION_11以上に設定します。エラー:
9136-9136/? E/ware.kanzi.coin: No implementation found for long com.rightware.kanzi.KanziRuntime.nCreate(android.content.Context) (tried Java_com_rightware_kanzi_KanziRuntime_nCreate and Java_com_rightware_kanzi_KanziRuntime_nCreate__Landroid_content_Context_2) 9136-9136/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.rightware.kanzi.coin, PID: 9136 java.lang.UnsatisfiedLinkError: No implementation found for long com.rightware.kanzi.KanziRuntime.nCreate(android.content.Context) (tried Java_com_rightware_kanzi_KanziRuntime_nCreate and Java_com_rightware_kanzi_KanziRuntime_nCreate__Landroid_content_Context_2) at com.rightware.kanzi.KanziRuntime.nCreate(Native Method) at com.rightware.kanzi.KanziRuntime.<init>(KanziRuntime.java:43) at com.rightware.kanzi.KanziRuntime.getOrCreateInstance(KanziRuntime.java:195) at com.rightware.kanzi.KanziRuntime.acquire(KanziRuntime.java:67) at com.rightware.kanzi.coin.Coin.onCreate(Coin.java:30)理由: アプリケーションが
Kanzi::kzdroidfwではなくKanzi::kzappfwにリンクしています。解決策:
Application/CMakeLists.txtでのリンクをKanzi::kzappfwからKanzi::kzdroidfwに変更します。エラー:
5629-5629/? E/ware.kanzi.coin: No implementation found for long com.rightware.kanzi.mathJNI.new_ColorRGBA__SWIG_3(float, float, float, float) (tried Java_com_rightware_kanzi_mathJNI_new_1ColorRGBA_1_1SWIG_13 and Java_com_rightware_kanzi_mathJNI_new_1ColorRGBA_1_1SWIG_13__FFFF) 5629-5629/? D/AndroidRuntime: Shutting down VM --------- beginning of crash 5629-5629/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.rightware.kanzi.coin, PID: 5629 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.rightware.kanzi.coin/com.rightware.kanzi.coin.Coin}: android.view.InflateException: Binary XML file line #6 in com.rightware.kanzi.coin:layout/main: Binary XML file line #6 in com.rightware.kanzi.coin:layout/main: Error inflating class com.rightware.kanzi.KanziSurfaceView at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4166) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4312) ...理由: アプリケーションは
Kanzi::kzjavaのネイティブバックを見つけることができません。解決策:
Application/CMakeLists.txtにKanzi::kzinterop Kanzi::kzjavaをリンクされたターゲットのリストに追加します。