2022年2月5日土曜日

【Android USB oscilloscope】(10) KotlinでThreadとHandleを動かす最弱なサンプルプログラム

余っているAndroidスマホをオシロにしよう!

前回、Handleが鬼の様にわからないとの辞世の句を述べました.

今日はこちらのサイトを参考に、kotlinでthreadとhandleを使う簡単なsampleを書いてみました.net界最弱のthreadサンプルだと思います.てかこのくらい脆弱なレベルからthreadなりhandleなりを解説してくれる者はどこにもおらんのか? 解説サイトはたくさんあるけど、どれもわたしのレベルを超えていて理解不能です.あとjavaの画面はビジーなのでkotlinがいいな.

project folder詰め合わせをupしておきます   →handleX.zip

動作の説明:
TEXT表示が1つ、ボタンが2つ あります.
ボタンを押すとTEXT表示が変わります.
2つのボタンの役割は、内部動作の違いです.
・表示画面(Main Activity)でTEXT書き換えする
・別のthreadを建ててそっちからhandleに何かを飛ばしてTEXT書き換えする

android studioで開いてもらうと判ると思いますが、kotlin codeはほぼこれだけです.onCreate()内でボタン処理を定義してるだけ.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {

        IDtxt1.text = "ボタンを押してください"
        IDbtn1.text = "Main Activity内でTEXTを書き換えるボタン"
        IDbtn2.text = "別スレッドを迂回してTEXTを書き換えるボタン"

        IDbtn1.setOnClickListener{    ①簡単にTEXT書き換えする
            IDtxt1.text = "Main ActivityでTEXTを書き換えました"
        }

        val handler = Handler()    ②別スレッド経由でTEXT書き換えする
        IDbtn2.setOnClickListener {
            Thread {     Handlerのpostメソッドで何かを送る
                handler.post {
                    IDtxt1.text = "Handlerを使って別スレッドからTEXTを書き換えました" 
                }
            }.start()

①はMain Activity内で処理している平和(ピンフ)なやり方です.

②はボタンが押されたら、別threadを建てる→handler.post→Main Activityで実行してほしい処理を宜しく頼む、という建てつけになってます.別threadはIDtxt1というものを知らないので、IDtxt1を知っているpost先の人に代行して頂きます.

スマホで動かせるthreadプログラムでこれ以上簡単なものって例示できないと思います.

thread,handlerの下りは「handler objectを設けた人にしか出来ない処理をpostする」と理解しておきますが、なにげに腑に落ちませんが、そうゆうものということで....

あと、何度もボタンを押すとthreadがその都度作られちゃってるのかな? threadの寿命ってオレ知らないや.

ーーーー
上記②について、やってることは同じなのだけど、もっと整理整頓した記述もできるようです.上の赤字の部分を下記のようにバラバラに書けます.こっちがプロっぽいかね?
project folder詰め合わせ   →handleX2.zip

        // IDtxt1を知っているここでhandlerを実態化しておく
        val handler = Handler()

        // 遠隔Threadからここに依頼が飛んでくる処理内容をRunnableに書く
        // run()の名前は決め打ち
        // IDtext1に表示する処理
        // object:をつけないと具合が悪いみたいよ
        val runnable = object : Runnable {
            override fun run() {
                IDtxt1.text = "Handlerを使って別スレッドからTEXTを書き換えました"
            }
        }

        // 別Threadを定義する
        // run()の名前は決め打ち.中に処理を書く
        // 上で実態化したhandlerにrunnableをpostするのが処理
        class thread : Thread() {
            public override fun run() {
                handler.post(runnable)
            }
        }

        // ボタンが押されたら、threadを実態化して起動する
        IDbtn2.setOnClickListener {
            val t = thread()
            t.start()
        }

9へ             11へ

かしこ

13 件のコメント:

  1. threadという単語を見て、思い出しました。
    マルチスレッドのアプリの場合ポインタ渡しはNGの意味。
    ある意味マルチスレッドのプログラムはハードウェアで言えば非同期回路だとNG.
    スレッドが他のスレッドへポインタを使って渡した後、元のスレッドが無くなるとポインタで渡したデータが消えるので例外で止まる。
    スレッド間はメッセージとか呼ばれる方法で渡していたような記憶があります。

    自分は3D設計でめげて、iphoneアプリでめげて、めげまくりです。
    きっと平坂さんががんばれば自分もまたがんばれるかも・・・?と思いながら見ています。
    「応援しています。」(^o^)/

    返信削除
    返信
    1. >きっと平坂さんががんばれば自分もまたがんばれるかも・・・?と思いながら見ています

      あはははー
      それはそうかも.
      わたしのソフト素人さは当ブログで知れ渡っていると思うので、迷える子羊たちよ我に続けw

      >元のスレッドが無くなるとポインタで渡したデータが消える

      あっちの処理終了を検知するのに例外をcatchしてとか、気味悪いことをしているような気配を察知しているところです.うひょー

      削除
  2. >threadの寿命

    「②別スレッド経由でTEXT書き換えする」以下をちゃんと書くと、多分こうなって、
    ---------------------------------------------
    val handler = Handler()

    class MyRunnable: Runnable() {
    public override fun run() {
    IDtxt1.text = "Handlerを使って別スレッドからTEXTを書き換えました"
    }
    }

    class MyThread: Thread() {
    public override fun run() {
    handler.post(MyRunnable())
    }
    }

    class MyButtonClick: View.OnClickListener() {
    public override fun onClick(View v) {
    val myThread = MyThread()
    myThread.start()
    }
    }

    IDbtn2.setOnClickListener(MyButtonClick())
    ---------------------------------------------
    要するに、「IDtxt1.text = ・・・」の行が終わったら、勝手に、Threadは終了すると思います。
    ※正確には、「myThread.start()」の次に行を書く(例えば、println("hoge")とか)と、そっちが先に実行されて、その次に「IDtxt1」が、書き換わって、終了、となると思います。

    ※Lambda式(元のような書き方)だと、「定義部」と「実行部」が、ごちゃごちゃになって、「いつ何が実行されるか」わかりずらくなってバグの温床になるので、私はあまり好きではありません。
    ちなみに、私はKotlin環境は持って無いので、↑のが本当に動くかどうかは不明です。

    返信削除
  3. インデントが全部消えてやんの。円マークといい、コメント改変しすぎだろ>blogspot
    これでどうかな?
    ---------------------------------------------
        val handler = Handler()

        class MyRunnable: Runnable() {
          public override fun run() {
            IDtxt1.text = "Handlerを使って別スレッドからTEXTを書き換えました"
          }
        }

        class MyThread: Thread() {
          public override fun run() {
            handler.post(MyRunnable())
          }
        }

        class MyButtonClick: View.OnClickListener() {
          public override fun onClick(View v) {
            val myThread = MyThread()
            myThread.start()
          }
        }

        IDbtn2.setOnClickListener(MyButtonClick())
    ---------------------------------------------

    返信削除
    返信
    1. これはありがたく。
      家についたらマジメに読みます。

      定義部と実行部が別の場所についてはわたしもそう思ってたところです。

      削除
    2. ↑のは、半角スペース*2 → 全角スペース に、置き換えただけです。
      そのまま開発環境に張り付けると、動かないかもしれません・・・

      削除
    3. Runnable()が登場しました.これがまだよくわかってないとこです.

      削除
  4. >あっちの処理終了を検知するのに例外をcatchしてとか
    ↑のように書けば、
    ・myThread.start()
    の、次の行に、
    ・myThread.join()
    と書けば、Threadの終了まで、待ってくれます。うまく書けば、myThread.なんとか、で、結果取得とかも出来るはず。

    Lambda式(元のような書き方)だと、こういうことができないので、「何か別の方法」でやるしかないんだろうな・・・

    >わたしのソフト素人さ
    いや、そんなことはないと思いますよ。ここまで書けるんだから。
    (私は、今日初めてKotlinのソースを見ました。なんか、(Java+JavaScript+c#)/3みたいな言語ですね。)

    返信削除
    返信
    1. >(Java+JavaScript+c#)/3

      ヘェ~そうゆう感じなんだ。JavaはともかくJavaScript C#はsourceすら見たことないっちゃ。
      C#は名付けがフザけ過ぎとわたしのゴーストが囁きます。

      削除
    2. >(Java+JavaScript+c#)/3
      Kotlinは、
      ・言語自体の元は、Java
      ・「最後のセミコロンが要らない」ところは、JavaScript
      ・その他、「いろんな言語の良いとこどり」をしてるところは、c#
      に、似てると思います。
      (最後のセミコロンが無いので、最初、typoかと思ってたら、言語仕様だった。)
      ※Androidアプリのソースを検索してみたのですが、Java版とKotlin版が混在してて、ちょっと紛らわしいですね・・・

      削除
    3. このコメントは投稿者によって削除されました。

      削除
    4. >(Java+JavaScript+c#)/3
      ・クラスの継承の書き方、は、c# から来てますね。
      extends ~ の代わりに、コロン「:」だけで済んでしまうところが良いですね。
      インスタンス生成に、new キーワードは要らないとあるのですが、これちょっと大丈夫?って気もする。

      削除
    5. 最後のセミコロンが無いのはpythonもそんなでしたかな.ウロですが.

      :は軽くて好きです.newは無くても済むもんなのかそうなのかと思いました.

      >Java版とKotlin版が混在

      書籍にせよnet情報にせよ、JAVAの方が情報量が多いのでkotlin学習者は不利な立場のようです.

      削除