스마트폰 OS인 Android에서 Hybrid App 관련 사항을 정리 한다.


하이브리드 앱


제가 생각하는 하이브리드 앱은 모바일 앱과 모바일 웹(HTML5)이 서로의 장점을 살려서 모바일 환경을 더욱 풍요롭게 하는 것을 의미 합니다. Android에서는 하이브리드 앱을 구현하기 위해서 WebView를 사용 합니다.


권한 설정


  • AndroidManifest.xml
    
    
    


화면 설정


  • /res/layout/~.xml


Web 화면


  • HTML Page

    • ratio : 0.75, 1.0, 1.5
      
      

    ```


    ==Activity 구현==
  • Activity

    private WebView browser = null;
    private Activity activity = null;
    
    public void onCreate(Bundle savedInstanceState)
    { 
       WebSettings setting = null;
    
       super.onCreate(savedInstanceState);
       setContentView(R.layout.smarthybrid);
    
       activity = this;
       browser = (WebView) findViewById(R.id.website);
       setting = browser.getSettings();
       setting.setJavaScriptEnabled(true);
       browser.setWebViewClient(new ProxyWebViewClient());
       browser.setWebChromeClient(new ProxyWebChromeClient());
    
       //--- 프로젝트의 /assets 폴더에 test.html 파일을 추가
       //--- browser.loadUrl("file:///android_asset/test.html");
       //--- browser.loadData("한글", "text/html", "utf-8");
       browser.loadUrl(website);
       //--- byte[](.md) post = EncodingUtils.getBytes("a=b&c=d&e=f", "BASE64");
       //--- browser.postUrl("http://example.com/myform/", post);
    }
    
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
       if ((keyCode == KeyEvent.KEYCODE_BACK) && browser.canGoBack()) { 
           browser.goBack(); 
           return true; 
       } 
       return super.onKeyDown(keyCode, event);
    }
    
    private class ProxyWebViewClient extends WebViewClient {
       public boolean shouldOverrideUrlLoading(WebView view, String url) {
           if (url.startsWith("tel:")) {
               Intent i = new Intent(Intent.ACTION_CALL, Uri.parse(url));
               startActivity(i);
          } else {
               view.loadUrl(url);
          }
          return true;
       }
    
       public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
           Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show();
       }
    }
    
    private class ProxyWebChromeClient extends WebChromeClient {
       public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
           Toast.makeText(activity, message, 3000).show();
           result.confirm();
           return true;
       }
    }

  • WebView에서 HTML5 사용을 위한 WebSettings 설정

          WebSettings setting = null;
    
          browser = (WebView) findViewById(R.id.website);
          setting = browser.getSettings();
          setting.setJavaScriptEnabled(true);        //--- JavaScript 허용
          setting.setGeolocationEnabled(true);    //--- 위치 정보 사용 허용
          setting.setJavaScriptCanOpenWindowsAutomatically(true); 
          setting.setLoadsImagesAutomatically(true);
          setting.setPluginsEnabled(true);
          setting.setLightTouchEnabled(true); 
          setting.setSupportZoom(true);
          setting.setBuiltInZoomControls(true);
    
          //--- HTML5에서 Database를 설정 한다. 
          setting.setDatabaseEnabled(true);        //--- HTML5에서 Database 허용
          //--- Database를 위해 WebChromeClient.onExceededDatabaseQuota(~) 함수도 같이 설정할 것
          setting.setDatabasePath("/data/data/com.jopenbusiness.android.smarthybrid/database");
    
          //--- HTML5에서 DOM Storage를 설정 한다.
          setting.setDomStorageEnabled(true);        //--- HTML5 DOM Storage 허용
        
    //--- HTML5에서 Cache 설정을 한다. //--- Database를 위해 WebChromeClient.onReachedMaxAppCacheSize(~) 함수도 같이 설정할 것 setting.setAppCacheMaxSize(1024 * 1024 * 8); //--- Default Cache Size를 8 MB로 설정 setting.setAppCachePath("/data/data/com.jopenbusiness.android.smarthybrid/cache"); setting.setAppCacheEnabled(true); setting.setAllowFileAccess(true); setting.setCacheMode(WebSettings.LOAD_DEFAULT);



  • Activity에서 Cookie 동기화 처리

    private WebView browser = null;
    
    public void onCreate(Bundle savedInstanceState)
    { 
       CookieSyncManager.createInstance(this);
    }
    
    public void onStart() { 
       super.onStart(); 
    
       browser = (WebView) findViewById(R.id.website);
       browser.setWebViewClient(new ProxyWebViewClient());
       CookieSyncManager.createInstance(this);
    }
    protected void onResume() { super.onResume(); CookieSyncManager.getInstance().startSync(); } protected void onPause() { super.onPause(); CookieSyncManager.getInstance().stopSync(); } private class ProxyWebViewClient extends WebViewClient { public void onPageFinished(WebView view, String url) { CookieSyncManager.getInstance().sync(); } }


Progress Bar 표시


앱의 타이틀바에 웹페이지 로딩 진행 상태(Progress Bar)를 표시 한다.

  • Activity에 다음을 추가 한다.

    private WebView browser = null;
    private Activity activity = null;
    
    public void onCreate(Bundle savedInstanceState)
    { 
       super.onCreate(savedInstanceState);
       //--- setContentView(~) 앞에 다음 라인을 추가 한다.
       getWindow().requestWindowFeature(Window.FEATURE_PROGRESS);       
    setContentView(R.layout.main); activity = this; this.setTitle("앱 타이틀"); browser = (WebView) findViewById(R.id.website); browser.setWebChromeClient(new ProxyWebChromeClient()); } public class ProxyWebChromeClient extends WebChromeClient { public void onProgressChanged(WebView view, int newProgress) { activity.setTitle("로딩 ..."); activity.setProgress(newProgress * 100); if (newProgress == 100) { activity.setTitle("앱 타이틀); } } }


앱과 웹의 통신


  • Activity에서 다음과 같이 구현 한다.

    import  android.os.Handler;
    
    private WebView browser = null; private final Handler handler = new Handler(); public void onCreate(Bundle savedInstanceState) { WebSettings setting = null; browser = (WebView) findViewById(R.id.website); setting = browser.getSettings(); setting.setJavaScriptEnabled(true); browser.addJavascriptInterface(new Hybrid(), "hybrid"); } private class Hybrid { public void setMessage(final String arg) { handler.post(new Runnable() { public void run() { Log.d("Hybrid", "setMessage("+arg+")"); mTextView.setText(arg); } }); } } //--- JavaScript에서 App 호출 window.hybrid.setMessage(msg); //--- App에서 JavaScript 호출 browser.loadUrl("javascript:setMessage('message')");


화면 회전 금지


  • WebView 화면이 회전되지 않도록 하려면, [화면 회전](Android_SDK.md#화면 회전.md)에서 "화면이 회전해도 Activity가 다시 로딩되지 않도록 하는 방법"을 참조 하세요.


WebView의 HTML5 지원


  • Android 2.2의 WebView의 HTML5 지원 점수
    그림:Android22 html5test.png

참고 문헌


공유하기