0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

KonyのスレッドAPIについて

Last updated at Posted at 2021-06-28

目次

  1. はじめに
  2. 実装方法
  3. まとめ

はじめに

本記事では、KonyのThreading APIについてデモを用いて解説いたします。

まず**スレッド(Thread)**とは、プログラムが実行されていく一連の流れのことです。
この流れは通常一本ですが、処理に時間がかかる重たい処理を実行する時などには、複数の流れを用意しないと詰まってしまう(ユーザのアクションに対応できない、別の処理が実行できない)場合もあります。

例えば、以下のような処理は複数のスレッドによって成り立っています。

  • ブラウザを使用中、HTMLを読み込んでいる途中でも、戻るボタンを押せる
  • 重いファイルをダウンロードしている時に、ダウンロードの進行度が表示される

Konyでは kony.runOnMainThreadkony.runOnWorkerThreadというAPIを用いて、使用するスレッドを指定して処理を実行することができます。

それでは、APIの詳細について説明していきます。

kony.runOnMainThread

非同期のAPIで、メインスレッドでJavaScriptコードを実行するのに使用します。

パラメータ 説明
f [Function]【必須】 実行するコールバック関数を指定します。
args [Array]【必須】 f に渡されるパラメータを保持するJavaScript配列を指定します。

kony.runOnWorkerThread

メインの処理と並行して実行できるマルチスレッドを提供するAPIです。

パラメータ 説明
f [Function]【必須】 実行するコールバック関数を指定します。
args [Array]【必須】 f に渡されるパラメータを保持するJavaScript配列を指定します。

Konyでは、スレッドAPIを使用するためのガイドラインが以下のように記載されています。

・スレッドAPIは、マルチスレッド環境をネイティブにサポートします。

・アプリケーションは、複数の並行スレッドで構成できます。

・メインスレッド(UIスレッド)は、ウィジェットにイベントを割り当てて、UIの要素を描画する役割を果たします。

・メインスレッド(UIスレッド)が止まるような処理はNGです。メインスレッドでネットワークアクセスやデータベースクエリなどの時間のかかる操作を実行すると、ユーザーインターフェイスがブロックされます。

・メインスレッド(UIスレッド)の外部からUIコンポーネントにアクセスしないでください。

JavaScriptスレッド:
・UIの更新を必要としないJavaScriptで記述されたアプリケーションロジックは、メインスレッドまたはUIスレッドとは異なるスレッドで実行されます。

・UIを更新する操作は、メインスレッドまたはUIスレッドに投稿されます。

・API kony.runOnMainThread(function、args)を使用して、UIスレッドでJavaScriptバインディングとJavaScriptロジックを実行します。

注意:下記の場合は、非同期ではなく同期モードで実行されます。

例)

  • Mainスレッド上でrunOnMainThread()を実行した時
  • Workerスレッド上でrunOnWorkerThread()を実行した時

APIの説明は以上なので、 次に、デモを用いて実際の挙動について見てみましょう。

作成したデモ

実際にrunOnMainThread()、runOnWorkerThread()を使って、
以下の処理を各スレッドで実行してログを見ていきたいと思います。

  • Mainスレッド: ラベルの変更
  • Workerスレッド: 終了まで5秒かかる処理

ss.gif

まず、デモ用にFormを作成し、ラベル : lblMainボタン : btnRun を配置しました。
紹介する2つのAPIは iOS/Android用なので、Mobileで作成します。
スクリーンショット 2021-06-21 18.31.12.png

以下は、FromControllerに記載したソースです。

FromController
define({ 

  onClickBtn : function() {
    kony.print("___onClick");
    kony.runOnMainThread(this.mainFunction, [this.view.lblMain]);
    kony.print("___finish_onClick");
  },

  wokerFunction : function() {
    // 時間のかかる処理
  kony.print("___start_workerThread");
    var dt1 = new Date().getTime();
    var dt2 = new Date().getTime();
    var dtDiff = 0;
    var count = 0;

    // 5秒後に処理終了
    while (dtDiff < 5000){
      dt2 = new Date().getTime();
      dtDiff = dt2 - dt1;
      //2.5秒経過ごとにログを出力
      if(dtDiff % 2500 === 0){
        count++;
     kony.print("___count_workerThread : " + count);
      }
    }
  kony.print("___finish_workerThread");
  },

  mainFunction : function(widget) {
    kony.runOnWorkerThread(this.wokerFunction, [this.view.lblMain]);
    // テキストを変更する
  kony.print("___start_mainThread");
    widget.text = "【 Main Thread 】";
  kony.print("___finish_mainThread");
  },


});

wokerFunction では、WhileとDate().getTime()※現在時刻の取得
を使って、5秒後に終了する処理を書いています。
また、進捗がわかるように2.5秒に一回ログを出力させています。

mainFunctionでは、MainスレッドからrunOnWorkerThreadを呼び出して、
その後 引数として受け取っているLabelのテキストを変更する処理を書いています。

出力されるログ

ボタン押下後、Android StudioのLogcatで確認すると以下のようなログが出力されます。

スクリーンショット 2021-06-21 17.40.12.png

MainとWorkerに分けて見てみましょう。

  • 黄色い枠が Mainスレッドで実行されている処理
  • 赤い枠が 別スレッドで実行されている処理

スクリーンショット 2021-06-21 17.39.00.png
スクリーンショット 2021-06-21 17.37.05.png

ログについての説明
使用されているスレッドをログから確認することができます。

2021-06-21 15:54:08.834 12941-12965/com.orgname.appp D/StandardLib: ___onClick

ログメッセージの形式は次のとおりです。

date time PID-TID/package priority/tag: message

使用スレッドは、ログの PID-TID の部分で確認することができます。
PIDとTIDが同じ場合は基本となるスレッド(メインスレッド)が使用されています。

PID はプロセス ID の略で、TID はスレッド ID の略です。スレッドが 1 つしか存在しない場合、これらは同一になることがあります
https://developer.android.com/studio/debug/am-logcat?hl=ja

解説

①・②

スクリーンショット 2021-06-21 17.46.02.png

  onClickBtn : function() {
    kony.print("___onClick");
    kony.runOnMainThread(this.mainFunction, []);
    kony.print("___finish_onClick");
  },

①ボタン押下によって___onClickが出力されます。
②kony.runOnMainThread()は非同期のため、次に___finish_onClickが出力されます。

※ controller内のonClickBtnで出力しているログは、メインではなくrunOnWorkerThreadで使われるスレッドと同様のスレッドが使われるようです。

③〜⑧

スクリーンショット 2021-06-21 17.46.33.png

まず、Workerスレッドとは別スレッド(Mainスレッド)から、kony.runOnWorkerThreadを呼び出しているため非同期モードとなり、Workerスレッドの処理を待たずに③が実行されています。

  mainFunction : function(widget) {
    kony.runOnWorkerThread(this.wokerFunction, []);
    // テキストを変更する
  kony.print("___start_mainThread");
    widget.text = "【 Main Thread 】";
  kony.print("___finish_mainThread");
  },

その後、並行してwokerFunctionが実行され、④・⑤が出力されます。
次はmainFunctionの処理が終了することで⑥が出力されて、wokerFunctionにある残りの⑦・⑧が出力されます。

  wokerFunction : function() {
    // 時間のかかる処理
  kony.print("___start_workerThread");
    var dt1 = new Date().getTime();
    var dt2 = new Date().getTime();
    var dtDiff = 0;
    var count = 0;

    // 5秒後に処理終了
    while (dtDiff < 5000){
      dt2 = new Date().getTime();
      dtDiff = dt2 - dt1;
      //2.5秒経過ごとにログを出力
      if(dtDiff % 2500 === 0){
        count++;
     kony.print("___count_workerThread : " + count);
      }
    }
  kony.print("___finish_workerThread");
  },

ss.gif

デモの説明は以上です。

: 注意 :
はじめにの最後でもご紹介いたしましたが、controller内のメソッドでの処理は、runOnWorkerThreadで使われるスレッドと同様のスレッドが使われるようでした。

今回はMainスレッドの中で呼び出しましたが、
普通にrunOnWorkerThread()を実行すると、以下の理由から同期モードで実行されてしまうので、中身が全て実行されるまで待機状態になってしまいます。
使用の際は、使用元のメソッドがどのスレッドで実行されているかを確認しましょう。

注意:下記の場合は、非同期ではなく同期モードで実行されます。
例)

  • Mainスレッド上でrunOnMainThread()を実行した時
  • Workerスレッド上でrunOnWorkerThread()を実行した時

まとめ

今回はkony.runOnMainThreadkony.runOnWorkerThreadというAPIの使用説明・解説をいたしました。本記事がお役に立てば幸いです。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?