http://action713.tistory.com/943
http://action713.tistory.com/944
http://action713.tistory.com/945
Android webview 에서 로컬 리소스 접근하기
안드로이드 웹뷰에서 외부 폰트를 적용하는 부분은 크게 2가지로 나뉜다.
- 내부 로컬 html 에서 폰트 적용하기
- 외부 원격 html 에서 폰트 적용하기
전자의 경우는 별 문제 없이 file:///android_assetes 같은 형식으로 url 을 주면 쉽게 적용이 되지만, 후자의 경우는 구글링을 미친 듯이 해봐도 답이 나오지 않았다. 유일한 해결 방법은 원격지에 있는 html 파일을 로딩한 억지로 로컬 html 처럼 로딩하는 방법이였다[1].
사실 간단한 페이지의 경우 그냥 처리를 하면 되지만, ajax 같이 동적인 요소가 있는 부분에서는 인터넷 요청을 hook 해서 계속 새롭게다운로드->로컬 html->로딩 을 해줘야 하는데 WebViewClient 에서 api11 부터 새롭게 추가된 shouldInterceptRequest 와 같은 함수를 사용하지 못하는 상황이라서 어쩔 수 없이 12MB 나 되는 폰트를 다운 받아야 하는 상황이였다.
첫번째로 고민한 부분이 전자와 같이 css 경로에 file:///android_assets 과 같은 방식으로 처리하면 되지 않을까 했지만, 웹뷰에서 로컬 리소스를 접근 할수 없다는 것을 알게되었다[2]. 결국 고민 고민하다 해결 하였다.
jetty 와 같은 경량 웹서버를 앱 내부에 띄워서 assets 경로에 있는 파일들을 제공하자
사실 jetty 와 같은 경량서버라고 해도 안드로이드에서는 돌리기가 부담되는 크기였다. 그래서 맨 처음은 http response 를 받는 패키지를 새로 추가하려고 했으나 역시 구글님, 단번에 해결책을 준다.
일단 클래스 파일 한개로 되어 있어서 프로젝트의 구조를 바꿀 필요도 없이 추가가 가능하고, jetty 보다 더 경량'스러워' 보여서 선택했다.
단순히 개념은 웹페이지에서 localhost:xxxx 로 요청하면 그 요청의 경로에 맞춰서 asset 폴더에 있는 파일들을 제공하면 된다.
몇 번의 테스트 끝에 결국은 jetty 모듈을 붙이기로 했다. 생각보다 nanohttpd 가 리소스를 적절히 보내주지 못해서 폰트가 사라지거나, css 가 로딩이 안되거나 js 파일을 못 주는 등의 문제가 종종 발생해서 jetty 로 울렸다.
staticfile 을 전송할 수 있게 이거저거 찾아가면서 코딩을 했다. 생각보다 무겁지도 않고 일단 로컬에서 access control 도 가능하니 생각보다 보안 문제도 좋아졌다. 제일 큰 문제는 port 번호 잡는 부분 정도?
추가적으로 메인 쓰레드 대신 service 로 등록해서 실행을 해서 어플리케이션이 처리할 부분을 줄여줬다. nexus one 에서도 잘 돌아가니 그럭저럭 큰 문제가 없으면 사용 가능 할것 같다.
public class StaticFileServer extends NanoHTTPD { private Context context; public StaticFileServer(int port, Context context) { super(port); this.context = context; } @Override public Response serve(IHTTPSession session) { try { String file_url = session.getUri(); String file_path = file_url.substring(1, file_url.length()); InputStream fis = null; AssetManager assetManager = context.getAssets(); fis = assetManager.open(file_path); return new NanoHTTPD.Response(Status.OK, getMimeType(file_path), fis); } catch (IOException e) { return new NanoHTTPD.Response(e.toString()); } } public void closeServer() { if (StaticContext.staticFileServer != null) { StaticContext.staticFileServer.stop(); } } private String getExtension(String path) { String[] splited_text = path.split("\\."); return splited_text[splited_text.length - 1]; } private String getMimeType(String path) { String extention = getExtension(path); if ("js".equals(extention)) return "text/javascript"; else if ("css".equals(extention)) return "text/css"; else if ("png".equals(extention)) return "image/png"; else if ("otf".equals(extention)) return "application/x-font-otf"; else return ""; } }
간단한 클래스로 assets 폴더 밑에 있는 파일들을 쉽게 읽어올수 있다.
장 단점
장점으로는
- 기존에 있는 레거시 css/js/html 에서 요청 url 만 바꿔주면 간단하게 사용이 가능하다
- 넥서스원에서도 아직까지는 큰 문제 없이 잘 돌아갔다
- 웹뷰 소스코드의 수정이 없어서 변화를 최소화 시킬 수 있다
- 멋있다
단점으로는
- 일단 웹서버가 뜨니 약간 뭔가 무거워 보인다
로컬 파일들을 외부 디바이스에서도 접근을 할수 있다[3]
참고
- ↑webViewer.loadDataWithBaseURL("file:///android_asset/", body, "text/html", "UTF-8", null) 와 같이...
- ↑ 보안상 문제
- ↑
access control? 등등을 사용하면 될듯jetty 는 그냥 설정만 해주면 바로 되네
@font-face
http://eclipse.or.kr/wiki/@font-face
웹 페이지에 사용자 정의 폰트를 삽입할 수 있는 CSS 셀렉터 룰. CSS 폰트 모듈 레벨3에 속하며, 통칭 웹폰트로 회자된다.
목차[숨기기] |
[편집]문법
@font-face { font-family: '사용자폰트명'; src: 폰트 소스(, 폰트 소스)*; (font-style: 폰트 스타일;)? (font-weight: 폰트 두께;)? (unicode-range: 캐릭터 범위;)? }
[편집]사용자 폰트명
사용자 폰트명은 나중에 이 폰트를 사용할 때 다른 css 셀렉터 룰에서 사용할 폰트 이름을 의미한다.
[편집]폰트 소스
폰트를 얻는 방법을 기술한다.
local("로컬 운영체제에 등록된 폰트 이름") | url ("폰트 파일의 URL") format("폰트파일의 포맷")
폰트 소스는 ','(콤마)를 구분자로 하여 여러개가 지정될 수 있으며, 앞쪽이 우선순위를 갖는다. 로컬 폰트 소스는 사용자의 PC에 이미 폰트가 등록된 경우 불필요하게 폰트를 다운로드 받는 것을 방지한다.
format 지정자 및 로컬 폰트 소스는 IE에서는 사용할 수 없다[1]
[편집]예제
NanumGothic.ttf 와 NanumGothicBold.ttf 두개의 폰트파일을 "기본글꼴" 이라는 하나의 폰트로 정의하는 방법:
@font-face { font-family: "기본글꼴"; src: local("나눔고딕"), url("fonts/NanumGothic.ttf") format("truetype"); font-weight: regular; } @font-face { font-family: "기본글꼴"; src: local("나눔고딕"), url("fonts/NanumGothicBold.ttf") format("truetype"); font-weight: bold; } /* NanumGothic.ttf 가 적용됨 */ body{ font-family: 기본글꼴; } /* NanumGothicBold.ttf 가 적용됨 */ .bold{ font-family: 기본글꼴; font-weight: bold; }
[편집]크로스 브라우저 이슈
브라우저마다 지원하는 폰트의 포맷이 조금씩 다르기 때문[1]에 사용에 주의해야 한다. 특히 IE의 경우 9.0이 WOFF를 지원하는 것을 제외하고 EOT 포맷만을 지원한다.
브라우저별로 별도의 CSS가 삽입되도록 서버 스크립트를 작성하거나, 서버 사이드 스크립트랄 사용할 수 없는 경우 IE의 조건부 주석을 이용하여 브라우저별로 다른 CSS를 삽입 할 수 있다.
[편집]참조
'차근차근 > Android' 카테고리의 다른 글
viewpager (0) | 2015.02.02 |
---|---|
actionbar (0) | 2015.02.02 |
앱 폰트 웹에서 사용, 하이브리드 앱 , 웹뷰 (0) | 2015.01.29 |
웹뷰 폰트 적용하기 (0) | 2015.01.29 |
안드로이드 폰트 변경 (0) | 2015.01.29 |