728x90
반응형
💡비동기(Asynchronous) 실행"의 정형화된 패턴
- 실행(execute) : 비동기(Asynchronous) 작업 준비 및 시작.
- 백그라운드 작업(doInBackground) : 백그라운드 스레드에서 비동기(Asynchronous) 작업 실행.
- 진행 상황 업데이트(onProgressUpdate) : 백그라운드 스레드 진행 상황을 메인스레드로 전달.
- 비동기 실행 완료 후 처리(onPostExecute) : 백그라운드 스레드 완료 후 메인스레드에 완료 상태 전달.
execute -> doInBackground -> onProgressUpdate -> onPostExecute
📃어싱크태스크 예제
📝activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/text"
android:text="0"
android:gravity="center"
android:textSize="40sp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/update"
android:layout_gravity="center"
android:onClick="mOnClick"
android:text="Updata"/>
</LinearLayout>
📝MainActivity.java
◾ AccumulateTask 클래스 생성
◾ AccumulateTask 객체 생성
◾ execute로 실행한다.
◾ onPreExecute에서 value 값 지정
◾ doInBackground에서 value가 50보다 작을 때까지 publishProgress메소드를 통해 onProgressUpdate 호출
◾ onProgressUpdate에서 텍스트뷰에 값 세팅
◾ 작업을 모두 마치면 onPostExecute가 실행되고, 해당 텍스트가 세팅된다.
package com.project.test02;
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
long value;
TextView mText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mText = (TextView)findViewById(R.id.text);
}
public void mOnClick(View v) {
AccumulateTask myTask = new AccumulateTask();
myTask.execute(50);
// new AccumulateTask().execute(100);
}
class AccumulateTask extends AsyncTask<Integer, String, Long> {
protected void onPreExecute() {
value = 0;
}
protected Long doInBackground(Integer... params) {
while (isCancelled() == false) {
value++;
if (value < params[0]) { // execute의 인자값이 params[0] 로 전달
publishProgress(value + ""); // onProgressUpdate가 호출됨
} else {
break;
}
try { Thread.sleep(50); } catch (InterruptedException e) {;}
}
return value;
}
protected void onProgressUpdate(String... progress) {
mText.setText(progress[0]);
}
@Override
protected void onPostExecute(Long result) {
super.onPostExecute(result);
mText.setText("success!!! " + result);
Log.i("jenn", "작업을 마친 후 반환 값은 " + result + "입니다");
}
}
}
📃어싱크태스크를 이용한 프로그레스바 진행 표시
📝activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="100dp"
android:layout_centerInParent="true"
android:max="100"
android:progress="0" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="start"
android:layout_below="@id/progressBar"
android:onClick="mOnClick"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
📝MainActivity.java
package com.project.test03;
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
ProgressBar pb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pb = findViewById(R.id.progressBar);
}
public void mOnClick(View v) {
int max = pb.getMax();
new AccumulateTask().execute(max);
}
class AccumulateTask extends AsyncTask<Integer, Integer, String> {
static final String RESULT_SUCCESS = "SUCCESS";
int progress = 0;
@Override
protected void onPreExecute() {
progress = 0;
}
@Override
protected String doInBackground(Integer... params) {
while(progress < params[0]) {
progress++;
publishProgress(progress);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return RESULT_SUCCESS;
}
@Override
protected void onProgressUpdate(Integer... values) {
pb.setProgress(values[0]);
}
@Override
protected void onPostExecute(String result) {
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
}
}
}
📃초 단위 타이머 만들기
📝activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:id="@+id/et_time"
android:hint="초 단위로 입력하세요"
android:inputType="time"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/btn_start"
android:onClick="onClickStart"
android:layout_weight="1"
android:text="시작"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/btn_stop"
android:onClick="onClickStop"
android:layout_weight="1"
android:text="중지"/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/tv_count"
android:text="0"
android:layout_centerInParent="true" />
</RelativeLayout>
📝MainActivity.java
package com.project.test04;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
TimerTask tickTask; // 1초마다 카운트
TimerTask finishTask; // 에디트에 입력한 시간이 되면 실행
Timer timer = new Timer();
TextView tv_count; // 카운트 초를 출력하는 텍스트뷰
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_count = findViewById(R.id.tv_count);
}
// 시작 버튼을 클릭했을 때 호출되는 onClickStart()에서 타이머태스크 두 개를 생성한다.
// 하나는 1초마다 증가되는 시간을 카운트 할 tickTask
// 다른 하나는 에티드에 입력한 시간이 되면 tickTask를 중지한다.
public void onClickStart(View v) {
tickTask = new TimerTask() {
int count = 0;
@Override
public void run() {
count++;
tv_count.post(new Runnable() {
@Override
public void run() {
tv_count.setText(count + "초");
}
});
}
};
finishTask = new TimerTask() {
@Override
public void run() {
tickTask.cancel();
tickTask = null;
}
};
EditText et = findViewById(R.id.et_time);
int sec = Integer.valueOf(et.getText().toString());
int delay = sec * 1000; // 에디트에 입력된 값을 밀리세컨드로 변환
timer.schedule(finishTask, delay); // 입력된 시간에 finishTask 실행
timer.schedule(tickTask, 0, 1000); // 1초마다 tickTask가 실행
}
// 정지 버튼이 눌리면 모든 타이머태스크를 중지한다.
public void onClickStop(View v) {
if(tickTask != null) {
tickTask.cancel();
tickTask = null;
}
if(finishTask != null) {
finishTask.cancel();
finishTask = null;
}
}
}
728x90
반응형
'App > Android Studio' 카테고리의 다른 글
Android Studio - 프레퍼런스 (0) | 2022.08.12 |
---|---|
Android Studio - 공유 프레퍼런스, dialog (0) | 2022.08.11 |
Android Studio - 스레드와 핸들러 (0) | 2022.08.11 |
Android Studio - 프로그레스바와 핸들러 (0) | 2022.08.11 |
Android Studio - 초 타이머 만들기 (0) | 2022.08.10 |
댓글