아주 아주 오래전 간단한 서비스를 하는 어플을 하나 만들었는데, 어플이 웹과 연동도 되어야 하고, 주기적으로 정보도 갱신을 해야되는데 어플에서는 네트워크 비용이 최대한 들어가지 않도록 설계를 해야 했었다.


그래서 고민하고 고안한 방법이, 서비스를 제공하는 어플은 단지 별도로 제작한 웹에서 정보를 읽어만 오고, 해당 웹에 정보를 채워넣기 위해서 웹앱을 하나 만들어서 주기적으로 어플에서 로딩만 하게 하면, 모든 처리는 서버내에서 이루어지게 되므로, 스마트폰에서는 별도의 추가적인 네트워크가 많이 발생하지 않게 되었다.


일단 주기적으로 특정한 웹페이지를 계속해서 로딩하는 방법은 여러가지가 있지만 아주 간단하게, 서비스 하나와 타이머로 스마트폰이 켜져있고 네트워크가 연결되어있는한 계속해서 실행할수 있다.


코드는 아래와 같이 아주 간단하게 만들어주면 된다.



public class Scheduler extends Service {
	private String TAG = "Scheduler";
	private static final String url = "[웹페이지주소]";
	private static final long delta = 30 * 60 * 1000; // 30분마다 한번

	@Override
	public void onCreate() {
		

	}

	@Override
	public int onStartCommand(final Intent intent, int flags, int startId) {
		super.onStartCommand(intent, flags, startId);

		start();
		return START_STICKY;  // 이 서비스는 불멸이다.

	}

	private void start() {

		Timer timer = new Timer();
		
		timer.schedule(new TimerTask() {
			public void run() {
				URL obj;
				try {
					obj = new URL(url);
					HttpURLConnection conn = (HttpURLConnection) obj.openConnection();

					BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
					String inputLine;

					while ((inputLine = in.readLine()) != null) {
						Log.v(TAG, inputLine);
					}
					in.close();
				} catch (MalformedURLException e) {					
					e.printStackTrace();
				} catch (IOException e) {					
					e.printStackTrace();
				}
			}
		}, 0, delta);
	}

	@Override
	public IBinder onBind(Intent arg0) {		
		return null;
	}
}
블로그 이미지

rekun,ekun 커뉴

이 세상에서 꿈 이상으로 확실한 것을, 인간은 가지고 있는 것일까?

언제 부터인가 우분투에서는 openJDK가 기본으로 설치되고, /usr/bin/java도 기본으로 openJDK를 사용하도록 되어 있다.


Oracle에서 제공하는 Sun JDK를 설치하고 나서 기본 설정을 바꿔주기 위해서는 아래와 같이 하면 끝난다.(패스를 설정해줄수도 있지만)


/usr/local/java-6-sun 에 Sun JDK를 설치했다고 가정함.


nuke@ubuntu:~$ sudo update-alternatives --install "/usr/bin/java" "java" "/usr/local/java-6-sun/bin/java" 1


nnuke@ubuntu:~$ sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/local/java-6-sun/bin/javac" 1

update-alternatives: using /usr/local/java-6-sun/bin/javac to provide /usr/bin/javac (javac) in auto mode.


nuke@ubuntu:~$ sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/local/java-6-sun/bin/javaws" 1

update-alternatives: using /usr/local/java-6-sun/bin/javaws to provide /usr/bin/javaws (javaws) in auto mode.


nuke@ubuntu:~$ sudo update-alternatives --config java

There are 2 choices for the alternative java (providing /usr/bin/java).


  Selection    Path                                           Priority   Status

------------------------------------------------------------

* 0            /usr/lib/jvm/java-6-openjdk-i386/jre/bin/java   1061      auto mode

  1            /usr/lib/jvm/java-6-openjdk-i386/jre/bin/java   1061      manual mode

  2            /usr/local/java-6-sun/bin/java                         1         manual mode


Press enter to keep the current choice[*], or type selection number: 2

update-alternatives: using /usr/local/java-6-sun/bin/java to provide /usr/bin/java (java) in manual mode.


nuke@ubuntu:~$ java -version

java version "1.6.0_37"

Java(TM) SE Runtime Environment (build 1.6.0_37-b06)

Java HotSpot(TM) Client VM (build 20.12-b01, mixed mode, sharing)


이전에는 패스를 설정해서 oracle java가 먼저 실행되도록 했었지만, 기왕이면 설정을 등록하고 디폴트 설정을 선택할수 있으니 앞으로는 이와 같은 방법을 사용하여 더 편하게 사용하면 된다.

블로그 이미지

rekun,ekun 커뉴

이 세상에서 꿈 이상으로 확실한 것을, 인간은 가지고 있는 것일까?

Honey Comb(Android 3)부터 Fragment라는 것이 들어왔는데, 그동안 프로바이더나 네트워크 Sync쪽으로만 너무 일이 몰려있던 바람에 Fragment를 이것 저것 많이 다루지 못했던것 같다.


그래서 정말 진짜,, 기초적으로!!! 나중에 참고할일이 있을때 바로 샘플로 사용하기 위해서 간단하 Activity 하나에 Fragment를 두개를 붙이는 예제를 만들었다.

아무런 내용도 없는 진짜 껍데기만 존재하는 코드라서, 나중에 필요한 부분을 붙여넣을 일이 생길때만 사용하면 된다.





너무 휑~~ 하다. 소스도 역시 내용이 없다, 필요할때 채워서 써야 한다. 


1. Main Layout

<?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" >
    <fragment
        android:id="@+id/fragment1"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        class="com.hopeisagoodthing.fragments.Fragment1" />
    <fragment
        android:id="@+id/fragment2"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        class="com.hopeisagoodthing.fragments.Fragment2" />
</LinearLayout>



2. Fragment1 layout

<?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" >
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/fragment1"
        tools:context=".MainActivity" />

</RelativeLayout>



3. Fragment2 layout

<?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" >
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/fragment2"
        tools:context=".MainActivity" />

</RelativeLayout>



4. MainActivity.java

package com.hopeisagoodthing.fragments;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}



5. Fragment1.java

package com.hopeisagoodthing.fragments;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


public class Fragment1 extends Fragment {

	@Override
	public View onCreateView(LayoutInflater inflater,
			ViewGroup container, Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.fragment1, container, false);	

		return v;
	}

}



6. Fragment2.java

package com.hopeisagoodthing.fragments;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment2 extends Fragment {

	@Override
	public View onCreateView(LayoutInflater inflater,
			ViewGroup container, Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.fragment2, container, false);		

		return v;
	}

}

블로그 이미지

rekun,ekun 커뉴

이 세상에서 꿈 이상으로 확실한 것을, 인간은 가지고 있는 것일까?

오늘은 심심해서 Android 4.x에 새로 추가된것들에 대해서 보고 있었는데, 그중에 재미난것이 하나 있어서 코딩해볼까?? 하고 eclipse를 열었다.


그런데, 코딩할필요가 없었다.





이유는 아예 AnalogClock view를 지원하고 있다. 좋다!!!! 아무것도 할것 없이 그냥 아래 view 만 추가해주면 모든게 끝난다.


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


    <AnalogClock xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/analog"

    android:layout_width="match_parent"

    android:layout_height="match_parent" >

    </AnalogClock>


</RelativeLayout>


블로그 이미지

rekun,ekun 커뉴

이 세상에서 꿈 이상으로 확실한 것을, 인간은 가지고 있는 것일까?

코드를 읽거나, 코드를 작성하거나 할때, 일단 라인수가 큰 코드, 데이터와 코드가 분리되어 있지 않은 코드들을 보면 나도 모르게 불안해진다. 


마음속 깊은곳에서 "고쳐야돼.. 제거해야해... 줄여야해!!" 하는 소리가 들리는것 같은 기분으로 불안한 상태로 코드를 제대로 작성하거나 읽을수가 없다.


포인터가 사용가능한 C언어류를 사용할때에도 Switch나 if를 많이 쓰게 되면 함수포인터로 테이블을 생성하여 사용하거나 했는데, 자바로 넘어오니 어랏??? 없다. 포인터 같은게...


그래서 interface 와 map을 사용하여 switch - case 들을 제거하여 코딩하고 있다.


제거하면 나중에 좋을까?? 


상황에 따라 다르지만, 일반적으로 코드량을 줄일수 있다. 물론 switch - case로 가장 컴팩트하게 코딩을 할수 있는 경우도 많지만, 보통 case에서 구분되어야 하는 경우의 수를 구분짓기 위해 일단 int 형 구분 값이 고정적으로 들어간다.( case [constant 값] : 이런식으로 코딩을 하니까 )

map에서는 그 구분하는 것을 array의 index를 사용하던, 특정한 키 object를 사용하여 구분짓던 무엇이든지 map을 만들수 있는 방법이면 다 사용가능하다. 그래서 case에 대한 정의를 따로 할 필요가 없다. 키만 구분할수 있게 애초에 입력을 받으면 된다.


그리고, case가 추가되거나 제거될때는 map부분만 수정하고 추가하면 된다, switch를 구분하는 곳에서는 더이상수정할 필요가 없어지게 된다. 

이로 인해 logic을 관리하는 클래스와 case들을 관리하는 class로 구분이 가능하게 된다. Map들만 따로 클래스로 생성해서 나눈다음에 상황에 맞는 Map을 logic으로 올려주도록 하면 switch case가 portable하게 만들어지는 것이다.


학부시절 C언어로 뭔가를 만들어오라는 과제를 할때는 Switch Case를 당연히 사용하곤했었는데, 계속 프로그래밍을 하다보니, if,switch,case등을 계속 추가하게 되는 코드들은 나를 너무 불안하게 만들었다. ㅠ.ㅠ


요즘에는 참여하는 프로젝트에서 누군가가 Switch -case를 쓰면 나도 모르게 ctrl - a , delete를 누르게 된다. @.@


예제 코드는 정말 이런식으로 코딩할리 없겠지만, 어떻게 interface로 case를 구분하는냐에 대한 예제정도로만 봐주면 좋을것 같다.



package com.hopeisagoodthing.removeswitch;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class Main {

	/**
	 * @param args
	 */
	private interface IMethod{
		void method();
	}
	
	private static Map<Integer,IMethod> methodArray= new HashMap<Integer,IMethod>();
	static{
		methodArray.put(1, new IMethod(){
			@Override
			public void method() {
				System.out.println("1");				
			}});
		
		methodArray.put(2, new IMethod(){
			@Override
			public void method() {
				System.out.println("2");				
			}});
		
		methodArray.put(3, new IMethod(){
			@Override
			public void method() {
				System.out.println("3");				
			}});
		
		methodArray.put(4, new IMethod(){
			@Override
			public void method() {
				System.out.println("4");				
			}});
		
		methodArray.put(5, new IMethod(){
			@Override
			public void method() {
				System.out.println("5");				
			}});
		
		methodArray.put(6, new IMethod(){
			@Override
			public void method() {
				System.out.println("6");				
			}});
		
		methodArray.put(7, new IMethod(){
			@Override
			public void method() {
				System.out.println("7");				
			}});
		
		methodArray.put(8, new IMethod(){
			@Override
			public void method() {
				System.out.println("8");				
			}});
		
		methodArray.put(9, new IMethod(){
			@Override
			public void method() {
				System.out.println("9");				
			}});
		
		methodArray.put(10, new IMethod(){
			@Override
			public void method() {
				System.out.println("10");				
			}});
		
		methodArray.put(11, new IMethod(){
			@Override
			public void method() {
				System.out.println("11");				
			}});
		
		methodArray.put(12, new IMethod(){
			@Override
			public void method() {
				System.out.println("12");				
			}});
		
		methodArray.put(13, new IMethod(){
			@Override
			public void method() {
				System.out.println("13");				
			}});
		
		methodArray.put(14, new IMethod(){
			@Override
			public void method() {
				System.out.println("14");				
			}});
		
		methodArray.put(15, new IMethod(){
			@Override
			public void method() {
				System.out.println("15");				
			}});
		
		methodArray.put(16, new IMethod(){
			@Override
			public void method() {
				System.out.println("16");				
			}});
		
		methodArray.put(17, new IMethod(){
			@Override
			public void method() {
				System.out.println("17");				
			}});
		
		methodArray.put(18, new IMethod(){
			@Override
			public void method() {
				System.out.println("18");				
			}});
		
		methodArray.put(19, new IMethod(){
			@Override
			public void method() {
				System.out.println("19");				
			}});
		
		methodArray.put(20, new IMethod(){
			@Override
			public void method() {
				System.out.println("20");				
			}});
		
		methodArray.put(21, new IMethod(){
			@Override
			public void method() {
				System.out.println("21");				
			}});
		
		methodArray.put(22, new IMethod(){
			@Override
			public void method() {
				System.out.println("22");				
			}});
		
		methodArray.put(23, new IMethod(){
			@Override
			public void method() {
				System.out.println("23");				
			}});
		
		methodArray.put(24, new IMethod(){
			@Override
			public void method() {
				System.out.println("24");				
			}});
		
		methodArray.put(25, new IMethod(){
			@Override
			public void method() {
				System.out.println("25");				
			}});
		
		methodArray.put(26, new IMethod(){
			@Override
			public void method() {
				System.out.println("26");				
			}});
		
		methodArray.put(27, new IMethod(){
			@Override
			public void method() {
				System.out.println("27");				
			}});
		
		methodArray.put(28, new IMethod(){
			@Override
			public void method() {
				System.out.println("28");				
			}});
		
		methodArray.put(29, new IMethod(){
			@Override
			public void method() {
				System.out.println("29");				
			}});
		
		methodArray.put(30, new IMethod(){
			@Override
			public void method() {
				System.out.println("30");				
			}});
		
		methodArray.put(31, new IMethod(){
			@Override
			public void method() {
				System.out.println("31");				
			}});
		
		methodArray.put(32, new IMethod(){
			@Override
			public void method() {
				System.out.println("32");				
			}});
		
		methodArray.put(33, new IMethod(){
			@Override
			public void method() {
				System.out.println("33");				
			}});
		
		methodArray.put(34, new IMethod(){
			@Override
			public void method() {
				System.out.println("34");				
			}});
		
		methodArray.put(35, new IMethod(){
			@Override
			public void method() {
				System.out.println("35");				
			}});
		
		methodArray.put(36, new IMethod(){
			@Override
			public void method() {
				System.out.println("36");				
			}});
		
		methodArray.put(37, new IMethod(){
			@Override
			public void method() {
				System.out.println("37");				
			}});
		
		methodArray.put(38, new IMethod(){
			@Override
			public void method() {
				System.out.println("38");				
			}});
		
		methodArray.put(39, new IMethod(){
			@Override
			public void method() {
				System.out.println("39");				
			}});
		
		methodArray.put(40, new IMethod(){
			@Override
			public void method() {
				System.out.println("40");				
			}});
	}
	
	private static void withoutSwitch(int inA)
	{
		inA = inA%40+1;				
		final IMethod method = methodArray.get(inA);
		if(method!=null){
			method.method();
		}
		else
		{
			System.out.println("nothing");
		}		
	}
	
	private static void useSwitch(int inA)
	{
		inA = inA%40+1;
		switch(inA)
		{
		case 1:
			System.out.println("1");
			break;
		case 2:
			System.out.println("2");
			break;
		case 3:
			System.out.println("3");
			break;
		case 4:
			System.out.println("4");
			break;
		case 5:
			System.out.println("5");
			break;
		case 6:
			System.out.println("6");
			break;
		case 7:
			System.out.println("7");
			break;
		case 8:
			System.out.println("8");
			break;
		case 9:
			System.out.println("9");
			break;
		case 10:
			System.out.println("10");
			break;
		case 11:
			System.out.println("11");
			break;
		case 12:
			System.out.println("12");
			break;
		case 13:
			System.out.println("13");
			break;
		case 14:
			System.out.println("14");
			break;
		case 15:
			System.out.println("15");
			break;
		case 16:
			System.out.println("16");
			break;
		case 17:
			System.out.println("17");
			break;
		case 18:
			System.out.println("18");
			break;
		case 19:
			System.out.println("19");
			break;
		case 20:
			System.out.println("20");
			break;
		case 21:
			System.out.println("21");
			break;
		case 22:
			System.out.println("22");
			break;
		case 23:
			System.out.println("23");
			break;
		case 24:
			System.out.println("24");
			break;
		case 25:
			System.out.println("25");
			break;
		case 26:
			System.out.println("26");
			break;
		case 27:
			System.out.println("27");
			break;
		case 28:
			System.out.println("28");
			break;
		case 29:
			System.out.println("29");
			break;
		case 30:
			System.out.println("30");
			break;
		case 31:
			System.out.println("31");
			break;
		case 32:
			System.out.println("32");
			break;
		case 33:
			System.out.println("33");
			break;
		case 34:
			System.out.println("34");
			break;
		case 35:
			System.out.println("35");
			break;
		case 36:
			System.out.println("36");
			break;
		case 37:
			System.out.println("37");
			break;
		case 38:
			System.out.println("38");
			break;
		case 39:
			System.out.println("39");
			break;
		case 40:
			System.out.println("40");
			break;
			
		default:
			System.out.println("nothing");
			break;			
		}
		
	}
	private static final int TOTAL_TRIAL = 20;
	private static final int MAX_LOOP = 20000;
	public static void main(String[] args) {		
		Random urandom = new Random();
		int[] inputs = new int[MAX_LOOP];		
		int[] useSwitchResult = new int[TOTAL_TRIAL];
		int[] withoutSwitchResult = new int[TOTAL_TRIAL];
		
		for(int i=0;i<MAX_LOOP;i++){
			inputs[i] = urandom.nextInt();
		}
		
		
		for(int trial=0;trial<TOTAL_TRIAL;trial++)
		{
			System.gc();
			long start = System.currentTimeMillis();
			for(int a=0;a<500*trial;a++){						
				useSwitch(inputs[a]);
			}
			useSwitchResult[trial] = (int) (System.currentTimeMillis()-start);			
		}
		
				
		for(int trial=0;trial<TOTAL_TRIAL;trial++)
		{		
			System.gc();
			long start = System.currentTimeMillis();		
			for(int a=0;a<500*trial;a++){			
				withoutSwitch(inputs[a]);
			}
			withoutSwitchResult[trial] = (int) (System.currentTimeMillis()-start);
		}
		System.out.println("useSwitch :" );
		for(int trial=0;trial<TOTAL_TRIAL;trial++)
		{
			System.out.print(useSwitchResult[trial]+"\t");
		}
		
		System.out.println("\nwithoutSwitch :" );
		for(int trial=0;trial<TOTAL_TRIAL;trial++)
		{
			System.out.print(withoutSwitchResult[trial]+"\t");
		}				
	}
}



'코딩하고 > Java' 카테고리의 다른 글

Java에서 Switch-Case 사용하면 불안해져서 .....  (2) 2012.11.14
블로그 이미지

rekun,ekun 커뉴

이 세상에서 꿈 이상으로 확실한 것을, 인간은 가지고 있는 것일까?