Please Enable JavaScript!
Gon[ Enable JavaScript ]

안드로이드(Android) 백그라운드에서 Handler 를 통해 UI 변경

안드로이드 개발
반응형

안드로이드(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) 백그라운드에서 Handler 를 통해 UI 변경

 

반응형
Posted by 녹두장군1
,