Handler(遅延処理)
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秒後");
}
}