rokkonet

PC・Androidソフトウェア・アプリの開発・使い方に関するメモ

マルチスレッド Thread Runnable Handler android開発 java

2020 Jul. 25.
2020 Jul. 18.
2020 Jul. 11.


出典元
https://hogehuga.com/post-143/
http://mixi-inc.github.io/AndroidTraining/fundamentals/2.12.handler-and-looper.html
http://www.fineblue206.net/archives/230
http://accelebiz.hatenablog.com/entry/2016/09/01/061934
https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Thread.html
https://javabayashi.hatenablog.com/entry/2014/05/29/193103

スレッド間通信を行わない別スレッドの実行

Threadクラスのrunメソッドをオーバーライドして別スレッド実行(androidに限らずjava一般)

 Thread#start()で別スレッドを実行すること

// MyThread.java
class MyThread extends Thread {
    public void run() {
        CODES FOR ANOTHER THREAD
    }
}
// MainActivity.java
MyThread myThread = new MyThread();
myThread.start();
Runnableインターフェースのrunメソッドを実装して別スレッド実行(androidに限らずjava一般)

Runnableインターフェースを引数としてThreadインスタンスをコンストラクトする。
 Thread#start()で別スレッドを実行すること

// MainActivity.java
Thread myThread = new Thread(new Runnable(){
    @Override
    public void run() {
        CODES FOR ANOTHER THREAD
    }
});

// run another thread
myThread.start();


スレッド間通信を行う別スレッドの実行

別スレッドを実行すると共に、結果表示などをHandlerによって別スレッドからメインスレッドに処理依頼する(android独自手法)

上記の「スレッド間通信を行わない別スレッド」コードの別スレッド処理コードの後に、Handler#post()を記述する。
Handler#post()の引数をRunnableインターフェースとし、
別スレッドからメインスレッドへの依頼内容をrunメソッドの実装として記述する。

引数なしに myHandler=new Handler()とインスタンスを生成すると、
myHandler.post( ){new Runnable( ){ SOMEJOB }}で実行するSOMEJOBが、
new Handler()を実行したスレッド内で実行される。
myHandler=new Handler(LOOPER)として、myHandler.post( ){new Runnable( ){ SOMEJOB }}とすると
LOOPERが示すスレッド内で実行される。

// MainActivity.java  

Handler myHandler = new Handler();
buttonStart.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                ここに別スレッド処理を記述
                myHandler.post(  // 別スレッドからメインスレッドへの依頼
                    new Runnable( ){
                        run( ){
                            ここに別スレッドからメインスレッドへの依頼を記述
                        }
                    }
                );
            }
        });
    }
});


java sample

// MainActivity.java
package YOUR.PACKAGE.mylearnthreadjava;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    TextView textView1;
    Button buttonStart;
    int num = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView1 = (TextView)findViewById(R.id.text_view1);
        buttonStart = (Button)findViewById(R.id.button_start);

        final Handler myHandler = new Handler(Looper.getMainLooper());

        buttonStart.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // 別スレッドを実行
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        num += 1;

                        // Handlerを使用してメイン(UI)スレッドに処理を依頼する
                        myHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                textView1.setText(Integer.toString(num));
                                Toast.makeText(MainActivity.this, "tapped", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }

                }).start();
            }
        });
    }
}


kotlin sample

package YOUR.PACKAGE.mylearnmultithread

import android.os.Bundle
import android.os.Handler
import android.os.SystemClock.sleep
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    var num:Int = 0
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        text_view1.setText(R.string.countZero)
        val myHandler = Handler()
        button_start.setOnClickListener{
            // 別スレッドを実行
            // SAM(Single Abstract Method)変換によりrun()記述を省略
            Thread(Runnable {
                sleep(1000)
                num += 1

                // Handlerを使用してメイン(UI)スレッドに処理を依頼する
                // SAM(Single Abstract Method)変換によりRunnable(){run()}記述を省略
                myHandler.post {
                    text_view1.setText(num.toString())
                    Toast.makeText(this, "tapped", Toast.LENGTH_SHORT).show()
                }
            }).start()
        }
    }
}