차근차근/Android

@font-face ,Android webview 에서 로컬 리소스 접근하기

예쁜꽃이피었으면 2015. 1. 29. 11:37

http://action713.tistory.com/943


http://action713.tistory.com/944


http://action713.tistory.com/945




Android webview 에서 로컬 리소스 접근하기


http://wiki.lizzardry.com/wiki/Android_webview_%EC%97%90%EC%84%9C_%EB%A1%9C%EC%BB%AC_%EB%A6%AC%EC%86%8C%EC%8A%A4_%EC%A0%91%EA%B7%BC%ED%95%98%EA%B8%B0#cite_note-0



안드로이드 웹뷰에서 외부 폰트를 적용하는 부분은 크게 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 를 받는 패키지를 새로 추가하려고 했으나 역시 구글님, 단번에 해결책을 준다.

[nanohttpd]

일단 클래스 파일 한개로 되어 있어서 프로젝트의 구조를 바꿀 필요도 없이 추가가 가능하고, 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]

참고

  1. webViewer.loadDataWithBaseURL("file:///android_asset/", body, "text/html", "UTF-8", null) 와 같이...
  2.  보안상 문제
  3.  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를 삽입 할 수 있다.

[편집]참조

  1. ↑ 1.0 1.1 @font-face 크로스 브라우저 이슈정보: Webfonts.info[1]


반응형

'차근차근 > Android' 카테고리의 다른 글

viewpager  (0) 2015.02.02
actionbar  (0) 2015.02.02
앱 폰트 웹에서 사용, 하이브리드 앱 , 웹뷰  (0) 2015.01.29
웹뷰 폰트 적용하기  (0) 2015.01.29
안드로이드 폰트 변경  (0) 2015.01.29