|
안드로이드(Android) 백그라운드에서 Handler 를 통해 UI 변경 |
|
환경 : Eclipse Mars, Android 4.2.2 |
이번 예제는 백그라운드에서 Thread 가 돌아가며 특정한 일을 할수 있도록 만든 샘플입니다. 스레드가 주기적으로 돌아가면서 화면에 TextView 값을 바꿔가는 것이죠. 화면의 메인 스레드로 데이터를 주는 것은 Handler 객체가 담당하고 있습니다.
▼ 먼저 메시지를 주고 받을 Handler 클래스를 하나 만듭니다. 이 클래스의 역할은 스레드에서 전달받은 메시지를 메인 activiy 로 넘겨주는 역할을 합니다. 메인 activity 에서는 이것을 받아 적절한 처리를 하면 되는데 예제에서는 Text 내용을 바꾸는 기능을 하겠죠.
// 핸들러 객체 만들기
private static class MyHandler extends Handler {
private final WeakReference<BackgroundThreadActivity> mActivity;
public MyHandler(BackgroundThreadActivity activity) {
mActivity = new WeakReference<BackgroundThreadActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
BackgroundThreadActivity activity = mActivity.get();
if (activity != null) {
activity.handleMessage(msg);
}
}
}
▼ 핸들에서 호출한 메인 activity 의 handleMessage() 함수 내용입니다. 이곳에서 TextView 를 숨기거나 보여주는 기능을 합니다.
// Handler 에서 호출하는 함수
private void handleMessage(Message msg) {
if (myTextOn) {
myTextOn = false;
myText.setVisibility(View.GONE);
} else {
myTextOn = true;
myText.setVisibility(View.VISIBLE);
}
}
▼ 이번에는 스레드 클래스 입니다. 일정하게 반복되면서 Handler 에 메시지를 보내는 역할을 하게 되는 것이죠. 소스에서는 1초에 한번씩 보내도록 sleep 을 주었습니다.
public class BackgroundThread extends Thread {
boolean running = false;
void setRunning(boolean b) {
running = b;
}
@Override
public void run() {
while (running) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mHandler.sendMessage(mHandler.obtainMessage());
}
}
}
▼ 메인 activity 에서는 스레드를 시작하고 종료하는 코드를 구현하기 위해 onStart(), onStop() 함수를 오버라이드 해서 구현하였습니다.
@Override
protected void onStart() {
super.onStart();
backgroundThread = new BackgroundThread();
backgroundThread.setRunning(true);
backgroundThread.start();
Toast.makeText(this, "onStart()", Toast.LENGTH_LONG).show();
}
@Override
protected void onStop() {
super.onStop();
boolean retry = true;
backgroundThread.setRunning(false);
while (retry) {
try {
backgroundThread.join();
retry = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Toast.makeText(this, "onStop()", Toast.LENGTH_LONG).show();
}
▼ 메인 activity 의 전체 레이아웃 xml 입니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="#3F0099"
android:paddingBottom="@dimen/abc_action_bar_icon_vertical_padding"
android:paddingTop="@dimen/abc_action_bar_icon_vertical_padding"
android:text="백그라운드 1초에 한번씩 글을 숨기거나 보여주는 예제 "
android:textColor="#FFFFFF" />
<TextView
android:id="@+id/mytext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/abc_action_bar_icon_vertical_padding"
android:text="이글은 백그라운드 스레드에서 보여주거나 숨깁니다. " />
</LinearLayout>
▼ 메인 activity 의 전체 소스 입니다. Thread 클래스와 Handler 가 모두 포함되어 있습니다.
import java.lang.ref.WeakReference;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class BackgroundThreadActivity extends Activity {
BackgroundThread backgroundThread;
TextView myText;
private boolean myTextOn = true;
private final MyHandler mHandler = new MyHandler(this);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_background_thread);
myText = (TextView) findViewById(R.id.mytext);
Toast.makeText(this, "onCreate()", Toast.LENGTH_LONG).show();
}
// Handler 에서 호출하는 함수
private void handleMessage(Message msg) {
if (myTextOn) {
myTextOn = false;
myText.setVisibility(View.GONE);
} else {
myTextOn = true;
myText.setVisibility(View.VISIBLE);
}
}
@Override
protected void onStart() {
super.onStart();
backgroundThread = new BackgroundThread();
backgroundThread.setRunning(true);
backgroundThread.start();
Toast.makeText(this, "onStart()", Toast.LENGTH_LONG).show();
}
@Override
protected void onStop() {
super.onStop();
boolean retry = true;
backgroundThread.setRunning(false);
while (retry) {
try {
backgroundThread.join();
retry = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Toast.makeText(this, "onStop()", Toast.LENGTH_LONG).show();
}
public class BackgroundThread extends Thread {
boolean running = false;
void setRunning(boolean b) {
running = b;
}
@Override
public void run() {
while (running) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
mHandler.sendMessage(mHandler.obtainMessage());
}
}
}
// 핸들러 객체 만들기
private static class MyHandler extends Handler {
private final WeakReference<BackgroundThreadActivity> mActivity;
public MyHandler(BackgroundThreadActivity activity) {
mActivity = new WeakReference<BackgroundThreadActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
BackgroundThreadActivity activity = mActivity.get();
if (activity != null) {
activity.handleMessage(msg);
}
}
}
}
'안드로이드 개발' 카테고리의 다른 글
| 안드로이드(Android) Chronometer, OnChronometerTickListener 통해 시간알아오기 (2) | 2015.01.04 |
|---|---|
| 안드로이드(Android) 웹페이지에서 이미지 다운로드 구현 (0) | 2015.01.01 |
| 안드로이드(Android) ListActivity 를 이용해여 간단한 목록형 화면만들기 (0) | 2014.12.28 |
| 안드로이드(Android) 백그라운드 스레드 소스 Runnable 이용해 구현 (0) | 2014.12.26 |
| 안드로이드(Android) This Handler class should be static or leaks might occur 해결 (6) | 2014.12.21 |
| 안드로이드(Android) Android.graphics.Color 에서 제공하는 컬러보기 샘플구현 (0) | 2014.12.17 |
| 안드로이드(Android) Activity 의 라이프사이클(LifeCycle) 알아보기위한 예제 (0) | 2014.12.16 |
| 안드로이드(Android) SurfaceView 와 Thread 이용해 화면에서 움직이는 공구현 (0) | 2014.12.12 |
