노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

ToDo App by Flutter / 플루터로 만드는 '할일앱'



1. Flutter 프로젝트 생성하기


> flutter create flutter_todo




2. 생성된 lib/main.dart를 지우고, 새로운 내용으로 채우기(Material Design)



심플한 Material-style의 앱을 title bar와 body만을 갖고 있도록 고친다.



모든 것은 Widget이다. MaterialApp, Scaffold, AppBar


3. Stateless & Stateful 위젯



StatelessWidget는 동적으로 변경될 수가 없다. 하지만, 동적인 자식들을 가질 수 있다.

이것이 StatefulWidget이다.




4. State 변경 하기



5. User Interaction: Adding a todo item



6. User Interaction: Removing todo items



...


# 원문


https://medium.com/the-web-tub/making-a-todo-app-with-flutter-5c63dab88190




# Flutter 설치하기 ( Windows )


https://flutter.io/get-started/install/


블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


Android Studio (3.1)에서 발생한 이슈 


# 이슈


1. Android Studio Updates(IDE and Plugin) 실패


2. Android Studio 구성 정보의 Disk 사이즈 문제


- C:\ 드라이브 공간이 작은데, 차지하는 공간이 크다.




# 해결책

- \Android Studion\bin\idea.properites를 찾기

- config 폴더와 시스템 폴더 변경 하기




블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.
토렌트 다운로드중에 영화 시청

1. 준비물

- uTorrent 
- VLC media Player


2. 스트리밍 주소

- uTorrent에서 주소복사 하기
- VLC media Player에서 주소 열기


 


블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

케이뱅크 APP 다운로드 (해외에서)


APP을 설치를 해야 가입이 되지만, 해외에서 APP를 다운로드 할 수가 없는 경우가 있다.







1. APK Download 사이트 방문



https://apkpure.com/

https://apps.evozi.com/apk-downloader/


* 잘 찾아 주는 사이트는 해외별로 다른것으로 보임



2. 검색창에 패키지명을 입력 한다.


com.kbankwith.smartbank



3. 다운로드 


apk를 다운로드 후에 phone에 업로드하고 apk 설치를 한다.







* 다운로드 사이트별로 양호/불량으로 나누어 지는 경우가 있으므로, 잘 찾아 봐야 한다.




블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


How To Install Node.js on a CentOS 7 server


-node.js를 centos 7에 설치하는 방법


Introduction/소개

Node.js is a Javascript platform for server-side programming. It allows users to easily create networked applications that
require backend functionality. 
By using Javascript as both the client and server language, development can be fast and consistent.

Node.js는 서버쪽 프로그래밍을 위한 자바스크립트 플랫폼이다. 이것을 개발자에게 백엔드
기능을 갖춘 네트웍 처리를 하는 어플리케이션을 만들기 쉽게 해준다.
클라이언트와 서버 언어 양쪽을 자바스크립트를 사용하는 것은 개발은 빠르고 일관성있게 해 준다.

In this guide, we will show you a few different ways of getting Node.js installed on a CentOS 7 server so that you can get started.
Most users will want to use the EPEL installation instructions or the NVM installation steps.

이 가이드에서는, CentOS 7 서버에  Node.js를 얻는 몇가지 방안을 보여주고 시작할 수 있게 해 줄 것이다.
대부분의 사용자는 EPEL 설치 방식과 NVM 설치 절차를 사용하는 것을 원할 것 같다.

1. Install Node from Source / 소스를 통한 설치

 One way of acquiring Node.js is to obtain the source code and compile it yourself.
 To do so, you should grab the source code from the project's website. On the downloads page,
 right click on the "Source Code" link and click "Copy link address" or whatever similar option your browser gives you.


 >wget http://nodejs.org/dist/v0.10.30/node-v0.10.30.tar.gz
 >tar xzvf node-v* && cd node-v*
 >sudo yum install gcc gcc-c++
 >./configure
 >make
 >sudo make install
 >node --version

2. Install a Package from the Node Site / 패키지를 통한 설치
 Another option for installing Node.js on your server is to simply get the pre-built packages
 from the Node.js website and install them.

 cd ~  wget http://nodejs.org/dist/v0.10.30/node-v0.10.30-linux-x64.tar.gz

3. Install Node from the EPEL Repository/ EPEL저장소를 통한 설치
 

An alternative installation method uses the EPEL (Extra Packages for Enterprise Linux) repository
 that is available for CentOS and related distributions.

 >sudo yum install epel-release
 >sudo yum install nodejs
 >node --version
 v0.10.30

4. Install Node Using the Node Version Manager / NVM을 통한 설치
 

Another way of installing Node.js that is particularly flexible is through NVM, the Node version manager.
 This piece of software allows you to install and maintain many different independent versions of Node.js,
 and their associated Node packages, at the same time.

 >curl https://raw.githubusercontent.com/creationix/nvm/v0.13.1/install.sh
 >curl https://raw.githubusercontent.com/creationix/nvm/v0.13.1/install.sh | bash
 >nvm list-remote


Conclusion / 결론


 As you can see, there are quite a few different ways of getting Node.js up and running on your CentOS 7 server.
 ~

원문 : https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-a-centos-7-server

'Application, App > Node.js' 카테고리의 다른 글

Node.JS 웹 채팅 (간단한 예제)  (0) 2017.02.07
(1) 소개 - Node.js  (0) 2016.05.20
블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


Node.JS 웹 채팅 (간단한 예제)


소스 구성 : app.js ( package.json) , index.html ( java script )



1. package.json

{
  "_comment" : "0. setup package",
  "name":"chat",
  "version" : "0.0.1",
  "private": "true",
  "dependencies" : {
    "socket.io" : "1.4.2",
    "express" : "4.13.4"
  }
}


2.app.js

- require

// SOCKET.IO Setup
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http); //initialise after http server

- listen

// http.listen
http.listen(3000, function(err) {
    if ( err ) {
        console.log(err);
    } else {
        console.log('listening on *: 3000')
    }
} );

- get / send index.html

// app.get
app.get('/', function(req, res) {
    // index.html
    res.sendFile(__dirname + '/index.html');

});

3. edit index.html

<head>
    <!-- 4. definition form -->
    <style>
        #div-chat-display {
            height:350px;
            width:500px;
            overflow-x: hidden;
            overflow-y: auto;
        }
    </style>
</head> 
<body> 
    <!-- 4. definition form -->
    <h3>Just simple your webChat ( v 0.0.1,  @stanwix , 21-Apr-2016 ) </h3>
    <div id="container-id">
        <form id="form-input-userid">
            your ID :  <input size="15" id="input-userid"/>
            <input type="submit" value="Join"/>
        </form>
    </div>
    <div id="container-message" style="display: none;">
        <div id="div-chat-display"></div>
        <form id="form-send-message">
            <input size="35" id="input-message"/>
            <input type="submit" value="Send"/>
        </form>
    </div>
</body> 

4. include javascript

   <!-- 5. setup js script -->
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>

5. javascript for message handle

아래 소스를 참조


소스

https://github.com/sketchout/NodeJs_SocketIO_PartOne


'Application, App > Node.js' 카테고리의 다른 글

Node.js를 CentOS에 설치하는 방법들  (0) 2017.02.07
(1) 소개 - Node.js  (0) 2016.05.20
블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

OnTimer - SetTimer


작업1) 메시지를 등록한다.


WM_TIMER->OnTimer을 추가하면

void SetTimerTestDlg::OnTimer(UINT_PTR nIDEvent)
{
    CDialog::OnTimer(nIDEvent);
}

가 자동으로 생성이 된다.. 



작업 2) 그리고 두개의 함수를 만들어 준다.

void SetTimerTestDlg::OnStartTimer()
{

    //1은 ID, 1000는 시간(ms)
    SetTimer(1, 30*1000, 0);  // 30초에 한번 실행
}

void SetTimerTestDlg::OnStopTimer()
{

    // 타이머 종료 
    KillTimer(1);
}


*  추가 설명

// OnStartTimer()은 타이머 시작 이고
// OnStopTimer()은 타이머 중지 이다.

void SetTimerTestDlg::OnTimer(UINT_PTR nIDEvent)
{

    printf(" timer called \n");
    CDialog::OnTimer(nIDEvent);
}


라고 실행할 명령어( 테스트로 printf)를 입력하고 OnStartTimer를 실행하면
1초에 한 번씩 프린트를 실행하게 된다.

타이머 종료할때는 OnStopTimer()를 실행하면된다.


블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

C# Packet Class

바이트 버퍼링 전송 수신 send receive

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;

namespace LClient
{
    public partial class Packet
    {
        NetworkStream _stream;
        BinaryWriter _writer;

        byte[] _buffer;
        byte[] _data;

        public void setStream( NetworkStream stream )
        {
            _stream = stream;
            _writer = new BinaryWriter(_stream);
        }

        public void read()
        {
            byte[] blen = new byte[4];
            int read = _stream.Read(blen, 0, blen.Length);
            int ilen = BitConverter.ToInt32(blen,0);
            
            _data = new byte[ilen];
            _stream.Read(_data, 0, ilen);

        }
        public int readInt()
        {
            //보관
            byte[] t = new byte[_data.Length];
            Array.Copy(_data, 0, t, 0, _data.Length);

            byte[] idata = new byte[4];
            Array.Copy(_data, 0, idata, 0, idata.Length);

            _data = new byte[t.Length - idata.Length];
            Array.Copy(t, idata.Length, _data, 0, _data.Length);

            return BitConverter.ToInt32(idata, 0);
        }

        public String readUTF8()
        {
            //보관
            byte[] t = new byte[_data.Length];
            Array.Copy(_data, 0, t, 0, _data.Length);

            byte[] sl = new byte[2];
            Array.Copy(_data, 0, sl, 0, sl.Length );
            short slen = BitConverter.ToInt16(sl,0);

            byte[] sd = new byte[slen];
            Array.Copy(_data, 0, sd, 0, sd.Length);

            if ( t.Length < sl.Length+slen )
            {
                return null;
            }
            else 
            {
                _data = new byte[t.Length - (sl.Length + sd.Length)];

                Array.Copy(t,(sl.Length+sd.Length),
                            _data,0, _data.Length);

                return Encoding.UTF8.GetString(sd);
            }

        }

        public void WriteInt( int num )
        {
            if (_buffer == null)
            {
                _buffer = BitConverter.GetBytes(num);
            }
            else
            {

                byte[] b = BitConverter.GetBytes(num);

                byte[] t = new byte[_buffer.Length];
                Array.Copy(_buffer, 0, t, 0, _buffer.Length);

                _buffer = new byte[t.Length + b.Length];

                Array.Copy(t, 0, _buffer, 0, t.Length);
                Array.Copy(b, 0, _buffer, t.Length, b.Length);
            }

        }

        public void WriteUTF( String str )
        {
            if (_buffer == null)
            {
                byte[] b = Encoding.UTF8.GetBytes(str);
                byte[] a = BitConverter.GetBytes((short)b.Length);

                _buffer = new byte[a.Length + b.Length];

                Array.Copy(a, 0, _buffer, 0, a.Length);
                Array.Copy(b, 0, _buffer, a.Length, b.Length);
            }
            else
            {
                byte[] t = new byte[_buffer.Length];
                Array.Copy(_buffer, 0, t, 0, _buffer.Length);
                byte[] b = Encoding.UTF8.GetBytes(str);
                byte[] a = BitConverter.GetBytes((short)b.Length);

                _buffer = new byte[t.Length + a.Length + b.Length];

                Array.Copy(t, 0, _buffer, 0, t.Length);
                Array.Copy(a, 0, _buffer, t.Length, a.Length);
                Array.Copy(b, 0, _buffer, t.Length + a.Length, b.Length);

            }
                
        }

        public void Flush()
        {
            // size
            _writer.Write(_buffer.Length);

            // data
            _stream.Write(_buffer, 0, _buffer.Length);

            _stream.Flush();
        }

        public int getLength()
        {
            return _buffer.Length;
        }
        public byte[] getData()
        {
            return _data;
        }
    }
}


'Application, App > VC++' 카테고리의 다른 글

OnTimer - SetTimer  (0) 2016.12.15
Stack with std::list  (0) 2016.12.15
Effective C++ 목차  (0) 2016.12.15
IO Completion Port 작성하기 ( 2010.10.06 )  (0) 2016.12.15
블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

Stack with std::list

#pragma once

#include 
#include 

/*
	Size : Unlimited
	I/O : LIFO, FIFO
*/

template
class NLStack
{
public :
	enum OutType
	{
		LIFO = 0,
		FIFO = 1,
	};
private:
	NLStack()
	{
		Clear();
	}

public:
	NLStack(int out) : m_Out(out)
	{
		Clear();	
	}

	void Clear()
	{
		if ( m_Stack.empty() == false )
		{
			m_Stack.clear();
		}
	}
	int Count() 
	{
		return static_cast( m_Stack.size() ) ;
	}

	bool IsEmpty() 
	{
		return m_Stack.empty();
	}

	// store data 
	void Push( T data )
	{
		m_Stack.push_back( data );
	}
	// extract data
	bool Pop ( T*data )
	{
		if ( IsEmpty() )
			return false;

		switch( m_Out)
		{
		case FIFO:
			//FIFO
			memcpy( data, &m_Stack.front(), sizeof(T) );
			m_Stack.pop_front();
			break;
		case LIFO:
			//LIFO
			memcpy( data, &m_Stack.back(), sizeof(T) );
			m_Stack.pop_back();
			break;
		}
		return true;
	}
	void SetOutType( int out )
	{
		m_Out = out; 
	}

private:
	std::list 	m_Stack;
	int				m_Out;
};



블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


 Effective C++ 목차




목차

Chapter 1. C++에 왔으면 C++의 법을 따릅시다.
 항목 1. C++를 언어들의 연합체로 바라보는 안목은 필수
 항목 2. #define을 쓰려거든 const, enum, inline을 떠올리자.  - #define 컴파일 에러시 디버깅 어려움
 항목 3. 낌새만 보이면 const를 들이대 보자! - const 외부 변경 불가능
 항목 4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자.
 

 Chapter 2. 생성자, 소멸자 및 대입 연산자
 항목 5. C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자.
 항목 6. 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해 버리자.
 항목 7. 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자.
 항목 8. 예외가 소멸자를 떠나지 못하도록 붙들어 놓자.
 항목 9. 객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자.
 항목 10. 대입 연산자는 *this의 참조자를 반환하게 하자.
 항목 11. operator=에서는 자기대입에 대한 처리가 빠지지 않도록 하자.
 항목 12. 객체의 모든 부분을 빠짐없이 복사하자.
 

 Chapter 3. 자원 관리
 항목 13. 자원 관리에는 객체가 그만!
 항목 14. 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자.
 항목 15. 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자.
 항목 16. new 및 delete를 사용할 때는 형태를 반드시 맞추자.
 항목 17. new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자.
 

 Chapter 4. 설계 및 선언
 항목 18. 인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 하자.
 항목 19. 클래스 설계는 타입 설계와 똑같이 취급하자.
 항목 20. '값에 의한 전달'보다는 '상수객체 참조자에 의한 전달' 방식을 택하는 편이 대게 낫다.
 항목 21. 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자.
 항목 22. 데이터 멤버가 선언될 곳은 private 영역임을 명심하자.
 항목 23. 멤버 함수보다는 비멤버 비프렌드 함수와 더 가까워지자.
 항목 24. 타입 변환이 모든 매개변수에 대해 적용되어야 한다면 비멤버 함수를 선언하자.
 항목 25. 예외를 던지지 않는 swap에 대한 지원도 생각해보자.
 

 Chapter 5. 구현 
 항목 26. 변수 정의는 늦출 수 있는 데 까지 늦추는 근성을 발휘하자.
 항목 27. 캐스팅은 절약, 또 절약! 잊지 말자.
 항목 28. 내부에서 사용하는 객체에 대한 "핸들"을 반환하는 코드는 되도록 피하자.
 항목 29. 예외 안전성이 확보되는 그날 위해 싸우고 또 싸우자!
 항목 30. 인라인 함수는 미주알고주알 따져서 이해해 두자.
 항목 31. 파일 사이의 컴파일 의존성을 최대로 줄이자.
 

 Chapter 6. 상속, 그리고 객체 지향 설계 
 항목 32. public 상속 모형은 반드시 "is-a"를 따르도록 만들자.
 항목 33. 상속된 이름을 숨기는 일은 피하자.
 항목 34. 인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구별하자.
 항목 35. 가상 함수 대신 쓸 것들도 생각해 두는 자세를 시시때때로 길러 두자.
 항목 36. 상속받은 비가상 함수를 파생 클래스에서 재정의하는 것은 절대 금물!
 항목 37. 어떤 함수에 대해서도 상속받은 기본 매개변수 값은 절대로 재정의하지 말자.
 항목 38. "has-a" 혹은 "is-implemented-in-terms-of"를 모형화 할때는 객체 합성을 사용하자.
 항목 39. private 상속은 심사숙고해서 구사하자.
 항목 40. 다중 상속은 심사숙고해서 사용하자.
 

 Chapter 7. 템플릿과 일반화 프로그래밍
 항목 41. 템플릿 프로그래밍의 천릿길도 암시적 인터페이스와 컴파일 타임 다형성부터
 항목 42. typename의 두 가지 의미를 제대로 파악하자.
 항목 43. 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아 두자.
 항목 44. 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자.
 항목 45. "호환되는 모든 타입"을 받아들이는 데는 멤버 함수 템플릿이 직방!
 항목 46. 타입 변환이 바람직할 경우에는 비멤버 함수를 클래스 템플릿 안에 정의해 두자.
 항목 47. 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자.
 항목 48. 템플릿 메타프로그래밍, 하지 않겠는가?
 

 Chapter 8. new와 delete를 내 맘대로
 항목 49. new 처리자의 동작 원리를 제대로 이해하자.
 항목 50. new 및 delete를 언제 바꿔야 좋은 소리를 들을지를 파악해 두자.
 항목 51. new 및 delete를 작성할 때 따라야 할 기존의 관례를 잘 알아 두자.
 항목 52. 위치지정 new를 작성한다면 위치지정 delete도 같이 준비하자.

  Chapter 9. 그 밖의 이야기들
 항목 53. 컴파일러 경고를 지나치지 말자.
 항목 54. TR1을 포함한 표준 라이브러리 구성요소와 편안한 친구가 되자.
 항목 55. Boo자유친! 부스트를 늘 여러분 가까이에
 


http://kelly.springnote.com/pages/552442

블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

IO Completion Port 작성 하기





1. MFC 프로젝트 - 다이얼로그 방식

프로젝트명 : IOCompletionPort 

생성 : 
자동 ( IOCompletionPortDlg.h / IOCompletionPortDlg.cpp / class CIOCompletionPort() {} /
        로 생김(자동으로 C가 붙음) )


2. 다이얼로그에  ListBox Control 추가

---- 흠

3. 버튼을 옮겨서 : 서버 시작 버튼을 만들고.....클릭시 함수처리부분에서 호출 및 사용될  class 정의


4.  class 정의 :  cIOCompletionPort

5. 클래스 마법사에서 ListBox 멤버 변수 작성 - IOCompletionPortDlg.cpp
6. ListBox에 문자 출력하는 함수 작성 - IOCompletionPortDlg.cpp
IOCompletionPortDlg.h
// 흠 흠 흠
#include "afxwin.h"
#include "resource.h"

#include "cIOCompletionPort.h"

#define	LISTEN_PORT		8000

///..........

public:
	void OutputMsg(char * szOutputString,...);
	CListBox m_ctOutput;
	boolean		m_bServerStarted;
	cIOCompletionPort m_IOCompletionPort;

	afx_msg void OnBnClickedStartserver();
	afx_msg void OnBnClickedCancel();



IOCompletionPortDlg.cpp
/// 사용자 추가
void CIOCompletionPortDlg::OutputMsg(char * szOutputString,...)
{

	char szOutStr[1024];
	va_list argptr;

	va_start(argptr, szOutputString) ;
	vsprintf( szOutStr, szOutputString, argptr );
	va_end(argptr);

	
	//  CListBox에 추가

	// 속성 - > 구성속성->일반 -> 멀티 바이트 문자 조합 MBCS
	//m_ctOutput.SetCurSel( m_ctOutput.AddString( szOutStr ) );

	m_ctOutput.InsertString(0, szOutStr) ;

}



void CIOCompletionPortDlg::OnBnClickedStartserver()
{
	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.

		if ( ! m_bServerStarted  ) {
			OutputMsg("0.----서버 ");

			m_IOCompletionPort.SetMainDlg(this);
			bool bRet = m_IOCompletionPort.InitSocket();

			OutputMsg("1.----포트:%d", LISTEN_PORT );
			m_IOCompletionPort.BindandListen(LISTEN_PORT);

			OutputMsg("2.----가동 " );
			m_IOCompletionPort.StartServer();

			m_bServerStarted=true;
		} else {
			OutputMsg("****************서버 가동중 : 누르지 마세요 ******************");
		}

}


void CIOCompletionPortDlg::OnBnClickedCancel()
{
	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.

	m_IOCompletionPort.DestroyThread();

	CDialogEx::OnCancel();
}


cIOCompletionPort.h
// 1. 패킷 사이즈
#define MAX_SOCKBUF		1024
// 2. 클라이언트 수
#define		MAX_CLIENT	1024
// 3. 쓰레스 수
#define		MAX_WORKERTHREAD	4


enum	enumOperation {
	OP_RECV,
	OP_SEND
};

/// WSAOVERLAPPED 구조체를 확장시켜 필요한 정보 추가
struct stOverlappedEx {
	WSAOVERLAPPED		m_wsaOverlapped;	// Overlapped I/O 구조체
	SOCKET				m_socketClient;		// client socket
	WSABUF				m_wsaBuf;			// Overlapped I/O 작업 버퍼
	char				m_szBuf[MAX_SOCKBUF];	// 데이타 버퍼
	enumOperation		m_eOperation;			// 작업 동작 종류
};
/// client 정보를 담기 위한 구조체
struct	stClientInfo {
	SOCKET				m_socketClient;		// 클라이언트와 연결되는 소켓
	stOverlappedEx		m_stRecvOverlappedEx;	// Recv Overlapped I/O 작업을 위한 변수
	stOverlappedEx		m_stSendOverlappedEx;	// Send Overlapped I/O 작업을 위한 변수

	/// 생성자에서 멤버 변수들을 초기화
	stClientInfo() 
	{
		m_socketClient = INVALID_SOCKET;
		ZeroMemory( &m_stRecvOverlappedEx, sizeof(m_stRecvOverlappedEx) );
		ZeroMemory( &m_stSendOverlappedEx, sizeof(m_stSendOverlappedEx) );
	}
};


class CIOCompletionPortDlg;

class cIOCompletionPort
{
public:
	cIOCompletionPort(void);
	~cIOCompletionPort(void);
	bool InitSocket(void);

	bool BindandListen(int nPort);
	bool StartServer(void);
	bool CreateWorkerThread(void);
	bool CreateAccepterThread(void);
	stClientInfo * GetEmptyClientInfo(void);
	bool BindIOCompletionPort(stClientInfo * pClientInfo);

	bool BindRecv(stClientInfo * pClientInfo);
	bool SendMsg(stClientInfo * pClientInfo, char * pMsg, int nLen);
	void WorkerThread(void);
	void AccepterThread(void);
	void SetMainDlg(CIOCompletionPortDlg * pMainDlg);
	void DestroyThread(void);
	void CloseSocket(stClientInfo * pClientInfo, bool bIsForce=false);
private:
	// 1. 클라이언트 정보 저장 구조체
	stClientInfo *	m_pClientInfo;

	// 2. 클라이언트 접속을 받기위한 리슨 소켓
	SOCKET			m_socketListen;

	// 3. 접속 되어 있는 클라이언트 수
	int				m_nClientCnt;

	// 4. 메인 윈도우 포인터
	CIOCompletionPortDlg *		m_pMainDlg;

	// 5. 작업 스레드 핸들
	HANDLE			m_hWorkerThread[MAX_WORKERTHREAD];

	// 6. 접속 스레드 핸들
	HANDLE			m_hAccepterThread;

	// 7. CompletionPort 객체 핸들
	HANDLE			m_hIOCP;

	// 8. 작업 스레드 동작 플래그
	bool			m_bWorkerRun;

	// 9. 접속 스레드 동작 플래그
	bool			m_bAccepterRun;

	// 10. 소켓 버퍼
	char			m_szBuf[1024];

};



cIOCompletionPort.cpp
#include "StdAfx.h"

#include "cIOCompletionPort.h"

//// 흠
#include "IOCompletionPortDlg.h"

/// 쓰레드 만들기 
/// WSARecv , WSASend의 Overlapped I/O 작업을 위한 
unsigned int WINAPI	CallWorkerThread(LPVOID p)
{
	cIOCompletionPort * pOverlappedEvent = (cIOCompletionPort *)p;

	pOverlappedEvent->WorkerThread();

	return 0;
}
unsigned int WINAPI	CallAccepterThread(LPVOID p)
{
	cIOCompletionPort * pOverlappedEvent = (cIOCompletionPort *)p;

	pOverlappedEvent->AccepterThread();

	return 0;
}
/// 
cIOCompletionPort::cIOCompletionPort(void)
{
	/// 모든 멤버 변수들의 초기화
	m_pMainDlg = NULL;
	m_bWorkerRun	= true;
	m_bAccepterRun	= true;
	m_nClientCnt = 0;
	m_hAccepterThread = NULL;
	m_hIOCP	= NULL;
	m_socketListen = INVALID_SOCKET;
	ZeroMemory(m_szBuf, 1024);
	for ( int i=0; i < MAX_WORKERTHREAD; i++ ) {
		m_hWorkerThread [i] = NULL;
	}
	m_pClientInfo = new stClientInfo[MAX_CLIENT];
}


cIOCompletionPort::~cIOCompletionPort(void)
{
	// 윈속 사용 해재
	WSACleanup();
	// 다 사용한 객체 삭제
	if ( m_pClientInfo ) 
	{
		delete[] m_pClientInfo;
		m_pClientInfo = NULL;
	}
}


bool cIOCompletionPort::InitSocket(void)
{
	WSADATA	wsaData;

	// 윈속 버젼 2.2
	int nRet = WSAStartup( MAKEWORD(2,2) , &wsaData);
	if ( 0 != nRet ) {

		m_pMainDlg->OutputMsg("[에러]WSAStartup() 실패:%d:",WSAGetLastError() );

		return false;
	}
	m_socketListen = WSASocket(AF_INET, SOCK_STREAM,
					IPPROTO_TCP, NULL, NULL, WSA_FLAG_OVERLAPPED );

	if ( INVALID_SOCKET == m_socketListen ) {

		m_pMainDlg->OutputMsg("[에러]WSASocket() 실패:%d:",WSAGetLastError() );

		return false;

	}
	m_pMainDlg->OutputMsg(" InitSocket() 성공" );
	///
	return true;
}




bool cIOCompletionPort::BindandListen(int nPort)
{

	SOCKADDR_IN		stServerAddr;

	stServerAddr.sin_family = AF_INET;

	stServerAddr.sin_port = htons(nPort);

	stServerAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

	int nRet = bind( m_socketListen, (SOCKADDR *)&stServerAddr, sizeof(SOCKADDR_IN) );
	if ( 0 != nRet ) {

		m_pMainDlg->OutputMsg("[에러] bind() 실패:%d:",WSAGetLastError() );

		return false;

	}
	nRet = listen( m_socketListen, 5 ) ;
	if ( 0 != nRet ) {

		m_pMainDlg->OutputMsg("[에러] listen() 실패:%d:",WSAGetLastError() );

		return false;

	}
	m_pMainDlg->OutputMsg(" BindandListen() 성공" );
	///
	return true;
}





bool cIOCompletionPort::CreateWorkerThread(void)
{

	unsigned int uiThreadId = 0;

	/// Waiting Thread Queue에 대기 상태로 넣을 쓰레드들 생성
	/// 권장하는 개수 : cpu *2 +1

	for ( int i =0; i < MAX_WORKERTHREAD; i++ ) 
	{

		m_hWorkerThread[i] = (HANDLE)_beginthreadex(NULL, 0,
							&CallWorkerThread,
							this,
							CREATE_SUSPENDED,
							&uiThreadId);
		if ( m_hWorkerThread[i] == NULL ) 
		{
			m_pMainDlg->OutputMsg("[에러] CreateWorkerThread() 실패:%d:",GetLastError() );

			return false;
		}
		ResumeThread( m_hWorkerThread[i] );
	}


	m_pMainDlg->OutputMsg(" CreateWorkerThread() 성공" );
	///
	return true;
}


bool cIOCompletionPort::CreateAccepterThread(void)
{

	unsigned int uiThreadId = 0;

	/// 클라이언트 접속 요청을 받은 쓰레드 생성
	m_hAccepterThread = (HANDLE)_beginthreadex(NULL, 0,
						&CallAccepterThread,
						this,
						CREATE_SUSPENDED,
						&uiThreadId);
	if ( m_hAccepterThread == NULL ) 
	{
		m_pMainDlg->OutputMsg("[에러] CreateAccepterThread() 실패:%d:",GetLastError() );

		return false;
	}
	ResumeThread( m_hAccepterThread );


	m_pMainDlg->OutputMsg(" CreateAccepterThread() 성공" );
	///
	return true;
}
////
bool cIOCompletionPort::BindIOCompletionPort(stClientInfo * pClientInfo)
{

	HANDLE hIOCP;

	/// socket 과 pClientInfo를  CompletionPort객체와 연결 시킨다.
	hIOCP = CreateIoCompletionPort( (HANDLE)pClientInfo->m_socketClient,
			m_hIOCP,
			reinterpret_cast( pClientInfo ),
			0);
	if ( NULL == hIOCP || m_hIOCP != hIOCP ) 
	{
		m_pMainDlg->OutputMsg("[에러] CreateIoCompletionPort() 실패:%d:",GetLastError() );

		return false;
	}


	m_pMainDlg->OutputMsg(" BindIOCompletionPort() 성공" );
	///
	return true;
}

bool cIOCompletionPort::StartServer(void)
{


	m_hIOCP = CreateIoCompletionPort( INVALID_HANDLE_VALUE,
								NULL,
								NULL,
								0);
	if ( NULL == m_hIOCP ) 
	{
		m_pMainDlg->OutputMsg("[에러] CreateIoCompletionPort() 실패:%d:",GetLastError() );

		return false;
	}

	
	bool bRet = CreateWorkerThread();
	if ( false == bRet ) 
	{
		m_pMainDlg->OutputMsg("[에러] CreateWorkerThread() 실패:%d:",GetLastError() );

		return false;
	}

	bRet = CreateAccepterThread();
	if ( false == bRet ) 
	{
		m_pMainDlg->OutputMsg("[에러] CreateAccepterThread() 실패:%d:",GetLastError() );

		return false;
	}

	m_pMainDlg->OutputMsg(" StartServer() 성공" );
	///
	return true;
}

	
bool cIOCompletionPort::BindRecv(stClientInfo * pClientInfo)
{
	DWORD	dwFlag = 0;
	DWORD	dwRecvNumBytes = 0;


	// Overlapped I/O Setting
	pClientInfo->m_stRecvOverlappedEx.m_wsaBuf.len = MAX_SOCKBUF;
	pClientInfo->m_stRecvOverlappedEx.m_wsaBuf.buf = 
		pClientInfo->m_stRecvOverlappedEx.m_szBuf;
	pClientInfo->m_stRecvOverlappedEx.m_eOperation = OP_RECV;

	
	//// 입력 버퍼 클리어 ???????????????
	//ZeroMemory(pClientInfo->m_stRecvOverlappedEx.m_szBuf, 1024);

	int nRet = WSARecv( pClientInfo->m_socketClient,
						&(pClientInfo->m_stRecvOverlappedEx.m_wsaBuf),
						1,
						&dwRecvNumBytes,
						&dwFlag,
						(LPWSAOVERLAPPED)&(pClientInfo->m_stRecvOverlappedEx),
						NULL);
	/// socket_error 이면 client socket이 끊어 진걸로 처리한다.
	if ( nRet ==  SOCKET_ERROR && ( ERROR_IO_PENDING != WSAGetLastError()  )  ) 
	{
		m_pMainDlg->OutputMsg("[에러] BindRecv WSARecv() 실패 WSAGetLastError:%d:",WSAGetLastError() );

		return false;
	}
	m_pMainDlg->OutputMsg("[알림] BindRecv WSARecv() 성공");
	return true;
}


bool cIOCompletionPort::SendMsg(stClientInfo * pClientInfo, char * pMsg, int nLen)
{
	DWORD	dwRecvNumBytes = 0;

	//전송될 메시지를 복사
	CopyMemory( pClientInfo->m_stSendOverlappedEx.m_szBuf, pMsg, nLen );


	// Overlapped I/O Setting 정보
	pClientInfo->m_stSendOverlappedEx.m_wsaBuf.len = nLen;

	pClientInfo->m_stSendOverlappedEx.m_wsaBuf.buf =
							pClientInfo->m_stSendOverlappedEx.m_szBuf;

	pClientInfo->m_stSendOverlappedEx.m_eOperation = OP_SEND;

	int nRet = WSASend( pClientInfo->m_socketClient, 
						&(pClientInfo->m_stSendOverlappedEx.m_wsaBuf),
						1,
						&dwRecvNumBytes,
						0,
						(LPWSAOVERLAPPED)&(pClientInfo->m_stSendOverlappedEx),
						NULL);
	if ( nRet == SOCKET_ERROR ) {
		m_pMainDlg->OutputMsg("[에러] SendMsg WSASend() nRet:%s:","SOCKET_ERROR" );
	}
	/// socket_error 이면 client socket이 끊어 진걸로 처리한다.
	if ( nRet ==  SOCKET_ERROR && ( WSAGetLastError() != ERROR_IO_PENDING )  ) 
	{
		m_pMainDlg->OutputMsg("[에러] SendMsg WSASend() 실패 WSAGetLastError:%d:",WSAGetLastError() );

		return false;
	}
			
	m_pMainDlg->OutputMsg("[알림] SendMsg WSASend() 성공");

	return true;
}
// 할당
stClientInfo * cIOCompletionPort::GetEmptyClientInfo(void)
{
	for(int i = 0; i < MAX_CLIENT; i++ ) 
	{
		if(INVALID_SOCKET == m_pClientInfo[i].m_socketClient) 
		{
			return &m_pClientInfo[i];
		}
	}
	return NULL;
}



// 사용자 접속 받는 쓰레드
void cIOCompletionPort::AccepterThread(void)
{
	SOCKADDR_IN		stClientAddr;

	int nAddrLen = sizeof(SOCKADDR_IN);
	while ( m_bAccepterRun)
	{
		// 접속 받을 구조체 인덱스 얻기
		stClientInfo * pClientInfo = GetEmptyClientInfo();
		if ( NULL == pClientInfo )
		{
			m_pMainDlg->OutputMsg("[에러] NULL == pClientInfo :%s:","Client FULL");

			return ;
		}
		// 클라이언트 접속 요청까지 대기
		pClientInfo->m_socketClient = accept ( m_socketListen,
							(SOCKADDR *)&stClientAddr, &nAddrLen );
		if ( INVALID_SOCKET == pClientInfo->m_socketClient ) {
			continue;
		}
		// I/O Completion Port객체와 소켓을 연결 시킨다.
		bool bRet = BindIOCompletionPort( pClientInfo );
		if ( false == bRet ) {
			return;
		}
		// Recv Overlapped I/O 작업을 요청한다
		bRet = BindRecv(pClientInfo);
		if ( false == bRet ) {
			return;
		}

		m_pMainDlg->OutputMsg("[클라이언트 접속] ip(%s) SOCKET(%d)",
			inet_ntoa( stClientAddr.sin_addr) ,
			pClientInfo->m_socketClient);

		m_nClientCnt ++;

	}
}


void cIOCompletionPort::WorkerThread(void)
{
	// CompletionKey를 받을 포인터 변수
	stClientInfo * pClientInfo = NULL;

	// 함수 호출 성공여부
	BOOL bSuccess = TRUE;

	// Overlapped I/O작업에서 전송된 데이타 크기
	DWORD dwIoSize = 0;

	// I/O 작업을 위해 요청한 Overlapped 구조체를 받을 포인터
	LPOVERLAPPED lpOverlapped = NULL;

	while ( m_bWorkerRun ) 
	{
		/**
		이 함수로 인해 쓰래들들은 WaitingThread Queue에 대기상태로 들어간다
		완료된 Overlapped I/O 작업이 발생하면 IOCP Queue에서 완료된 작업을 가져와 뒤처리
		그리고 PostQueuedCompletionStatus()함수에 의해 사용자 메시지가 도착되면 쓰레드 종료
		**/
		bSuccess = GetQueuedCompletionStatus( m_hIOCP,
				&dwIoSize,							// 실제 전송된 바이트
				(LPDWORD)&pClientInfo,				// Completionkey
				&lpOverlapped,						// Overlappped I/O 객체
				INFINITE);							// 대기할 시간(무한대기)
		
		// 클라이언트가 접속 끊었을 때
		//
		//  FALSE == bSuccess
		//
		if ( FALSE == bSuccess && 0 == dwIoSize ) 
		{
			m_pMainDlg->OutputMsg("[클라이언트] SOCKET(%d) 접속 끊김",	pClientInfo->m_socketClient);
			CloseSocket(pClientInfo);
			continue;
		}

		// 사용자 스레드 종료 메시지 처리
		//
		//  TRUE == bSuccess
		//

		if ( TRUE == bSuccess && 0 == dwIoSize && NULL == lpOverlapped )
		{
			//
			// WorkerThread 종료
			//
			m_bWorkerRun = false ;
			continue;
		}

		if ( NULL == lpOverlapped ) {
			continue;
		}
		stOverlappedEx * pOverlappedEx =(stOverlappedEx *)lpOverlapped;

		// Overlapped I/O Recv 작업 결과 뒤 처리
		// 
		//	OP_RECV
		//
		if ( OP_RECV == pOverlappedEx->m_eOperation ) 
		{
			pOverlappedEx->m_szBuf[dwIoSize] = NULL;
			m_pMainDlg->OutputMsg("[수신] ( %d ) bytes , msg : %s ",dwIoSize,pOverlappedEx->m_szBuf);

			// 클라이언트에 메시지를 에코한다.
			//BindRecv( pClientInfo );

			//SendMsg(pClientInfo, pOverlappedEx->m_szBuf, dwIoSize );

			//pOverlappedEx->m_eOperation = OP_SEND;
			//BindRecv( pClientInfo );

			SendMsg( pClientInfo, pOverlappedEx->m_szBuf, dwIoSize);

		}
		// Overlapped I/O Send 작업 결과 뒤 처리
		// 
		//	OP_SEND
		//
		else if ( OP_SEND == pOverlappedEx->m_eOperation ) 
		{
			m_pMainDlg->OutputMsg("[송신] ( %d ) bytes , msg : %s ",dwIoSize,pOverlappedEx->m_szBuf);
			
			//// 입력 버퍼 클리어 ???????????????
			ZeroMemory(pOverlappedEx->m_szBuf, 1024);

			BindRecv( pClientInfo );

		}
		else 
		{
			m_pMainDlg->OutputMsg("[클라이언트] SOCKET(%d) 예외 상황 ",pClientInfo->m_socketClient);
		}
		lpOverlapped = NULL;
	}
}

void cIOCompletionPort::SetMainDlg(CIOCompletionPortDlg * pMainDlg)
{
	/// .h에서 .cpp로 옮겨 놓았는데? 문제 없나?
	m_pMainDlg = pMainDlg;
}


void cIOCompletionPort::DestroyThread(void)
{
	for(int i=0; i< MAX_WORKERTHREAD; i++)
	{
		// WaitingThreadQueue에서 대기중인 쓰레드에 사용자 종료 메시지 보내기
		PostQueuedCompletionStatus( m_hIOCP,0,0,NULL);
	}
	for(int i=0; i< MAX_WORKERTHREAD; i++)
	{
		CloseHandle( m_hWorkerThread[i] );
		WaitForSingleObject ( m_hWorkerThread[i], INFINITE );
	}

	m_bAccepterRun = false;
	// Accepter Thread 종료
	closesocket( m_socketListen );
	// Thread 종료
	WaitForSingleObject( m_hAccepterThread, INFINITE );


}


void cIOCompletionPort::CloseSocket(stClientInfo * pClientInfo, bool bIsForce)
{
	struct linger stLinger = {0,0};

	if ( true ) {
		// timeout=0으로 설정되어 강제 종료. 주의 : 데이타 손실 가능성
		// right now !!!
		stLinger.l_onoff = 1;
	}
	// 데이타 송수신 모두 중단
	shutdown( pClientInfo->m_socketClient, SD_BOTH );

	// 소켓 옵션
	setsockopt( pClientInfo->m_socketClient, SOL_SOCKET, SO_LINGER,
			(char *)&stLinger, sizeof(stLinger) );
	// 소켓 연결 종료
	closesocket(pClientInfo->m_socketClient);
	pClientInfo->m_socketClient = INVALID_SOCKET;
}


'Application, App > VC++' 카테고리의 다른 글

OnTimer - SetTimer  (0) 2016.12.15
Packet Class // 바이트 버퍼링 전송 수신 send receive  (0) 2016.12.15
Stack with std::list  (0) 2016.12.15
Effective C++ 목차  (0) 2016.12.15
블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.



ListView에서 자동 스크롤 시키기



추가등의 변경시에 




xml layout에서, 아래 파라미터를 listview에 설정을 하세요.


android:stackFromBottom="true"
android:transcriptMode="alwaysScroll"




출처 :


http://stackoverflow.com/questions/3606530/listview-scroll-to-the-end-of-the-list-after-updating-the-list


블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.



안드로이드 스튜디오에서 SHA-1 생성




  1. Open 안드로이드 스튜디오
  2. Open [해당 프로젝트]
  3. Click on Gradle (From Right Side Panel, you will see Gradle Bar)

  1. Click on Refresh (Click on Refresh from Gradle Bar, you will see List Gradle scripts of your Project)
  2. Click on [해당 프로젝트] (Your Project Name form List (root))
  3. Click on Tasks
  4. Click on Android
  5. Double Click on signingReport (You will get SHA1 and MD5 in Run Bar)

  1. Then click this button(Run화면): enter image description here
















참조 :

http://stackoverflow.com/questions/39697905/generate-sha1-fingerprint-in-android-studio-2-2

블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.

Android Chat SDK

순위권 Tread 비교


     -순위권
        zendesk ( or  zopim )
        liveperson
        twilio
        cometchat
        sendbird

     -순위권외
        conversity
        applogic
        azstack
        velaro
        snapengage
        purechat
        boldchat
        clickdesk
        comm1000
        smartsupp
        kayakoengage
        livehelpnow
        websitealive


https://www.google.com/trends/explore?q=zendesk,liveperson,twilio,cometchat,sendbird



Zendesk vs Salesforce vs Freshdesk: Comparison of Top 3 Help Desk Solutions

1.Freshdesk


2.Zendesk


3.Salesforce


https://financesonline.com/zendesk-salesforce-freshdesk-comparison-of-top-3-help-desk-solutions/


블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,
노출되는 이미지가 불편하시겠지만 양해를 구합니다. 노출, 클릭등에 관한 자료로 활용 중입니다.


Android HelloWorld 만들기


Android Studio를 실행하고,


1. create a new project



2. project name & company domain

Application name : My First App

Company Domain : example.com


3. Target Android Devices 선택 , Minimum SDK 선택


4. Add an Activity to Mobile , Empty Activity 선택


5. Customize the Activity , 기본값으로.. Finish


https://developer.android.com/training/basics/firstapp/creating-project.html




실행



Available Virtual Devices에 AVD(Android Virtual Device)추가 하기


Tools -> Android -> AVD Manager 선택


1. Create Virtual Device...



2. Select Hardware, Nexus 6를 선택


3. Select Image , API 22를 선택


4. AVD , Finish


실행 2





https://developer.android.com/training/basics/firstapp/running-app.html

블로그 이미지

StartGuide

I want to share the basic to programming of each category and how to solve the error. This basic instruction can be extended further. And I have been worked in southeast Asia more than 3 years. And I want to have the chance to work another country.

,