관리 메뉴

드럼치는 프로그래머

[안드로이드] 제12강좌 - Thread 추가 본문

★─Programing/☆─Android

[안드로이드] 제12강좌 - Thread 추가

드럼치는한동이 2011. 6. 1. 15:37

# Class - 함수나 메소드의 집합체  => extends 가 필요함

# Interface - 함수나 메소드 선언 (껍데기일뿐..) => implement 가 필요

 

@@@ 스레드 만드는 법 @@@

-게임과 같은것은 상관 없지만, web이나 페이스북 트위터등을 이용하려면 꼭 알아두어야 함.

1. inner Class

   --- class xxx extends Activity{

       ---mBackValue

       ---mBackText

       ---onCreate(){

       }

     class yyy extends Thread{

        mHandle.sendEmptyMessage()

     }

}

 

2. extend Class

  --- class xxx extends Activity{

      ---mBackText

      ---onCreate(){

       }

}

class yyy extends Thread{

   ---mBackValue

   ---mHandler 

  ㅁ = new Message()

  ㅁ.waht

  ㅁ.arg1    

     mHandle.sendEmptyMessage()

     }

}

첫번째 방법

- 땡땡이 침. 잘 모름

  새로운이름 extends.thread

          run(){

      }

@@@ java @@@

package com.android.thread;

import android.app.Activity;
import android.os.Bundle;
import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;

 

public class AndroidThread extends Activity {
 int mMainValue =0;
 int mBackValue =0;
 TextView mMainText;
 TextView mBackText;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       

    class BackThread extends Thread{   //Thread의 기본 구조로 onCreate()아래에 사용. 필요할때 가져다 사용. Thread와 extends 사용
         public void run(){                          //run 메소드
          while(true){
           mBackValue++;
           try{
            Thread.sleep(1000);
           }catch(InterruptedException e){
            ;
           }
          }
         }
        }
        //변수에 main쪽 아이들 데리고 옴.
        mMainText=(TextView)findViewById(R.id.text01);
        mBackText=(TextView)findViewById(R.id.text02);
        Button btn=(Button)findViewById(R.id.button);
       
        //버튼을 클릭했을때 리스너구현
        btn.setOnClickListener(new Button.OnClickListener(){
         public void onClick(View v){
          mMainValue++;
          mMainText.setText("MainValue:"+mMainValue);
          mBackText.setText("BackValue:"+mBackValue);
         }
        });
        BackThread Thread = new BackThread();
        thread.setDaemon(true);
        thread.start();
    }
}

@@@ xml @@@

 

===========================================================================================================================================

두번재 방법

- onCreate 에서 BackRunnabl 타입의 runnable 객체를 생성한 후, Thread 클래스의 생성자로 전달.

  스레드의 start 메서드는 Runnable 객체의 run 메서드르 ㄹ호출하여 스레드를 기동.

차이점: run 메서드가 Thread 객체에 있는가, Runnable 구현 객체에 있는가의 차이.

 

# 자바에서는 다중 상속이 허용하지 않기 때문에 쓰레드를 사용

-기존의 클래스를 이용하여 새로운 클래스를 생성하는 방법

새로운 클래스 extends 기존 클래스

onCreate(){

XXXX= new TestRunnable()

새로운 클래스 = new Thread(XXXX)

새로운 클래스.start()

}

class TestRunnable inplement Runnable{

  run(){

  }

}

@@@ java @@@

package com.android.thread;

import android.app.Activity;
import android.os.Bundle;
import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;

 

public class AndroidThread extends Activity {
 int mMainValue =0;
 int mBackValue =0;
 TextView mMainText;
 TextView mBackText;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        class BackRunnable implements Runnable{    //Thread 두번째 방법으로 Runnable객체와 implement를 사용
         public void run(){
          while(true){
           mBackValue++;
           try{
            Thread.sleep(1000);
           }catch(InterruptedException e){
            ;
           }
          }
         }
        }
        //변수에 main쪽 아이들 데리고 옴.
        mMainText=(TextView)findViewById(R.id.text01);
        mBackText=(TextView)findViewById(R.id.text02);
        Button btn=(Button)findViewById(R.id.button);
       
        //버튼을 클릭했을때 리스너구현
        btn.setOnClickListener(new Button.OnClickListener(){
         public void onClick(View v){
          mMainValue++;
          mMainText.setText("MainValue:"+mMainValue);
          mBackText.setText("BackValue:"+mBackValue);
         }
        });
        BackRunnable runnable = new BackRunnable();
        Thread thread = new Thread(runnable);
        thread.setDaemon(true);
        thread.start();
    }
}

@@@ xml @@@

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    />
    <TextView
     android:id="@+id/text01" 
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:text="textView01"
    />
    <TextView
     android:id="@+id/text02" 
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:text="textView02"
    />
    <Button
     android:id="@+id/button"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:text="Button" />
</LinearLayout>
============================================================================================================================================

@@@ 핸들러 @@@

- 핸들러를 한곳에 선언해두고, Thread에서 핸들러롤 이용하여 호출

 

# 방법 1

- 메시지를 통해 어떤 작업을 하라는 지시사항을 보냄

XXX = new Handler(){

   --- handleMessage(Msg){

            처리내용

}

//Thread 쪽

XXX.sendEmptyMessage(Msg)

 

# 방법 2

- 차이점 : 1번은 핸들러를 이용하여 메세지를 전송하고, 2번은 Runnable객체를 생성한 후 post 메서드를 보낸다.

- Runnable 객체를 이용하여 작업 처리

xxx = new Handler(){

}

Thread쪽

xxx.post(new Runnable(){

    run(){

     처리내용

   }

});

@@@ java @@@

class BackThread extends Thread{
  public void run(){
  while(true){
   mBackValue++;
   mHandler.post(new Runnable(){

       public void run(){

           mBackText.setText("BackValue:" + mBackValue);

      }

   });

   try{Thread.sleep(1000);}catch(InterruptedException e){;}
    }
  }

 }

  Handler mHandler = new Handler();

}

============================================================================================================================================

세번째 방법

# 외부스레드 - Activity 안에 있던 Thread를 밖의 class 로 빼내어 생성 함

 

package com.android.thread;

import android.app.Activity;
import android.os.Bundle;
import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;

public class AndroidThread extends Activity {
 int mMainValue =0;
 TextView mMainText;
 TextView mBackText;
 BackThread mThread;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        //변수에 main쪽 아이들 데리고 옴.
        mMainText=(TextView)findViewById(R.id.text01);
        mBackText=(TextView)findViewById(R.id.text02);
        Button btn=(Button)findViewById(R.id.button);
       
        //버튼을 클릭했을때 리스너구현
        btn.setOnClickListener(new Button.OnClickListener(){
         public void onClick(View v){
          mMainValue++;
          mMainText.setText("MainValue:"+mMainValue);
         
         }
        });
       // BackRunnable runnable = new BackRunnable(mHandler);
        Thread thread = new BackThread(mHandler);
        thread.setDaemon(true);
        thread.start();
    }
    Handler mHandler = new Handler(){
     public void handleMessage(Message msg){ <======
      if(msg.what ==0){
       mBackText.setText("BackTextValue : "+msg.arg1);  //전달하려는 메세지가 하나면 arg1 , 2개면 arg2까지, 더 많으면 object 사용 
      }
     }
    };
}
class BackThread extends Thread{ //Thread를 외부로 뺌
 int mBackValue = 0;
 Handler mHandler;
 BackThread(Handler handler){ //Thread에서 handler의 값을 받음
  mHandler = handler;
 }
 public void run(){
  while(true){
   mBackValue++;   //클릭시 마다 값 증가
   Message msg = new Message(); //message타입  msg변수 생성
   msg.what=0;            //msg의 what은  0,  작업지시
   msg.arg1=mBackValue;   //msg의 arg1은 mBackValue의 값

   //Message msg = Message.obtain(mHandler,0,mBackValue,0); 메세지를 캐쉬에 위치시켜서 속도를 향상시킬수 있다.
   mHandler.sendMessage(msg);  //핸들러에 작업지시와 msg를 담아서 보냄->empty가 아님   =>이 값이 위의 핸들러의 분홍색으로 감
   try{Thread.sleep(1000);}catch(InterruptedException e){;}
   
   }
 }
}

============================================================================================================================================

@@@ 루퍼 @@@

- 메세지 큐 : 전달되는 메세지를 차곡차곡 샇아 놓는 곳(메세지 풀과 비슷한 의미)

- 루퍼 클래스 : 큐에서 메세지를 꺼내어 핸들러로 전달하는 역할을 함.

                    메세지 루프를 통해서 메세지가 들어오는지 감시, 들어온 메세지를 처리할 핸들러를 찾아 handleMessage 메서드를 호출한다.

============================================================================================================================================

@@@ 스레드와 루퍼를 구하는 메서드 @@@

-Thread getThread() : 루퍼와 연결된 스레드를 구한다.

                                  루퍼는 반드시 하나의 스레드와 연관되어 리턴됨

-static Looper getMainLooper() : 응용프로그램의 주 스레드의 루퍼를 구함

             "          myLooper()  :  현재 스레드의 루퍼를 구함

 

@@@ java @@@

package com.android.loop;

import android.app.Activity;
import android.os.Bundle;
import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;

public class Androidloop extends Activity {
    /** Called when the activity is first created. */
 int mMainValue = 0;
 TextView mMainText;
 TextView mBackText;
 EditText mNumEdit;
 CalcThread mThread;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mMainText=(TextView)findViewById(R.id.text01);
        mBackText=(TextView)findViewById(R.id.text02);
        mNumEdit=(EditText)findViewById(R.id.edit);
        Button btn=(Button)findViewById(R.id.increase);
        btn.setOnClickListener(new Button.OnClickListener(){
         public void onClick(View v){
          mMainValue++;
          mMainText.setText("MainValue :"+mMainValue);
         }
        });
        btn=(Button)findViewById(R.id.Square);
        btn.setOnClickListener(new Button.OnClickListener(){
         public void onClick(View v){
          Message msg = Message.obtain();
          msg.what=0;
          msg.arg1=Integer.parseInt(mNumEdit.getText().toString());
          mThread.mBackHandler.sendMessage(msg);
         }
        });
        btn=(Button)findViewById(R.id.root);
        btn.setOnClickListener(new Button.OnClickListener(){
         public void onClick(View v){
          Message msg = Message.obtain();
          msg.what=1;
          msg.arg1=Integer.parseInt(mNumEdit.getText().toString());
          mThread.mBackHandler.sendMessage(msg);
         }
        });
        mThread = new CalcThread(mHandler);
        mThread.setDaemon(true);
        mThread.start();
    }
    Handler mHandler = new Handler(){  //UI의 값이 넘어옴
  public void handleMessage(Message msg){
   switch(msg.what){
   case 0:
    mBackText.setText("Square Result : "+msg.arg1);
    break;
   case 1:
    mBackText.setText("Root Result : "+((Double)msg.obj).doubleValue()); //2배된 값의 obj값은 다시 형변환
   }
  }
 };
}
class CalcThread extends Thread{
 Handler mMainHandler;
 CalcThread(Handler handler){
  mMainHandler = handler;
 }
 public void run(){
  Looper.prepare();   //내가 직접 제작한 것이라서 looper를 선언해줘야 함. UI쪽엔 되어있음.
  Looper.loop();
 }
 public Handler mBackHandler = new Handler(){

  public void handleMessage(Message msg){
   Message retmsg = Message.obtain();
   switch(msg.what){           
   case 0:
    try{
     Thread.sleep(100);
    }catch(InterruptedException e){
     ;
    }
    retmsg.what=0;
    retmsg.arg1=msg.arg1*msg.arg1;
    break;
   case 1:
    try{
     Thread.sleep(100);
    }catch(InterruptedException e){
     ;
    }
    retmsg.what=1;
    retmsg.obj=new Double(Math.sqrt((double)msg.arg1));
    break;
   }
   mMainHandler.sendMessage(retmsg); //결과 값을 메인쪽으로 넘겨준다.
  }
 };
}

@@@ xml @@@

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    />
    <TextView 
    android:id="@+id/text01"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="textView01"
    />
    <TextView 
    android:id="@+id/text02"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="textView02"
    />
    <EditText
     android:id="@+id/edit"
     android:layout_width="fill_parent"
        android:layout_height="wrap_content"
     />
    <Button
     android:id="@+id/increase"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="increase" />
     <Button
     android:id="@+id/Square"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="square" />
     <Button
     android:id="@+id/root"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="root" />
   
</LinearLayout>




 
Comments