Notice
Recent Posts
Recent Comments
Today
Total
05-04 00:14
Archives
관리 메뉴

Jeongchul Kim

안드로이드 Thread Handler AsyncTask 본문

Android

안드로이드 Thread Handler AsyncTask

김 정출 2016. 3. 23. 14:47


안드로이드 Thread Handler AsyncTask



ThreadTest 프로젝트를 만듭시다.


activity_main.xml

<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"

android:orientation="vertical">

  <Button

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:id="@+id/btn1"

android:text="Toast"/>

  <Button

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:id="@+id/btn2"

android:text="Count"/>


<TextView

android:layout_gravity="center"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textSize="20sp"

android:text="0"

android:id="@+id/txt"/>


</LinearLayout>



MainActivity.java

package com.example.threadtest;

import android.app.Activity;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.Button;

import android.widget.TextView;

import android.widget.Toast;

public class MainActivity extends Activity {

private Button btn1,btn2;

private TextView txt;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

btn1 = (Button)findViewById(R.id.btn1);

btn2 = (Button)findViewById(R.id.btn2);

txt = (TextView)findViewById(R.id.txt);

btn1.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Toast.makeText(MainActivity.this,"Hello",Toast.LENGTH_LONG).show();

}

});

btn2.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

for(int i=0;i<100;i++) {

/** 오류가 생긴다. ANR(Anroid Not Responding 창이 뜨면서 응답하지 않음. 대기하면 이어서 작업진행*/

txt.setText(i+""); // ""은 문자열로 자동 형변환

try {

Thread.sleep(500);

} catch (InterruptedException e) {


e.printStackTrace();

}

}

}

});

}

}


내부적으로는 일하고 있으나, 디바이스 에서는 오류가 발생


Thread, Handler, Message

Thread와 Handler와 Message를 이용하여 Code를 수정해봅시다.


package com.example.threadtest;

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.Button;

import android.widget.TextView;

import android.widget.Toast;

public class MainActivity extends Activity {

private Button btn1,btn2;

private TextView txt;

Handler handler = new Handler() {

public void handleMessage(android.os.Message msg) {

// 데이터를 공유하려면 이벤트 시스템과 Queue가 필요함

int count = msg.arg1;

txt.setText(count+"");

};

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

btn1 = (Button)findViewById(R.id.btn1);

btn2 = (Button)findViewById(R.id.btn2);

txt = (TextView)findViewById(R.id.txt);

btn1.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Toast.makeText(MainActivity.this,"Hello",Toast.LENGTH_LONG).show();

}

});

btn2.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

/** Thread Handler로 실행 한다. */

Thread t = new Thread() {

public void run() {

super.run();

for(int i=0;i<100;i++) {

//txt.setText(i+""); // ""은 문자열로 자동 형변환

Message msg = Message.obtain(); // 재활용한다.

msg.arg1 = i;

handler.sendMessage(msg);

try {

Thread.sleep(500);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

};

};

t.start();

}

});

}

}



오류 없이 실행이 잘됩니다.


Thread.sleep()을 사용하기 싫다면 다음과 같은 방법도 있습니다.


handler.sendMessageDelayed(msg,500+i*100);


가독성을 높이기 위해 코드를 변경한다.


public class MainActivity extends Activity {

private int cnt; // 전역변수 설정

Handler handler = new Handler();


@Override

public void onClick(View v) {

/** Thread Handler로 실행 한다. */

Thread t = new Thread() {

public void run() {

super.run();

for(int i=0;i<10;i++) {

cnt = i; // 전역변수 cnt

handler.post(new Runnable() {

@Override

public void run() {

txt.setText(cnt+"");

// i는 핸들로러 접근이 불가능하므로 전역 변수가 필요하다 }

});

}

}

}

}


하지만 지금도 구조적으로 문제가 있다.

AsyncTask

AsyncTask 클래스를 이용해보자.

액티비티를 하나 더 생성합시다


AsyncTaskActivity.java


package com.example.threadtest;

import java.security.PublicKey;

import android.app.Activity;

import android.os.AsyncTask;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.Button;

import android.widget.TextView;

import android.widget.Toast;

public class AsyncTaskActivity extends Activity {

private Button btn1,btn2;

private TextView txt;

class MyTask extends AsyncTask<Void, Integer, Void> {

// 첫째 Parameter params는 입력

// 둘째 Parameter Progress

// 마지막 Parameter Result는 리턴값

@Override

protected void onPreExecute() {

super.onPreExecute();

}

/** Thread의 Run과 같은 기능, Thread로 동작*/

public Void doInBackground(Void[] params) {

for(int i=0;i<100;i++) {

/** Handler 호출*/

publishProgress(i);

try {

Thread.sleep(500);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

return null;

};

protected void onPostExecute(Void result) {

};

/** Handler 전용*/

// Integer ... 은 가변 배여릉ㄹ 의미함

protected void onProgressUpdate(Integer ... values) {

txt.setText(values[0]+"");

}

;

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_async_task);

btn1 = (Button)findViewById(R.id.btn1);

btn2 = (Button)findViewById(R.id.btn2);

txt = (TextView)findViewById(R.id.txt);

btn1.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Toast.makeText(AsyncTaskActivity.this,"Hello",Toast.LENGTH_LONG).show();

}

});

btn2.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

MyTask task = new MyTask();

task.execute();

}

});

}

}


똑같이 잘 동작 됩니다.




Comments