LoginSignup
0
1

More than 3 years have passed since last update.

【Android】遅延処理・非同期処理を使って時間差でViewに反映させる

Posted at

Handler(遅延処理)

image.png

3つのTextViewに1秒ずつテキストをセットしてみます。

MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private Handler handler = new Handler();

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

    public void btnOnClick(View view) {

        final TextView txt1 = findViewById(R.id.txt1);
        final TextView txt2 = findViewById(R.id.txt2);
        final TextView txt3 = findViewById(R.id.txt3);

        txt1.setText("開始");

        //Runnableインターフェースのrunメソッドをオーバーライドしている。
        //そしてpostDelayedメソッドの引数としてrunメソッドを利用している。
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                txt2.setText("1秒後");
            }
        }, 1000);

        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                txt3.setText("2秒後");
            }
        }, 2000);
    }


activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="開始"
        android:onClick="btnOnClick"/>

    <TextView
        android:id="@+id/txt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/txt2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/txt3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

AsyncTask(非同期処理)

※AsyncTaskはAndroid11から非推奨になるようです。

こちらも3つのTextViewに時間差で文字セット。
activity_main.xmlは遅延処理のソースと同じ。

AsyncText.java
import android.content.Context;
import android.os.AsyncTask;
import android.widget.TextView;
import java.lang.ref.WeakReference;

public class AsyncText extends AsyncTask<String,String,String> {
    //WeakReferenceにするとリークを防げる
    private WeakReference<TextView> txt1;
    private WeakReference<TextView> txt2;
    private WeakReference<TextView> txt3;

    AsyncText(Context context) {
        //Viewの取得
        super();
        MainActivity activity = (MainActivity)context;
        txt1 = new WeakReference<>((TextView)activity.findViewById(R.id.txt1));
        txt2 = new WeakReference<>((TextView)activity.findViewById(R.id.txt2));
        txt3 = new WeakReference<>((TextView)activity.findViewById(R.id.txt3));
    }

    // 非同期処理を開始する前
    @Override
    protected void onPreExecute() {
        txt1.get().setText("開始前");
    }

    // 非同期処理の途中経過
    @Override
    protected void onProgressUpdate(String... values) {
        txt2.get().setText(values[0]);
    }

    // 非同期処理を終了した後
    @Override
    protected void onPostExecute(String result) {
        txt3.get().setText(result);

    }

    // 非同期処理をキャンセル
    @Override
    protected void onCancelled() {
    }


    //メインスレッドとは別のスレッドで実行される
    //ここに非同期で行いたい処理を書く
    @Override
    protected String doInBackground(String... strings) {
        publishProgress("途中");// onProgressUpdateを呼び出す

        //1秒待つ
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //戻り値はonPostExecuteに引数として渡される
        return strings[0];
    }
}
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;

public class MainActivity extends AppCompatActivity {
    private Handler handler = new Handler();

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

    public void btnOnClick(View view) {
        AsyncText asyncText = new AsyncText(this);
        asyncText.execute("非同期処理完了");//doInBackgroundメソッドが呼び出される
    }
}

Thread.sleep(失敗例)

これだと2秒後に全TextViewが一気に表示されてしまう。

MainActivity.java
package to.msn.wings.copy;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private Handler handler = new Handler();

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

    public void btnOnClick(View view) throws InterruptedException {

        final TextView txt1 = findViewById(R.id.txt1);
        final TextView txt2 = findViewById(R.id.txt2);
        final TextView txt3 = findViewById(R.id.txt3);

        txt1.setText("開始");
        Thread.sleep(1000);
        txt2.setText("1秒後");
        Thread.sleep(1000);
        txt3.setText("2秒後");
    }
}
0
1
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
1