Android 6.0 이상에서는 앱에 권한이 필요함을 선언하려면 해당 권한을 Manifest에 나열하고 런타임에 사용자가 권한을 승인하도록 해야합니다.  Android 지원 라이브러리를 사용하여 권한을 확인하고 요청하는 방법을 알아보겠습니다.

 

Android 프레임워크에서는 Android 6.0(API level 23)과 유사한 메서드를 제공하지만 지원라이브러리르 사용하여 더욱 쉽게 이전 Android 버전과 호환성을 지원할 수 있습니다.

 

manifest에 권한 추가

Android에서는 버전에 상관없이 앱에 권한이 필요함을 선언하려면 manifest에 <uses-permission> 요소를 최상위 <manifest>의 하위요소로 지정합니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hyun.sqlite">

    <uses-permission android:name="android.permission.CAMERA"/>

    <application
    	...
    </application>

</manifest>

권한 선언 후 해당 권한의 민감한 정도에 따라 시스템 동작은 달라집니다. 어떤 권한은 '정상'권한으로 간주되어 시스템이 설치 시에 곧바로 부여하지만, 어떤 권한은 '위험'권한으로 간주되어 사용자가 명시적으로 엑세스 권한을 부여해야 합니다. 권한에 관한 자세한 정보는 보호수준에서 확인할 수 있습니다.

 

권한 확인

앱에 위험 권한이 필요한 경우 해당 권한이 요구되는 작업을 할 때마다 권한이 있는지 확인해야합니다.

Android 6.0(API level 23)부터는 앱이 더 낮은 API 레벨을 타겟팅하더라도 사용자가 언제든 앱의 권한을 취소할 수 있습니다. 따라서 어제 카메라를 사용했다고 해서 오늘도 권한이 있다고 가정할 수는 없습니다.

 

권한이 있는지 확인하려면 ContextCompat.checkSelfPermission()메서드를 호출합니다.

// 권한 체크하기
if(ContextCompat.checkSelfPermission(this@WelcomeActivity, Manifest.permission.CAMERA) ==
   PackageManager.PERMISSION_GRANTED) {
	// 권한이 있을 때 카메라 실행하기
	Toast.makeText(this, "카메라 허가 가능, 프리뷰 시작", Toast.LENGTH_SHORT).show()
	startCamera()
} else {
	// 권한이 없을 때 권한 요청하기
	requestCameraPermission()
}

앱에 권한이 있는 경우 이 메서드는 PERMISSION_GRANTED를 반환하고, 앱은 작업을 계속 진행할 수 있습니다. 앱에 권한이 없는 경우 이 메서드는 PERMISSION_DENIED를 반환하고, 앱은 사용자에게 명시적으로 권한을 요청해야합니다.

 

권한 요청

앱이 checkSelfPermission()에서 PERMISSION_DENIED를 수신하면 사용자에게 해당 권한을 요청하는 메시지를 표시해야합니다. Android는 requestPermissions()과 같이 권한을 요청하는데 사용할 수 있는 여러 메서드를 제공합니다. 이러한 메서드를 호출하면 표준 Android 대화상자가 나타나며, 이 상자는 맞춤설정할 수 없습니다.

 

사용자에게 표시되는 방식은 기기 Android버전과 애플리케이션의 대상 버전에 따라 다릅니다. 자세한 내용은 권한 개요에 설명됩니다.

 

앱에 권한이 필요한 이유 설명

사용자가 사진앱을 실행하는 경우 사용자에게 카메라 사용 권한을 요청해도 놀라지 않을 것입니다. 그러나 사용자 위치나 연락처에 접근하려고 하면 사용자가 이유를 이해하지 못할 수도 있습니다. 앱에서 권한을 요청하기 전에 먼저 사용자에게 이유를 설명하는 것을 고려해야합니다. 명심할 점은, 설명이 사용자에게 부담이 되어서는 안됩니다. 너무 많은 설명을 제공할 경우 사용자가 짜증을 느끼고 앱을 제거할 수도 있습니다.

 

권한 설명에서 사용할 수 있는 한 가지 방법은 사용자가 해당 권한 요청을 이미 거절한 경우에만 설명을 제공하는 것입니다. Android에서는 이를 위해 유틸리티 메서드 shouldShowRequestPermissionRationable()를 제공합니다. 이 메서드는 사용자가 전에 해당 요청을 거부한 경우에는 true를 반환하고, 사용자가 해당 권한을 거부했으며 '다시 묻지 않음' 옵션을 선택했거나 기기 정책에서 해당 권한을 금지하는 경우에는 false를 반환합니다.

 

사용자가 권한이 요구되는 기능을 계속 사용하려고 시도하면서도 권한 요청을 계속 거절한다면 아마도 이 사용자는 해당 기능을 제공하기 위해 앱에 권한이 필요한 이유를 모를 수도 있습니다. 이런 상황에서는 설명을 하는 것이 좋을 수 있습니다. 권한을 요청할 때 좋은 사용자 환경을 만드는 방법에 관한 권장사항을 확인할 수 있습니다.

 

여러분에게 필요한 권한 요청

앱에 필요한 권한이 아직 없는 경우 앱은 requestPermissions() 메서드 중 하나를 호출하여 적절한 권한을 요청해야 합니다. 앱은 원하는 권한 및 이 권한 요청을 식별하기 위해 지정된 정수 요청 코드를 전달합니다. 이 메서드는 비동기식으로 작동합니다. 즉각적으로 반환되며, 사용자가 메시지에 응답하면 시스템은 그 결과를 가지고 앱의 콜백 메서드를 호출하여 앱이 requestPermissions()에 전달한 것과 동일한 요청 코드를 전달합니다.

 

아래의 예는 카메라 권한을 요청하는 코드입니다.

시나리오

  • 카메라 접근 권한이 있는지 확인

  • 권한이 없으면 권한이 필요한 이유를 표시해야하는지 확인

  • 권한 요청

private fun requestCameraPermission() {

	if (ActivityCompat.shouldShowRequestPermissionRationale(this@WelcomeActivity, Manifest.permission.CAMERA)) {
        Toast.makeText(this@WelcomeActivity, "카메라 권한이 요구됩니다", Toast.LENGTH_SHORT).show()
        ActivityCompat.requestPermissions(this@WelcomeActivity, arrayOf(Manifest.permission.CAMERA), PERMISSION_REQUEST_CAMERA)
    } else {
        // 다시 묻지 않음을 누르고 거부하고 요청했을 때
        Toast.makeText(this@WelcomeActivity, "카메라 허가를 받을 수 없습니다.", Toast.LENGTH_SHORT).show()
        ActivityCompat.requestPermissions(this@WelcomeActivity, arrayOf(Manifest.permission.CAMERA), PERMISSION_REQUEST_CAMERA)
    }
}

참고 : requestPermissions()을 호출하면 시스템은 표준 대화상자를 사용자에게 표시합니다. 이 대화상자를 구성하거나 변경할 수 없습니다. 앱에 권한이 필요한 이유에 나오는 것처럼, 사용자에게 정보나 설명을 제공해야하는 겨우 requestPermissions()를 호출하기 전에 제공하는 것이 좋습니다.

권한 요청 응답 처리

사용자가 앱 권한 요청에 응답하면 시스템은 앱의 onRequestPermissionResult() 메서드를 호출하여 사용자 응답을 전달합니다. 권한이 부여되었는지 확인하려면 앱은 해당 메서드를 재정의해야 합니다. 이 콜백에는 requestPermissions()에 전달한 것과 동일한 요청 코드가 전달됩니다.

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray
) {

    if(requestCode == PERMISSION_REQUEST_CAMERA) {
        if(grantResults.size == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this, "카메라의 허가를 받았다", Toast.LENGTH_SHORT).show()
            startCamera()
        }
    } else {
        Toast.makeText(this, "카메라 요청이 거부되었다", Toast.LENGTH_SHORT).show()
    }
}

시스템이 표시하는 대화상자에서는 앱이 액세스해야 하는 권한 그룹을 설명합니다. 특정 권한은 나열하지 않습니다. 

 

예를 들어 READ_CONTACTS 권한을 요청하는 경우 기기의 연락처에 액세스해야 한다는 메시지만 시스템 대화상자에 나타납니다. 사용자는 각 권한 그룹에 관해 한번만 권한을 부여해야 합니다.

 

앱이 해당 그룹에 있는 다른 권한(앱 manifest에 나열된 다른 권한)을 요청하는 경우 시스템이 자동으로 권한을 부여합니다. 여러분이 권한을 요청하면 시스템은 사용자가 시스템 대화상자를 통해 명시적으로 요청을 승인했을 때와 동일한 방식으로 onRequestPermissionsResult() 콜백 메서드를 호출하고 PERMISSION_GRANTED를 전달합니다.

 

참고 : 사용자가 이미 동일한 그룹에 있는 다른 권한을 부여한 경우라도 앱이 필요한 모든 권한을 명시적으로 요청해야 합니다. 향후 Android 리리스에서는 권한 그룹화도 변경될 수 있습니다. 코드에서는 특정 권한이 동일한 그룹에 있다고 가정하거나 없다고 가정해서는 안됩니다.

 

예를 들어 manifest에 READ_CONTACTS 및 WRITE_CONTACTS를 둘 다 나열한다고 가정합니다. READ_CONTACTS를 요청하여 사용자가 권한을 부여한 후 WRITE_CONTACTS를 요청하면 시스템이 사용자와 상호작용 없이 곧바로 해당 권한을 부여합니다.

 

사용자가 권한 요청을 거부하는 경우 앱은 적절한 작업을 수행해야 합니다. 예를 들어 해당 권한이 필요한 작업을 사용자가 요청하면, 수행할 수 없는 이유를 설명하는 대화상자를 표시할 수 있습니다.

 

시스템에서 사용자에게 권한을 부여하도록 요청하면 사용자는 해당 권한을 다시 요청하지 말도록 시스템에 지시할 수 있습니다. 이 경우 앱이 해당 권한을 다시 요청하기 위해 requestPermissions()를 사용할 때 마다 시스템은 즉시 해당 요청을 거부합니다. 시스템은 사용자가 명시적으로 요청을 다시 거부했을 때와 동일한 방식으로 onRequestPermissionResult() 콜백 메서드를 호출하고 PERMISSION_DENIED를 전달합니다.

 

앱이 해당 권한을 가지지 못하도록 기기 정책에서 금지하는 경우에도 이 메서드는 false를 반환합니다. 즉, requestPermissions()를 호출하는 경우 사용자와의 직접적 상호작용이 발생했다고 가정할 수 없습니다.

 

Reference

 

Android Runtime PermissionBasicSample을 참고하여 만들었습니다. 

package com.hyun.sqlite

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.activity_welcome.*

const val PERMISSION_REQUEST_CAMERA = 0

class WelcomeActivity : AppCompatActivity() {

    val TAG: String = ".WelcomeActivityAKDJKA"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_welcome)

        btn_camera.setOnClickListener {
            showCameraPreview()
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<out String>, grantResults: IntArray
    ) {
        Log.d(TAG, "onRequestPermissionsResult")

        if (requestCode == PERMISSION_REQUEST_CAMERA) {
            if (grantResults.size == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "카메라의 허가를 받았다. 프리뷰 시작", Toast.LENGTH_SHORT).show()
                startCamera()
            }
        } else {
            Toast.makeText(this, "카메라 요청이 거부되었다", Toast.LENGTH_SHORT).show()
        }
    }

    // 1
    fun showCameraPreview() {
        Log.d(TAG, "showCameraPreview")

        // 권한 체크하기
        if (ContextCompat.checkSelfPermission(this@WelcomeActivity, Manifest.permission.CAMERA) ==
            PackageManager.PERMISSION_GRANTED
        ) {
            // 권한이 있을 때 카메라 실행하기
            Toast.makeText(this, "카메라 허가 가능, 프리뷰 시작", Toast.LENGTH_SHORT).show()
            startCamera()
        } else {
            // 권한이 없을 때 권한 요청하기
            requestCameraPermission()
        }
    }


    private fun requestCameraPermission() {
        Log.d(TAG, "requestCameraPermission()")

        if (ActivityCompat.shouldShowRequestPermissionRationale(
                this@WelcomeActivity,
                Manifest.permission.CAMERA
            )
        ) {
            Toast.makeText(this@WelcomeActivity, "카메라 권한이 요구됩니다", Toast.LENGTH_SHORT).show()
            ActivityCompat.requestPermissions(
                this@WelcomeActivity,
                arrayOf(Manifest.permission.CAMERA),
                PERMISSION_REQUEST_CAMERA
            )
        } else {
            // 다시 묻지 않음을 누르고 거부하고 요청했을 때
            Toast.makeText(this@WelcomeActivity, "카메라 허가를 받을 수 없습니다.", Toast.LENGTH_SHORT).show()
            ActivityCompat.requestPermissions(
                this@WelcomeActivity,
                arrayOf(Manifest.permission.CAMERA),
                PERMISSION_REQUEST_CAMERA
            )
        }
    }

    private fun startCamera() {
        Log.d(TAG, "startCamera()")
        Intent(this@WelcomeActivity, CameraPreviewActivity::class.java).let {
            startActivity(it)
        }
    }
}

'Android' 카테고리의 다른 글

[Kotlin] 안드로이드 권한 - 1  (0) 2019.09.30
[Design] Material Design  (0) 2019.08.18
[Kotlin] Room Library  (0) 2019.08.17
Jetpack, AndroidX  (0) 2019.07.30
Singleton, MVC, MVP, MVVM 한 눈에 보기  (0) 2019.07.18

시간복잡도란 무엇일까요?

점근적 실행시간, 또는 big-O 시간에 대한 개념 이라고 말을 합니다. 예를 들어 데이터 전송 '알고리즘'의 실행시간을 예를 들어 보겠습니다.

온라인 전송 : O(s). 여기서 s는 파일의 크기가 된다. 즉, 파일의 크기가 증대함에 따라 전송 시간 또한 선형적으로 증가합니다.

비행기를 통한 전송 : O(1). 파일 크기에 관계없이 파일을 전송하는데 걸리는 시간이 늘어나지 않는다. 즉, 상수 시간만큼 소요된다.

간단하게 그래프로 그려 보겠습니다.

파랑 : O(1), 빨강 : O(s)

시간복잡도를 구할 때 기억할 것

  • 상수항은 무시하라
  • 지배적이지 않은 항은 무시하라

상수항은 무시하라

만든 알고리즘의 시간 복잡도가 4N+100000라는 시간이 걸린다고 생각해보자. N값의 따라 걸리는 시간이 달라진다. N의 값이 점점 커지고 여러분이 상상하는 가장 큰 숫자가 된다고 생각해보자. 뒤에 상수항은 그 숫자에 얼마나 큰 영향을 주게 되나요?

지배적이지 않은 항은 무시하라

이번에 만든 알고리즘의 시간복잡도는 N2 + N + 1000000 의 시간이 걸린다고 생각해보자. 이번에도 N의 값을 계속해서 키워나갈 때, N2의 값, N의 값, 1000000 들의 변화를 살펴보자. N2값에 비하면 N은 상수항과 비슷한 느낌을 받는다. 즉, N2값에 따라 이 알고리즘이 걸리는 시간이 결정된다. 그러므로 이 알고리즘을 big-O표기법을 사용해 표현하면 O(n2)의 시간복잡도를 가진다고 말할 수 있다.

덧셈 vs 곱셈

덧셈 수행시간 : O(A + B)

1
2
3
4
5
6
7
for(int a : arrA) {
    print(a);
}
 
for(int b : arrB) {
    print(b);
}

곰셈 수행시간 (A * B)

1
2
3
4
5
for(int a : arrA) {
    for(int b : arrB) {
        print(a + "," + b);
    }
}

알고리즘이 두 단계로 이루어져 있다고 가정하자. 어떤 경우에 수행 시간을 곱하고 어떤 경우에 더해야 할까?

  • 만약 알고리즘이 "A 일을 모두 끝마친 후에 B일을 수행"하는 형태라면 A와 B의 수행시간을 더해야한다.
  • 만약 알고리즘이 "A 일을 할 때마다 B일을 수행"하는 형태라면 A와 B의 수행시간을 곱해야 한다.

log N 수행시간

O(logN) 수행 시간을 자주 접할텐데 이 수행 시간은 어떻게 구해진걸까?

binary search(이진 탐색)을 생각해보자. 이진 탐색은 N개의 정렬된 원소가 들어있는 배열에서 원소 x를 찾을 때 사용된다. 먼저 원소 x와 배열의 중간값을 비교한다. 'x==중간값'을 만족하면 반환한다. 'x < 중간값'일 때는 배열의 왼쪽 부분을 재탐색하고 'x > 중간값'일 경우에는 배열의 오른쪽 부분을 재탐색한다.

처음에는 N개가 들어있는 배열에서 시작한다. 한 단계가 지나면 탐색해야할 원소의 개수가 N/2로 줄어들고, 다음 단계에서는 N/4로 줄어든다. 그러다 원소를 찾거나 탐색할 원소 1개가 남으면 탐색을 중지한다.

시작 N이 16이라고 가정하고 정리하면,

N = 16

N = 8

N = 4

N = 2

N = 1 의 결과로 원하는 x를 찾을 수 있다.

반대로 16에서 1로 증가하는 순서로 생각해보면 1에 2를 몇번이나 곱해야 할까?

N = 1

N = 2

N = 4

N = 8

N = 16 약, 4번 2를 곱하고 결과 값을 얻을 수 있다.

즉 2k = N을 만족하는 k는 무엇인가? 이때 사용되는 것이 바로 로그(log)이다.

2k = N  ▶  log216 = 4  ▶  4

log2N = k  ▶ 2k = N

 

어떤 문제에서 원소의 개수가 절반씩 줄어든다면 그 문제의 수행 시간은 O(logN)이 될 가능성이 크다. 로그의 밑은 고려하지 않아도 된다. 밑이 다른 로그는 오직 상수항만큼만 차이가 나는데 위에서 언급했듯이 상수항은 영향이 크지 않다. 표현할 때도 logN으로 표현되며, 로그의 밑은 무시해도 된다.

 

재귀적으로 수행시간 구하기

1
2
3
4
5
6
int f(int n) {
    if (n <= 1) {
        return 1;
    }
return f(n -1) + f(n - 1);
}

재귀 함수의 수행시간은 어떻게 구해야할까? 함수 f가 두 번 호출된 것을 보고 성급하게 O(N2)이라고 결론 내린 사람은 다시 생각해보자. 수행 시간을 추측하지 말고 코드를 하나씩 읽어 나가면서 수행 시간을 계산해 보자. n = 4라고 가정하자.

f(4)는 f(3)을 두번 호출한다.

  • f(4) : f(3), f(3)

f(3)은 f(2)를 두번 호출하며 f(3)은 2개가 있다.

  • f(3) : f(2), f(2)    *  2

f(2)는 f(1)을 두번 호출하며 f(2)는 4개가 있다.

  • f(2) : f(1), f(1)    *  4

총 호출 횟수는 몇 개인가? 일일이 세지 말고 계산해보자!

f(4)

f(3)                                     f(3)

       f(2)            f(2)                   f(2)               f(2)     

 f(1)    (f1)    f(1)    f(1)           f(1)    f(1)    f(1)    f(1)

트리의 형태로 표현하면 위와 같다. 트리의 깊이가 N이고, 각 노드는 두개의 자식 노드를 갖고 있다. 따라서 깊이가 한 단계 깊어질 때마다 이전보다 두 배 더 많이 호출하게 된다. 같은 높이에 있는노드의 개수를 세어 보자.

깊이 노드의 개수 다른 표현방식 또 다른 표현방식
0 1   20
1 2 2 * 2이전 깊이 = 2 21
2 4 2 * 2이전 깊이 = 2 * 21=22 22
3 8 2 * 2이전 깊이= 2 * 22=23 23

따라서 전체 노드의 개수는 20 + 21 + 2 2 + ... + 2N(=2N+1-1)이 된다. 이 패턴을 기억하길 바란다. 다수의 호출로 이루어진 재귀 함수에서 수행시간은 보통 O(분기깊이)로 표현되곤 한다. 여기서 분기란 재귀 함수가 자신을 재호출하는 횟수를 뜻한다. 따라서 예제의 경우에 수행 시간은 O(2n)이 된다.

앞에서 언급했는데 로그의 밑은 상수항으로 취급되기 때문에 big-O표기법에서 로그의 밑은 무시해도 된다고 했었다. 하지만 지수에서는 얘기가 달라진다. 지수의 밑은 무시하면 안된다. 간단한 예로 2n과 8n을 비교해보자.

8n은 2(3)n = 23n = 22n*2n 으로 표현할 수 있다. 8n은 2n에 22n을 곱한 것과 같으므로 2n과 8n사이에는 22n만큼의 차이가 있다. 이 차이는 지수항이므로상수항과는 아주 큰 차이가 있다.

 

처음에는 big-O 시간이라는 개념이 어렵게 느껴질 수 있다. 하지만 한번 이해하면 꽤 쉽게 받아들일 수 있으니 다른 코드나 자신이 만든 코드의 시간 복잡도가 어떻게 되는지 위와 같이 계산해보길 바란다.

오메가 : 최선의 시간을 고려
세타 : 평균의 시간을 고려
오 : 최악의 시간을 고려 (세타를 O(오)로 통합해 표현하기도 합니다)

'Algorightm' 카테고리의 다른 글

[Kotlin] 387.First Unique Character in a String [LeetCode]  (0) 2020.05.12
[Kotlin] 344.ReverseString [LeetCode]  (0) 2020.04.28
[Level1] 완주하지 못한 선수  (0) 2019.10.24
Hash Algorithm  (0) 2019.10.14

Java CMD에서 클리어하기


1
2
3
4
5
final String os = System.getProperty("os.name");
if(os.contains("Windows"))
    new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
else
    Runtime.getRuntime().exec("clear");
cs

CMD화면에서 자바프로그램을 실행했을 때 화면을 새롭게 지우고 싶으면 위의 코드를 삽입하면 됩니다.



'Language > Java' 카테고리의 다른 글

1. 자바 입력버퍼 오류  (0) 2019.02.03

문제) nextInt() 사용 후 입력이 제대로 되지 않는 문제를 확인


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
    
    boolean loop = true;
    Scanner sc = new Scanner(System.in);
    int number;
    
    while(loop) {
        System.out.print("숫자입력:");
        try {
            number = sc.nextInt();
 
            if(number == 0) {
                loop = false;
            }
        } catch (Exception e) {
        }
    }
}

cs

문제 발생 이유) nextInt()로 입력을 받을시 입력한 숫자까지만 입력을 받게되서 다음에 입력할 때 문제가 발생하게 된다.


해결 방법)  nextLine()을 삽입해서 Scanner의 입력버퍼를 한번 비워주도록 만들었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {
    
    boolean loop = true;
    Scanner sc = new Scanner(System.in);
    int number;
    
    while(loop) {
        System.out.print("숫자입력:");
        try {
            number = sc.nextInt();
 
            if(number == 0) {
                loop = false;
            }
        } catch (Exception e) {
            sc.nextLine();
        }
    }
}
cs


'Language > Java' 카테고리의 다른 글

2. Java CMD Clear  (0) 2019.02.03

이름 

단축키 

 파일 불러오기

Ctrl + I

 되돌리기 

Ctrl + Z 

 편집기준선에 맞춰 자르기

Ctrl + K 

빈 공백 지우기

(잔물결 삭제, Ripple Delete)

Shift + Delete

삭제하기 

Delete 

+ 키

타임라인 패널 확대 

 - 키 

타임라인 패널 축소 

 Mark In

I

Mark Out

O

 역재생 (JJ 2배속, JJJ 3배속)

J

 정지 

K

 재생 (LL 2배속, LLL 3배속)

Mark In 제거

Ctrl + I 

Mark Out 제거

Ctrl + O

 Mark In, Out 모두제거

Ctrl + Shift + X

Mark In ~ Mark Out 구간 실행 

Ctrl + Shift + Space bar 

삽입 (Insert)

 ,(쉼표)

덮어쓰기 (Overwrite)

.(마침표) 



오늘은 간단하게 태그들과 태그에서 사용할 수 있는 속성들을 살펴보도록 하겠습니다.



  • <body> : 웹페이지의 내용물들이 위치하는 태그
    <Body 속성="속성값" 속성="속성값">

                 웹 페이지 내용물
    </body>
  •  속성

    설명 

     TOPMARGIN="수치"

     상단 여백 지정 (수치의 단위는 픽셀) 

     LEFTMARGIN="수치"

     왼쪽 여백 지정 (수치의 단위는 픽셀)

     BACKGROUND="주소"

     배경 이미지 지정

     BGCOLOR="색상" 

     배경 색상 지정 (색상은 16진수의 6자리이거나 )

     TEXT="색상"

     글자 색상 지정 (특정 색상 지정 )     ex) TEXT="#ff00ff" or TEXT="red"

     LINK="색상"

     하이퍼 링크 색상 지정

     ALINK="색상" 

     하이퍼 링크를 마우스로 클릭할 때 색상 지정 (누르고 있으면 색상을 확인해 볼 수 있다)

     VLINK="색상" 

     이미 방문한 링크의 색상 지정


  • <!--   내용  --> : 주석처리하고 싶은 내용을 <!--       안쪽에 써주면 인식하지 못합니다        --> 

  • <font> : 글씨의 크기, 색상 글꼴 지정
  •  속성

    설명 

    SIZE="수치" 

    글자 크기 지정  ( 수치 범위 : 1~7 ,  Default : 3)

    COLOR="색상" 

    글자 색상 지정 

    FACE="글꼴" 

    글꼴 종류 지정 


  • <br> : 줄 바꾸기 (line break),  보통 글을 작성할 때 Enter친 것과 같은 효과입니다.
    내용 <br>

  • <p> : 단락(Paragraph)을 구분합니다.
        <p 속성="값">  내용 </p>
    <pre> : 작성한 형식을 그대로 유지합니다.
        <pre 속성="값"> 내용 </pre>
  •  속성

    설명 

    ALIGN 

     정렬시킵니다





'Language > Javascript' 카테고리의 다른 글

7.javascript배열  (0) 2017.09.22
6.javascript 반복문  (0) 2017.09.22
5.javascript객체  (0) 2017.09.22
3.javascript 조건문  (0) 2017.09.19
2.Javascript 연산자  (0) 2017.09.19

이번에는 배열에 대해서 알아보겠습니다.


배열(Array)은 많은 데이터를 순번을 가지고 저장할 때 사용됩니다. 배열에는 원소라는 index번호를 할당받은 저장소가 있으며, 배열의 원소에 index로 접근하여 할당된 값을 읽어 올 수 있습니다. 많은 양의 데이터를 보관해야 할 때 배열을 사용하면 효율적으로 데이터를 관리할 수 있습니다. 


배열 생성

배열은 객체의 생성 방법과 유사합니다. 그럼 배열의 생성방법을 보겠습니다.

1
2
var arr = [];
var arr = new Array();
cs


배열 원소에 값을 할당하기

배열 원소의 index를 통해서 값을 할당해 주거나 배열을 생성하면서 동시에 값을 할당하는 것도 가능합니다. 

배열을 생성하고 값 넣기

1번 라인에서 []배열을 생성시켜 변수 fruits에 할당합니다. 그리고 변수 fruits를 통해서 배열의 원소 0~2index에 값을 각각 할당합니다. 

배열의 index는 0부터 시작하기 때문에 2번 라인에서 index0 에 값을 할당했습니다.

1
2
3
4
var fruits = [];
fruits[0] = "사과";
fruits[1] = "배";
fruits[2] = "바나나";
cs


배열을 생성하면서 값 넣기

1
var fruits = ["사과", "배", "바나나"];
cs

위의 두개의 배열의 값은 같습니다. 


fruits배열

  fruits[0]

  fruits[1]

 fruits[2] 

 사과

배 

바나나 


배열 원소의 값과 원소 갯수 얻어오기


1번 라인에서 배열을 생성해 주었고, 2번 라인에서 index 0에 해당하는 원소를 읽어왔습니다. 그리고 3번라인에서 length프로퍼티로 원소의 갯수를 변수 len에 할당하고 document에 출력합니다.

1
2
3
4
5
var fruits = ["사과", "배", "바나나"];
var apple = fruits[0];
var len = fruits.length;
document.write(apple);
document.write(len);
cs




'Language > Javascript' 카테고리의 다른 글

HTML 태그 설명  (0) 2018.03.12
6.javascript 반복문  (0) 2017.09.22
5.javascript객체  (0) 2017.09.22
3.javascript 조건문  (0) 2017.09.19
2.Javascript 연산자  (0) 2017.09.19

+ Recent posts