WebView 워크플로

게시일: 2014년 2월 28일

웹 개발의 장점 중 하나는 워크플로를 개선하는 데 사용할 수 있는 다양한 도구가 있다는 것입니다.

이러한 도구 중 하나의 예는 프로덕션용 빌드를 만들기 전에 Sass 컴파일 및 실시간 서버 시작에서 이미지 압축, JavaScript 축소, JSHint 실행에 이르기까지 웹 앱에서 실행할 태스크를 정의할 수 있는 JavaScript 태스크 런너인 Grunt입니다.

Yeoman은 웹 애플리케이션을 만들고, 불러오기 템플릿을 생성하고, Bowernpm에서 라이브러리를 가져오고, 사전 정의된 태스크가 포함된 Grunt 파일을 만드는 데 도움이 되는 도구입니다.

이 튜토리얼에서는 Yeoman을 사용하여 새 기본 웹 애플리케이션을 만든 다음 Android 스튜디오 빌드 시스템 (Gradle)을 Grunt와 통합하여 웹 애플리케이션을 빌드합니다. 또한 브라우저에서 애플리케이션을 테스트하기 위해 로컬 실시간 리로드 서버를 실행하도록 Grunt 작업을 설정하여 HTML, CSS, JavaScript 파일을 변경할 때마다 페이지를 수동으로 새로고침하지 않아도 됩니다.

기본 요건

시작하기 전에 몇 가지 기본 요건을 설치해야 합니다.

  1. Yeoman 설치: https://github.com/yeoman/yeoman/wiki/Getting-Started
  2. Android 스튜디오 설치: https://developer.android.com/sdk/installing/studio.html

1단계: Android 스튜디오에서 WebView를 사용하여 새 프로젝트 만들기

방법에 관한 자세한 안내는 시작 가이드에서 확인하세요.

2단계: 웹 앱 콘텐츠의 하위 디렉터리 만들기

프로젝트를 만든 후 새 최상위 디렉터리를 만듭니다. Android 스튜디오에서 프로젝트 폴더를 마우스 오른쪽 버튼으로 클릭하고 새로 만들기 > 디렉터리를 선택합니다.

디렉터리 이름을 webapp로 지정합니다.

3단계: 새 디렉터리에 Yeoman 프로젝트 만들기

터미널에서 cd를 프로젝트의 webapp 디렉터리로 이동합니다.

cd <path-to-project>/webapp/

그런 다음 Yeoman으로 새 웹 앱을 만듭니다.

yo webapp

화면에 표시되는 안내에 따라 프로젝트 옵션을 선택합니다. 머신에 npm이 설치된 방식에 따라 sudo npm install를 실행해야 할 수도 있습니다.

다음 단계로 진행하기 전에 다음 명령어를 실행하여 앱을 테스트합니다.

grunt server

브라우저에 새 탭이 열리고 Grunt에서 시작한 로컬 서버에 연결됩니다. 프로젝트에서 HTML, CSS 또는 JavaScript 파일 중 하나를 변경하면 페이지가 자동으로 새로고침되고 업데이트됩니다.

grunt build를 실행하면 새 디렉터리 dist가 생성되고 웹 앱이 압축, 최적화되어 이 폴더 내에 프로덕션 버전으로 만들어집니다.

4단계: Gradle 빌드 구성

webapp 디렉터리에서 build.gradle이라는 새 파일을 만듭니다.

build.gradle 파일에 다음을 추가합니다.

import org.apache.tools.ant.taskdefs.condition.Os

task buildWebApp(type: Exec) {
  executable = Os.isFamily(Os.FAMILY_WINDOWS) ? "grunt.cmd" : "grunt"
  args = ["build"]
}

그러면 사전 정의된 유형 Exec으로 buildWebApp라는 새 작업이 생성됩니다. 그런 다음 Execexecutable 변수를 현재 OS에 따라 관련 grunt 명령어로 설정합니다. args"build"로 설정되어 명령줄에서 grunt build가 실행되는 것과 같습니다. 마지막으로 상단의 가져오기는 Os.isFamily(Os.FAMILY_WINDOWS)를 사용하는 것입니다.

이 새 작업을 사용하려면 프로젝트에서 새 build.gradle 파일을 인식하도록 해야 합니다.

루트 디렉터리에서 settings.gradle을 열고 다음 줄을 추가합니다.

include ':webapp'

5단계: Android 앱을 빌드할 때 웹 앱 빌드

웹 앱을 빌드한 다음 앱을 Android 앱의 assets 디렉터리에 복사합니다.

다음을 Android 앱 build.gradle 파일에 복사합니다.

task copyWebApplication(type: Copy) {
  from '../webapp/dist'
  into 'src/main/assets/www'
}

task deleteWebApplication(type: Delete) {
  delete 'src/main/assets/www'
}

copyWebApplication.dependsOn ':webapp:buildWebApp'
copyWebApplication.dependsOn deleteWebApplication

android.applicationVariants.all { variant ->
  tasks.getByPath(":${project.name}:assemble${variant.buildType.name.capitalize()}").dependsOn copyWebApplication
}

각 부분을 살펴보겠습니다.

작업 copyWebApplication

task copyWebApplication(type: Copy) {
  from '../webapp/dist'
  into 'src/main/assets/www'
}

Copy 태스크는 webapp/dist 디렉터리에서 애플리케이션을 복사합니다. 파일을 src/main/assets/www에 복사하려고 합니다. 또한 이 작업은 필요한 디렉터리가 없는 경우 필요한 파일 구조를 만듭니다.

task deleteWebApplication

task deleteWebApplication(type: Delete) {
  delete 'src/main/assets/www'
}

이 삭제 작업은 assets/www 디렉터리의 모든 파일을 삭제합니다.

copyWebApplication.dependsOn

copyWebApplication.dependsOn ':webapp:buildWebApp'
copyWebApplication.dependsOn deleteWebApplication

첫 번째 줄은 copyWebApplication에 웹 앱의 build.gradle 파일에서 buildWebApp 작업에 대한 종속 항목이 있음을 나타냅니다.

두 번째 줄은 deleteWebApplication 작업에 종속 항목이 있음을 나타냅니다.

즉, 파일을 실제로 assets 디렉터리에 복사하기 전에 웹 앱을 빌드하고 assets 디렉터리의 현재 콘텐츠를 삭제해야 합니다.

android.applicationVariants.all

android.applicationVariants.all { variant ->
  tasks.getByPath(":${project.name}:assemble${variant.buildType.name.capitalize()}").dependsOn copyWebApplication
}

이 태스크는 앱의 각 버전에 대해 모든 프로젝트 빌드의 종속 항목을 지정합니다. 여기서는 copyWebApplication를 실행하는 assemble 태스크에 종속 항목을 설정합니다.

assemble 작업은 프로젝트의 출력을 조합하므로 먼저 웹 앱을 Android 프로젝트에 복사해야 합니다.

6단계: 모든 것이 작동하는지 확인

Android 스튜디오의 Android 애플리케이션 src 폴더에는 assets 디렉터리가 없어야 합니다.

index.html 페이지를 사용하도록 WebView를 설정합니다.

mWebView.loadUrl("file:///android_asset/www/index.html");

Run을 클릭하고 애플리케이션을 빌드합니다. www 하위 디렉터리에 웹 애플리케이션이 포함된 assets 디렉터리가 표시됩니다.

7단계: 실시간 서버 및 실시간 리로드 만들기

실시간 리로드는 웹 애플리케이션을 빠르게 변경하는 데 매우 유용합니다. 이를 사용 설정하려면 앱에 두 가지 '제품 버전'을 만들 수 있습니다. 라이브 서버 버전과 웹 콘텐츠가 Android 애플리케이션에 패키징된 정적 버전입니다.

Android 앱의 build.gradle에서 android 요소 끝에 다음 줄을 추가합니다.

android {
  ...
  defaultConfig {
    ...
  }
  productFlavors {
    staticbuild {
      packageName "com.google.chrome.myapplication"
    }

    liveserver {
      packageName "com.google.chrome.myapplication.liveserver"
    }
  }

}

이제 Gradle에서 라이브서버 패키지 이름으로 앱 버전을 만들고 일반 패키지 이름으로 앱 버전을 만들 수 있습니다. 동기화가 완료되었는지 확인하려면 Run 버튼 옆에 있는 상단 표시줄에서 Sync Project with Gradle Files를 클릭합니다.

그런 다음 Android 스튜디오의 왼쪽 하단에 있는 Build Variants를 확인합니다. 이 창에는 기본적으로 빌드할 수 있는 앱 버전이 표시됩니다.

productFlavor에는 디버그출시 버전이 있으며 Gradle용 Android 플러그인에서 기본적으로 제공합니다. 이 값에 따라 빌드가 디버그 빌드인지 아니면 Play 스토어에 배포하는 데 적합한 출시 빌드인지 결정됩니다.

이제 두 가지 버전이 있지만 아직 실제로는 다른 작업을 하지 않습니다.

8단계: 실시간 서버에서 로드

이제 빌드하는 제품 버전에 따라 다른 URL을 로드하도록 애플리케이션을 구성합니다.

Android 애플리케이션에서 모든 제품 버전에 공통적인 파일은 src/main에 있습니다. 하나의 제품 버전에만 해당하는 코드나 리소스를 추가하려면 src 아래에 productFlavor와 동일한 이름의 디렉터리를 만듭니다. 해당 빌드 변형을 빌드하면 Gradle 및 Android 플러그인이 src/main의 파일 위에 이러한 추가 파일을 병합합니다.

URL을 문자열 리소스로 정의하고 코드에서 하드코딩된 URL 대신 이 리소스를 사용합니다.

  1. src/liveserversrc/staticbuild 폴더를 만듭니다.

  2. liveserver 폴더에서 values라는 하위 폴더가 있는 res라는 새 폴더를 만듭니다. 이 안에 config.xml라는 파일을 만듭니다. staticbuild 폴더에 대해 이 프로세스를 반복합니다.

  3. 구성 파일 내에서 src/liveserver/res/values/config.xml에 다음 줄을 추가합니다.

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
      <string name="init_url">https://<Your Local Machine IP Address>:9000</string>
    </resources>
    

    src/staticbuild/res/values/config.xml에 다음 블록을 추가합니다.

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
      <string name="init_url">file:///android_asset/www/index.html</string>
    </resources>
    
  4. 이러한 구성 파일의 init_url를 사용하도록 WebView를 설정합니다.

    mWebView.loadUrl(getString(R.string.init_url));
    
  5. liveserver/AndroidManifest.xmlAndroidManifest.xml라는 새 파일을 만들고 다음 줄을 추가합니다.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="https://schemas.android.com/apk/res/android">
      <uses-permission android:name="android.permission.INTERNET" />
    </manifest>
    

    이렇게 하면 liveserver 빌드에 인터넷 권한이 추가됩니다.

  6. webapp/Gruntfile.js 내에서 다음을 찾습니다.

    connect: {
      options: {
        port: 9000,
        livereload: 35729,
        // change this to '0.0.0.0' to access the server from outside
        hostname: **'localhost'**
      },
      ...
    }
    

    로컬 네트워크에서 로컬 서버에 액세스할 수 있도록 localhost0.0.0.0로 바꿉니다.

    connect: {
      options: {
        port: 9000,
        livereload: 35729,
        // change this to '0.0.0.0' to access the server from outside
        hostname: '**0.0.0.0'**
      },
      ...
    }
    

변경사항을 테스트하려면 다음 단계를 따르세요.

  1. 실시간 서버를 시작합니다.

    grunt server
    
  2. Android 스튜디오의 Build Variant 선택에서 LiveserverDebug를 선택합니다. 그런 다음 실행을 클릭합니다.

    HTML, CSS, JavaScript 콘텐츠를 수정하면 브라우저에 즉시 반영됩니다.

이제 애플리케이션의 두 가지 버전이 있습니다. Grunt 서버에서 실시간으로 새로고침하는 개발 버전과 Android 앱에 로컬로 패키징된 정적 버전입니다.