2014년 2월 28일 금요일

Phonegap 3을 Eclips로 사용하는 방법

Phonegap 3 버전부터는 설치 부터가 쉽지않다. Phonegap 파일을 다운로드 받는게 아니라 node.js을 이용해서 command-line으로 다운로드 받게되어 있다. 이번 글에서는 Phonegap 3.x 버전을 설치하고 Eclipse에서 개발하는 방법을 적어보겠다.

Step 1. node.js 설치
http://nodejs.org/” 에서 node.js을 설치 한다. 설치중에 환경 Path을 추가할 것인지 물어보는데 꼭 추가해줘야한다.

Step 2. Andorid SDK Path 추가
sdk\platform-tools와 sdk\tools 디렉토리가 Path에 꼭 추가되어 있어야 한다. 안되어 있으면 나중에 에러가 쫙~

Step 3. Cordova(Phonegap) install
“npm install -g cordova” ← 설치를 시작한다. Maven 처럼 명령어를 실행할 때 그에 필요한 파일을 그때 그때 받아오는 것 같다. 설치되는 위치는 “C:\Users\username\AppData\Roaming\np”로 숨겨져 있는 폴더이다. npm에는 여러 명령어가 있는데 나중에 update 명령어도 cordova 최신버전으로 갱신할수 있다.

Step 4. 프로젝트 생성
기존 버전과 다르게 먼저 프로젝트를 만들고 다음에 지원할 Platform을 등록하는 방식이다.
프로젝트를 생성할 디렉토리로 이동한다.

hello 프로젝트에 MainActivity는 HelloWorld을 생성한다.
cordova create hello com.example.hello HelloWorld



cd hello

개발 플렛폼을 추가.
$ cordova platform add wp7
$ cordova platform add wp8
$ cordova platform add windows8
$ cordova platform add amazon-fireos
$ cordova platform add android
$ cordova platform add blackberry10
$ cordova platform add firefoxos






Step 4. Command-line Build
“cordova build” 또는  “cordova build android”



Step 5. Run
cordova emulate android
cordova run android




이제부터 Eclipse에 프로젝트를 만들어 본다.
Step 6. Eclipse의 Android Project을 만든다.



Step 7. Import
Command-line에서 생성한 hello 프로젝트을 Root로 지정하고 하위의 2개 프로젝트를 import한다. 기존까지 jar. js로 배포되던 cordova 라이브러리가 각 프로젝트별로 Android library project로 제공된다. 실제 jar.js 파일을 찾고 싶다면 bin 밑의 “dexedLibs” 밑에 jar가 있고 js는 apk 파일을 만들어 내부의 “assets/www”에 있는걸 확인할수 있다.

아직 Phonegap 3 버전을 써보진 안았다. 많은 변화가 있듯 기존보다 더 좋아져 있길 바란다.

2014년 2월 27일 목요일

Android NetworkOnMainThreadException

Android 메인 Thread에서 라이프사이클과 다양한 Callback을 처리하다 보니 시간이 오래걸리는 작업을 하게 되면 응답속도가 느려져 사용자가 불편해 한다. 그래서 Honeycomb 버전 부터 어플리케이션 응답속도을 보장하기 위해 많은 메인 Thread내에서 시간이 오래걸리는 네트워크 작업이나 UI을 핸들링 하지 못하게 하였다. "NetworkOnMainThreadException"은 메인 Thread내에서 네트워크 작업을 진행하려할때 발생한다.
그러면 어떻게 해결하나? 해결 방법은 2가지가 있는데 AsyncTask을 이용하는 방법과 StrictMode을 활용한 방식이 있다.

AsyncTask 사용 예
너무들 잘 알려진 AsyncTask입니다.
public class AsyncTaskMainActivity extends Activity {
private Button bStartTask = null;
private Button bInitState = null;
private TextView tStateView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.async_task_main);
bInitState = (Button)findViewById(R.id.bInit);
bStartTask = (Button)findViewById(R.id.bTask);
tStateView = (TextView)findViewById(R.id.tState);
bStartTask.setOnClickListener(new TaskOnClickListener());
bInitState.setOnClickListener(new TaskOnClickListener());
}

public class TaskOnClickListener implements android.view.View.OnClickListener {

public void onClick(View v) {
if (v.getId() == R.id.bInit) {
} else if (v.getId() == R.id.bTask) {
new BackTask().execute(tStateView);
}
}
}
public class BackTask extends AsyncTask<TextView, String, String> {
TextView tState = null;
@Override
protected void onProgressUpdate(String... values) {
tState.setText(values[0]);
}

@Override
protected String doInBackground(TextView... args) {
tState = args[0];
try {
publishProgress("기다리고 있습니다.");
Thread.sleep(3000);
} catch (InterruptedException e) {
publishProgress(e.getMessage());
}
return "Task 완료";
}

@Override
protected void onPostExecute(String result) {
tState.setText(result);
}

}
}

AsyncTask의 odInBackgroud내에서는 직접적으로 UI을 핸들링 할 수 없습니다. 처리중에 UI을 변경하려면 onProgressUpdate을 사용하고 완료후에는 onPostExecute을 사용하면됩니다.
예제를 네트워크 관련해서 만들려고 했는데 코드가 길어져서 UI로 했습니다. 중요한것은 개념이니깐요!

StrictMode 사용 예
이 방법은 허니컴 이상의 버전에서의 Thread정책을 모두 기존처럼 사용하겠다고 선언하는 방식으로 권장하지 않습니다.

Activity의 onCreate에 다음 코드를 넣습니다.
if(android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}


2014년 2월 25일 화요일

JMX-Communication with Notifications

Components of the JMX notification model
MBean events are wrapped as notification objects and broadcast from MBeans. Notification listeners, like event listeners, register with MBeans in order to receive notifications, including user-deined notifications.

Component
Descripton

Notification broadcaster
An object that implements the javax.management.NotificationBroadcaster interface, allowing it to send notifications.

Notification
An object emitted from broadcaters that contain information for a listener.

Notificatioin listener
An object that implements the javax.management.NotificationListener interface, allowing it to receive notifiacaitons.

Notification filter
An obejct associated with a listener that can filter notifications, allowing only the desired notifications to be delivered to a listener.


The Notification class
The Notification class extends java.util.EventObject and is used as a super class for other notification classes.
The Notification class contains six member variables that are all accessible through getter methods.
The Notification class has several different constructors, each providing a different set of initializaation arguments for these class members.

Class member
Purpose
Message
A String object representing a message. This could be the reason for the notification.
SequenceNumber
A number indicating the order in relation of events from the source. The source populates this field if it intends to give listeners the ability to sort incoming notifications. The notification model makes no guaranties that notifications will be received in the order they were sent.
TimeStamp
The timestamp of the notification, represented as a long value.
Type
The dot-separated String value indicating the type of the notification. Not a class type. Fore example:acme.mbeanA.event1.
UserData
An object used to contain any data that a source wants to send to a notification listener.
Source
The source of the notification. This object contains an ObjectName or a reference to the object that generated the notification.



package com.daddycat.blog.jmx;

public interface HelloMBean {
public void setMessage(String message); → message 설정

public String getMessage();

public void sayingHello(); → 설정된 message로 Notification을 1초마다 발생한다.
public void shutup(); → Notification 중지
}



package com.daddycat.blog.jmx;

import javax.management.AttributeChangeNotification;
import javax.management.MBeanNotificationInfo;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;

public class Hello extends NotificationBroadcasterSupport implements HelloMBean, Runnable {
private String message = null;
private boolean stop = true;
private int sayCount = 0;
public Hello() {
message = "Hello, world";
}

public Hello(String message) {
this.message = message;
}


public void setMessage(String message) {
String oldValue = this.message;
this.message = message;
//source, sequenceNumber, timeStamp, msg, attributeName, attributeType, oldValue, newValue
AttributeChangeNotification atrChangeNotification =
new AttributeChangeNotification(this, 0, System.currentTimeMillis(), "Hello Message Change", "message", "String", oldValue, message);
sendNotification(atrChangeNotification);

}


public String getMessage() {
return message;
}


public void sayingHello() {
stop = false;
Thread t = new Thread(this);
t.start();
}

public void shutup() {
stop = true;
}


public void run() {
while(!stop) {
try {
System.out.println("waiting...");
Thread.sleep(1000);
System.out.println("Saying...");
} catch (InterruptedException e) {
e.printStackTrace();
}
// Type, Source, sequenceNumber, TimeStamp, Message
Notification notification = new Notification("DaddyCat.JMX.Say.Counter", this, sayCount++, System.currentTimeMillis(), message+"("+sayCount+")");
sendNotification(notification);
}
}

@Override
public MBeanNotificationInfo[] getNotificationInfo() {
String[] type = {"DaddyCat.JMX.Say.Counter" };
MBeanNotificationInfo[] info = new MBeanNotificationInfo[ 2 ];
info[ 0 ] = new MBeanNotificationInfo( type, "javax.management.Notification", "The HelloMBean counter" );
String[] attChanges = {
AttributeChangeNotification.ATTRIBUTE_CHANGE };
info[ 1 ] = new MBeanNotificationInfo( attChanges, "javax.management.AttributeChangeNotification", "The HelloMBean counter" );
return info;
}
}
AttributeChangeNotification은 MBean의 Attribute가 변경되었을 때 사용된다.  해당 attributeName, attributeType, oldValue, newValue가 포함된다.



package com.daddycat.blog.jmx;

import java.lang.management.ManagementFactory;

import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;


public class NotificationAgent implements NotificationListener {
private MBeanServer mbs = null;

public NotificationAgent() {

// Get the platform MBeanServer
mbs = ManagementFactory.getPlatformMBeanServer();
// Unique identification of MBeans
Hello helloBean = new Hello();
ObjectName helloName = null;

try {
// Uniquely identify the MBeans and register them with the platform
// MBeanServer
helloName = new ObjectName("DADDYCAT:name=Communication_Notification");
mbs.registerMBean(helloBean, helloName);
helloBean.addNotificationListener(this, null, null); → 리스너 등록
} catch (Exception e) {
e.printStackTrace();
}
}

// Utility method: so that the application continues to run
private static void waitForEnterPressed() {
try {
System.out.println("Press  to continue...");
System.in.read();
} catch (Exception e) {
e.printStackTrace();
}
}

public static void main(String argv[]) {
NotificationAgent agent = new NotificationAgent();
System.out.println("Communication_Notification is running...");
NotificationAgent.waitForEnterPressed();
}

@Override
public void handleNotification(Notification notification, Object handback) {
System.out.println("Receiving notification....");
System.out.println(notification.getType());
System.out.println(notification.getMessage());
}
}


NtoficationAgent의 Operation의 sayingHello을 실행하면 Notification이 전달 된다.
물론 shutup을 실행하면 중지.



Attribute의 Message을 수정하면 AttributeChangeNotification이 발생한다.


블록체인 개요 및 오픈소스 동향

블록체인(block chain) 블록체인은 공공 거래장부이며 가상 화폐로 거래할때 발생할때 발생할 수 있는 해킹을 막는 기술. 분산 데이터베이스의 한 형태로, 지속적으로 성장하는 데이터 기록 리스트로서 분산 노드의 운영자에 의한 임의 조작이 불가...