SlideShare une entreprise Scribd logo
1  sur  44
The Principle of
  Hybrid App.
     @musart
The solutions is Hybrid App...
What is Hybrid App.?




       ?

                       : http://www.phonegap.com/
The type of Hybrid App.


• Run-time Hybrid App.
 • phonegap
 • appspresso
• Build-time Hybrid App.
 • titanium
Build-time vs. Run-time

JavaScript           JavaScript, CSS, html




     App.             WebView
    Graphic           Graphic
    Context           Context
Build-time vs. Run-time

       JavaScript           JavaScript, CSS, html


Convert JS to Java, Obj-C
     Package App.


             App.            WebView
            Graphic          Graphic
            Context          Context
Build-time vs. Run-time

       JavaScript            JavaScript, CSS, html


Convert JS to Java, Obj-C   Connect JS and Java, Obj-C
     Package App.                Package App.


             App.              WebView
            Graphic            Graphic
            Context            Context
Magic Point in Android
Magic Point in Android
<!DOCTYPE html>
 <head>
  <script>
   function changeText() {
     document.getElementById(‘myDiv’).innerHTML = MyHybrid.hello();
   }
  </script>
 </head>
 <body>
   <b id=‘myDiv’>Hello world.</b><br/>
   <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/>
 </body>
</html>



public class HybirdApp extends Activity {
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    WebView webView = findResourceById(R.id.WebView);
    webView.loadUrl(“file:///android_asset/www/index.html”);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.addJavascriptInterface(new MyHybrid(), “MyHybrid”);
  }
  class MyHybrid {
    public String hello() {
      return “Hello hybrid App.”;
    }
  }
}
Magic Point in Android
<!DOCTYPE html>
 <head>
  <script>
   function changeText() {
     document.getElementById(‘myDiv’).innerHTML = MyHybrid.hello();
   }
  </script>
 </head>
 <body>
   <b id=‘myDiv’>Hello world.</b><br/>
   <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/>
 </body>
</html>



public class HybirdApp extends Activity {
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    WebView webView = findResourceById(R.id.WebView);
    webView.loadUrl(“file:///android_asset/www/index.html”);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.addJavascriptInterface(new MyHybrid(), “MyHybrid”);
  }
  class MyHybrid {
    public String hello() {
      return “Hello hybrid App.”;
    }
  }
}
Magic Point in Android
<!DOCTYPE html>
 <head>
  <script>
   function changeText() {
     document.getElementById(‘myDiv’).innerHTML = MyHybrid.hello();
   }
  </script>
 </head>
 <body>
   <b id=‘myDiv’>Hello world.</b><br/>
   <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/>
 </body>
</html>



public class HybirdApp extends Activity {
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    WebView webView = findResourceById(R.id.WebView);
    webView.loadUrl(“file:///android_asset/www/index.html”);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.addJavascriptInterface(new MyHybrid(), “MyHybrid”);
  }
  class MyHybrid {
    public String hello() {
      return “Hello hybrid App.”;
    }
  }
}
1. parameter type



• Which type of parameter in JavaScript is suitable for
  Java?
  • numeric, boolean, string
  • object, array, function
1. parameter type
<script>
 function changeText() {
   var str = MyHybrid.setInt(20) + “<br/>”;
   str += MyHybrid.setFloat(20.5) + “<br/>”;
   str += MyHybrid.setBoolean(true) + “<br/>”;
   str += MyHybrid.setString(“hello”) + “<br/>”;
   document.getElementById(‘paramTest’).innerHTML = str;
 }
</script>
<body>
 <div id=‘paramTest’></div>
</body>




class MyHybrid {
  public String setInt(int data) {
    return “setInt:” + Integer.toString(data);
  }
  public String setFloat(float data) {
    return “setFloat:” + Float.toString(data);
  }
  public String setBoolean(boolean data) {
    return “setBoolean:” + Boolean.toString(data);
  }
  public String setString(String data) {
    return “setString:” + data;
  }
}
1. parameter type
<script>
 function changeText() {
   var str = MyHybrid.setInt(20) + “<br/>”;
   str += MyHybrid.setFloat(20.5) + “<br/>”;
   str += MyHybrid.setBoolean(true) + “<br/>”;
   str += MyHybrid.setString(“hello”) + “<br/>”;
   document.getElementById(‘paramTest’).innerHTML = str;
 }
</script>
<body>
 <div id=‘paramTest’></div>
</body>




class MyHybrid {
  public String setInt(int data) {
    return “setInt:” + Integer.toString(data);
  }
  public String setFloat(float data) {
    return “setFloat:” + Float.toString(data);
  }
  public String setBoolean(boolean data) {
    return “setBoolean:” + Boolean.toString(data);
  }
  public String setString(String data) {
    return “setString:” + data;
  }
}
1. parameter type
<script>
 function changeText() {
   var str = MyHybrid.setObject({}) + “<br/>”;
   str += MyHybrid.setArray([]) + “<br/>”;
   str += MyHybrid.setFunction(func1) + “<br/>”;
   document.getElementById(‘paramTest’).innerHTML = str;
 }
 function func1() {
   var value1=0;
 }
</script>
<body>
 <div id=‘paramTest’></div>
</body>


class MyHybrid {
  public String setObject(String data) {
    return “setObject:” + data;
  }
  public String setArray(String data) {
    return “setArray:” + data;
  }
  public String setFunction(String data) {
    return “setFunction:” + data;
  }
}
1. parameter type
<script>
 function changeText() {
   var str = MyHybrid.setObject({}) + “<br/>”;
   str += MyHybrid.setArray([]) + “<br/>”;
   str += MyHybrid.setFunction(func1) + “<br/>”;
   document.getElementById(‘paramTest’).innerHTML = str;
 }
 function func1() {
   var value1=0;
 }
</script>
<body>
 <div id=‘paramTest’></div>
</body>


class MyHybrid {
  public String setObject(String data) {
    return “setObject:” + data;
  }
  public String setArray(String data) {
    return “setArray:” + data;
  }
  public String setFunction(String data) {
    return “setFunction:” + data;
  }
}
1. parameter type
<script>
 function changeText() {
   var str = MyHybrid.setObject( JSON.stringify({}) ) + “<br/>”;
   str += MyHybrid.setArray( JSON.stringify([]) ) + “<br/>”;
   str += MyHybrid.setFunction( func1.toString() ) + “<br/>”;
   document.getElementById(‘paramTest’).innerHTML = str;
 }
 function func1() {
   var value1=0;
 }
</script>
<body>
 <div id=‘paramTest’></div>
</body>


class MyHybrid {
  public String setObject(String data) {
    return “setObject:” + data;
  }
  public String setArray(String data) {
    return “setArray:” + data;
  }
  public String setFunction(String data) {
    return “setFunction:” + data;
  }
}
1. parameter type
<script>
 function changeText() {
   var str = MyHybrid.setObject( JSON.stringify({}) ) + “<br/>”;
   str += MyHybrid.setArray( JSON.stringify([]) ) + “<br/>”;
   str += MyHybrid.setFunction( func1.toString() ) + “<br/>”;
   document.getElementById(‘paramTest’).innerHTML = str;
 }
 function func1() {
   var value1=0;
 }
</script>
<body>
 <div id=‘paramTest’></div>
</body>


class MyHybrid {
  public String setObject(String data) {
    return “setObject:” + data;
  }
  public String setArray(String data) {
    return “setArray:” + data;
  }
  public String setFunction(String data) {
    return “setFunction:” + data;
  }
}
2. asynchronous function in Java



• If JavaScript is stuck ?
 • OMG!!
 • ANR!!
2. asynchronous function in Java
<script>
 var start = new Date().getTime();
 setInterval(function() {
   document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”;
 }, 1000);
 function changeText() {
   document.getElementById(‘tTest’).innerHTML += “call MyHybrid.hang()<br/>”;
   MyHybrid.hang(5);
   document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”;
 }
</script>
<body>
 <div id=‘tTest’></div>
 <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/>
</body>

class MyHybrid {
  public void hang(int time) {
    try {
      Thread.sleep(time*1000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}
2. asynchronous function in Java
<script>
 var start = new Date().getTime();
 setInterval(function() {
   document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”;
 }, 1000);
 function changeText() {
   document.getElementById(‘tTest’).innerHTML += “call MyHybrid.hang()<br/>”;
   MyHybrid.hang(5);
   document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”;
 }
</script>
<body>
 <div id=‘tTest’></div>
 <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/>
</body>

class MyHybrid {
  public void hang(int time) {
    try {
      Thread.sleep(time*1000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}
2. asynchronous function in Java
<script>
 var start = new Date().getTime();
 setInterval(function() {
   document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”;
 }, 1000);
 function changeText() {
   document.getElementById(‘tTest’).innerHTML += “call MyHybrid.asyncJob()<br/>”;
   MyHybrid.asyncJob(5);
   document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”;
 }
</script>
<body>
 <div id=‘tTest’></div>
 <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/>
</body>

class MyHybrid {
  public void asyncJob(final int time) {
    Thread thread = new Thread(new Runnable() {
     public void run() {
       try {
         Thread.sleep(time*1000);
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
     }
    });
    thread.start();
  }
}
2. asynchronous function in Java
<script>
 var start = new Date().getTime();
 setInterval(function() {
   document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”;
 }, 1000);
 function changeText() {
   document.getElementById(‘tTest’).innerHTML += “call MyHybrid.asyncJob()<br/>”;
   MyHybrid.asyncJob(5);
   document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”;
 }
</script>
<body>
 <div id=‘tTest’></div>
 <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/>
</body>

class MyHybrid {
  public void asyncJob(final int time) {
    Thread thread = new Thread(new Runnable() {
     public void run() {
       try {
         Thread.sleep(time*1000);
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
     }
    });
    thread.start();
  }
}
3. return value & callback function




• When functions are changed asynchronously, how to
  return results to the caller exactly?
3. return value & callback function
<script>
 var start = new Date().getTime();
 setInterval(function() {
   document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”;
 }, 1000);
 function changeText() {
   document.getElementById(‘tTest’).innerHTML += “call MyHybrid.asyncJob()<br/>”;
   MyHybrid.asyncJob(5);
   document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”;
 }
</script>
<body>
 <div id=‘tTest’></div>
 <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/>
</body>

class MyHybrid {
  public void asyncJob(final int time) {
    Thread thread = new Thread(new Runnable() {
     public void run() {
       try {
         Thread.sleep(time*1000);
         // how to return results?
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
     }
    });
    thread.start();
  }
}
3. return value & callback function
<script>
 var start = new Date().getTime();
 setInterval(function() {
   document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”;
 }, 1000);
 function changeText() {
   document.getElementById(‘tTest’).innerHTML += “call MyHybrid.asyncJob()<br/>”;
   MyHybrid.asyncJob(5);
   document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”;
 }
</script>
<body>
 <div id=‘tTest’></div>
 <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/>
</body>

class MyHybrid {
  public void asyncJob(final int time) {
    Thread thread = new Thread(new Runnable() {
     public void run() {
       try {
         Thread.sleep(time*1000);
         // how to return results?
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
     }
    });
    thread.start();
  }
}
3. return value & callback function
<script>
 var start = new Date().getTime();
 setInterval(function() {
   document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”;
 }, 1000);
 function changeText() {
   document.getElementById(‘tTest’).innerHTML += “call MyHybrid.asyncJob()<br/>”;
   MyHybrid.asyncJob(5);
   document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”;
 }
</script>
<body>
 <div id=‘tTest’></div>
 <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/>
</body>

class MyHybrid {
 public void asyncJob(final int time) {
   Thread thread = new Thread(new Runnable() {
    public void run() {
      try {
        Thread.sleep(time*1000);
        mWebView.loadUrl(“javascript:document.getElementById(‘tTest’).innerHTML +=
”finish asyncJob()<br/>””);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
   });
   thread.start();
 }
3. return value & callback function
<script>
 var start = new Date().getTime();
 setInterval(function() {
   document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”;
 }, 1000);
 function changeText() {
   document.getElementById(‘tTest’).innerHTML += “call MyHybrid.asyncJob()<br/>”;
   MyHybrid.asyncJob(5);
   document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”;
 }
</script>
<body>
 <div id=‘tTest’></div>
 <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/>
</body>

class MyHybrid {
 public void asyncJob(final int time) {
   Thread thread = new Thread(new Runnable() {
    public void run() {
      try {
        Thread.sleep(time*1000);
        mWebView.loadUrl(“javascript:document.getElementById(‘tTest’).innerHTML +=
”finish asyncJob()<br/>””);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
   });
   thread.start();
 }
3. return value & callback function
<script>
 var start = new Date().getTime();
 setInterval(function() {
   document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”;
 }, 1000);
 function changeText() {
   document.getElementById(‘tTest’).innerHTML += “call MyHybrid.aFuncJob()<br/>”;
   MyHybrid.aFuncJob(asyncFunction.toString().match(/^s*functions+([^s(]+)/)[1], 5);
   document.getElementById(‘tTest’).innerHTML += “aFuncJob 5secs<br/>”;
 }
 function asyncFunction(str) {
   document.getElementById(‘tTest’).innerHTML += “asyncFunction:” + str + “<br/>”;
 }
</script>
<body>

class MyHybrid {
  public String aFuncJob(final String strFunc, final int time) {
    Thread thread = new Thread(new Runnable() {
     public void run() {
       try {
         Thread.sleep(time*1000);
         mWebView.loadUrl(“javascript:” + strFunc + “(”finish aFuncJob()<br/>”)”);
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
     }
    });
    thread.start();
  }
}
3. return value & callback function
<script>
 var start = new Date().getTime();
 setInterval(function() {
   document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”;
 }, 1000);
 function changeText() {
   document.getElementById(‘tTest’).innerHTML += “call MyHybrid.aFuncJob()<br/>”;
   MyHybrid.aFuncJob(asyncFunction.toString().match(/^s*functions+([^s(]+)/)[1], 5);
   document.getElementById(‘tTest’).innerHTML += “aFuncJob 5secs<br/>”;
 }
 function asyncFunction(str) {
   document.getElementById(‘tTest’).innerHTML += “asyncFunction:” + str + “<br/>”;
 }
</script>
<body>

class MyHybrid {
  public String aFuncJob(final String strFunc, final int time) {
    Thread thread = new Thread(new Runnable() {
     public void run() {
       try {
         Thread.sleep(time*1000);
         mWebView.loadUrl(“javascript:” + strFunc + “(”finish aFuncJob()<br/>”)”);
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
     }
    });
    thread.start();
  }
}
4. anonymous callback function


• We use anonymous callback functions in JavaScript,
  normally.
      setInterval(function() {
        alert(“hello”);
      }, 1000);



• Let’s make it possible!
4. anonymous callback function
<script>
 function changeText() {
   var str = MyHybrid.setFunction( func1.toString() ) + “<br/>”;
   str += MyHybrid.setFunction((function func2() {var value2=0;}).toString()) + “<br/>”;
   str += MyHybrid.setFunction((function() {var value3=0;}).toString()) + “<br/>”;
   document.getElementById(‘paramTest’).innerHTML = str;
 }
 function func1() {
   var value1=0;
 }
</script>
<body>
 <div id=‘paramTest’></div>
</body>


class MyHybrid {
  public String setFunction(String data) {
    return “setFunction:” + data;
  }
}
4. anonymous callback function
<script>
 function changeText() {
   var str = MyHybrid.setFunction( func1.toString() ) + “<br/>”;
   str += MyHybrid.setFunction((function func2() {var value2=0;}).toString()) + “<br/>”;
   str += MyHybrid.setFunction((function() {var value3=0;}).toString()) + “<br/>”;
   document.getElementById(‘paramTest’).innerHTML = str;
 }
 function func1() {
   var value1=0;
 }
</script>
<body>
 <div id=‘paramTest’></div>
</body>


class MyHybrid {
  public String setFunction(String data) {
    return “setFunction:” + data;
  }
}
4. anonymous callback function
<script>
 function changeText() {
   document.getElementById(‘tTest’).innerHTML += “call HybridFunc()<br/>”;
   HybridFunc(function(str) {
    document.getElementById(‘tTest’).innerHTML += “callbackFunc:” + str + “<br/>”
   }, 5);
 }

 function HybridFunc(cb, arg) { CbMgr.callCbFunc(cb, arg); }

 var CbMgr = {};
 CbMgr.cbId = 0;
 CbMgr.cbs = {};
 CbMgr.callCbFunc = function(func, arg) {
  var id = “CbMgr” + CbMgr.cbId++;
  if(!CbMgr.cbs[id]) {
    CbMgr.cbs[id] = func;
    MyHybrid.aFuncJobWithId(id, arg);
  }
 };
 CbMgr.fireCbFunc = function(id, args) {
  if(CbMgr.cbs[id]) {
    CbMgr.cbs[id](args);
    delete CbMgr.cbs[id];
  }
 };
</script>
<body>
 <div id=‘tTest’></div>
 <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/>
</body>
4. anonymous callback function
<script>
 function changeText() {
   document.getElementById(‘tTest’).innerHTML += “call HybridFunc()<br/>”;
   HybridFunc(function(str) {
    document.getElementById(‘tTest’).innerHTML += “callbackFunc:” + str + “<br/>”
   }, 5);
 }

 function HybridFunc(cb, arg) { CbMgr.callCbFunc(cb, arg); }

 ...

</script>



public String aFuncJobWithId(final String strId, final int time) {
 Thread thread = new Thread(new Runnable() {
   public void run() {
    try {
      Thread.sleep(time*1000);
      mWebView.loadUrl(“javascript:CbMgr.fireCbFunc(”” + strId + “”, ”finish
aFuncJobWithId()<br/>”)”);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
   });
   thread.start();
 }
4. anonymous callback function
<script>
 function changeText() {
   document.getElementById(‘tTest’).innerHTML += “call HybridFunc()<br/>”;
   HybridFunc(function(str) {
    document.getElementById(‘tTest’).innerHTML += “callbackFunc:” + str + “<br/>”
   }, 5);
 }

 function HybridFunc(cb, arg) { CbMgr.callCbFunc(cb, arg); }

 ...

</script>



public String aFuncJobWithId(final String strId, final int time) {
 Thread thread = new Thread(new Runnable() {
   public void run() {
    try {
      Thread.sleep(time*1000);
      mWebView.loadUrl(“javascript:CbMgr.fireCbFunc(”” + strId + “”, ”finish
aFuncJobWithId()<br/>”)”);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
   });
   thread.start();
 }
To use generally
<script src=”MyHybrid.js”></script>
<script>
 function changeText() {
   document.getElementById(‘tTest’).innerHTML += “call HybridFunc()<br/>”;
   HybridFunc(function(str) {
    document.getElementById(‘tTest’).innerHTML += “callbackFunc:” + str + “<br/>”
   }, 5);
   HybridFunc(function(str) {
    alert(str);
   }, 1);
   HybridFunc(function(str) {
    if(str == “handsome guy”) alert(“”);
   }, {age : 20, name : “musart”);
 }
</script>

class MyHybrid {
  public String aFuncJobWithId(final String strId, final int time) {
   Thread thread = new Thread(new Runnable() {
     public void run() {
      try {
        Thread.sleep(time*1000);
        mWebView.loadUrl(“javascript:CbMgr.fireCbFunc(”” +strId+ “”, ” +time+ ”)”);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
     });
     thread.start();
   }
}
Simple Hybrid App.


• If you draw 10 dots, get results from Java.
Simple Hybird App.
<!DOCTYPE html>
<head>
 <script>
  /* MyHybrid.js */
  function HybridFunc(action, cb, arg) {
    CbMgr.callCbFunc(action, cb, arg);
  }

 var CbMgr = {};
 CbMgr.cbId = 0;
 CbMgr.cbs = {};
 CbMgr.callCbFunc = function(action, cb, arg) {
   var id = "CbMgr" + CbMgr.cbId++;
   if(!CbMgr.cbs[id]) {
     CbMgr.cbs[id] = cb;
     MyHybrid.HybridFunc(action, id, arg);
   }
 };
 CbMgr.fireCbFunc = function(id, args) {
   if(CbMgr.cbs[id]) {
     CbMgr.cbs[id](args);
     delete CbMgr.cbs[id];
 }
 }
 </script>
    ...
</head>
<body>
    ...
</body>
</html>
Simple Hybird App.
<script>
function startDotGame() {
   var canvas = document.getElementById("canvas1");
   ctx = canvas.getContext("2d");

   canvas.addEventListener("touchstart", function(event) {
       ctx.beginPath();
       ctx.lineWidth = 10;
       ctx.moveTo(event.touches[0].pageX, event.touches[0].pageY);
       ctx.lineTo(event.touches[0].pageX+1, event.touches[0].pageY+1);
       ctx.stroke();
   });
   canvas.addEventListener("touchmove", function(event) {});
   canvas.addEventListener("touchend", function(event) {
       ctx.stroke();
       ctx.closePath();
       ctx.save();
       HybridFunc("addDot", function() {});
   });

   HybridFunc("startDot", function(value) {
       ctx.beginPath();
       ctx.fillText(value, 50, 50);
       ctx.stroke();
       ctx.closePath();
       ctx.save();
   });
   document.getElementById('btn').value = "stop";
}
</script>
Simple Hybird App.
<!DOCTYPE html>
<head>
    ...
</head>
<body>
    <canvas id="canvas1" width=300 height=300 style="position: relative; border: 1px
solid #000;"></canvas>
    <input id="btn" type='button' onclick='startDotGame()' value='start'/>
</body>
</html>
Simple Hybird App.
package com.HybridApp;

import   android.app.Activity;
import   android.os.Bundle;
import   android.view.ViewGroup.LayoutParams;
import   android.webkit.WebChromeClient;
import   android.webkit.WebView;
import   android.widget.LinearLayout;
import   com.HybridApp.R;

public class HybridAppActivity extends Activity {
    /** Called when the activity is first created. */
    private WebView mWebView = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
      //mWebView = (WebView) findViewById(R.id.webView);
        mWebView = new WebView(this);

          mWebView.setLayoutParams(new LinearLayout.LayoutParams(
                 LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
          setContentView(mWebView);
          mWebView.loadUrl("file:///android_asset/www/index2.html");
          mWebView.getSettings().setJavaScriptEnabled(true);
          mWebView.addJavascriptInterface(new MyHybrid(), "MyHybrid");
    }

    ...
}
Simple Hybird App.
 class MyHybrid {
 public int dotNum = 0;

 public void addDot(final String cbId, final String arg) {
   dotNum++;
 }
 public void startDot(final String cbId, final String arg) {
 dotNum = 0;
 final Thread thread = new Thread(new Runnable() {
   public void run() {
     while(true) {
      if(dotNum == 10) {
        mWebView.loadUrl("javascript:CbMgr.fireCbFunc("" + cbId + "", "finish1")");
        break;
      } else {
        try {
          Thread.sleep(500);
        } catch (InterruptedException e) {}
        }
      }
     }});
   thread.start();
 }
 public void HybridFunc(final String strFunc, final String cbId, final String arg) {
   if("addDot".equals(strFunc)) {
     addDot(cbId, arg);
   } else if("startDot".equals(strFunc)) {
     startDot(cbId, arg);
   }
 }
}
Thank you
                @musart

        all source codes are in github.
https://github.com/musart/HybridApplication

Contenu connexe

Tendances

Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
Hi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab PresentationHi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab Presentationplindner
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMJonathan Wage
 
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperJonathan Wage
 
4시간만에 따라해보는 Windows 10 앱 개발 샘플코드
4시간만에 따라해보는 Windows 10 앱 개발 샘플코드4시간만에 따라해보는 Windows 10 앱 개발 샘플코드
4시간만에 따라해보는 Windows 10 앱 개발 샘플코드영욱 김
 
Java Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDBJava Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDBMongoDB
 
What's new in iOS 7
What's new in iOS 7What's new in iOS 7
What's new in iOS 7barcelonaio
 
Dominando o Data Binding no Android
Dominando o Data Binding no AndroidDominando o Data Binding no Android
Dominando o Data Binding no AndroidNelson Glauber Leal
 
MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...
MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...
MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...MongoDB
 
Dominando o Data Binding no Android
Dominando o Data Binding no AndroidDominando o Data Binding no Android
Dominando o Data Binding no AndroidNelson Glauber Leal
 
How Signpost uses MongoDB for Tracking and Analytics
How Signpost uses MongoDB for Tracking and AnalyticsHow Signpost uses MongoDB for Tracking and Analytics
How Signpost uses MongoDB for Tracking and Analyticsmattinsler
 
ZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMJonathan Wage
 
Using Mongoid with Ruby on Rails
Using Mongoid with Ruby on RailsUsing Mongoid with Ruby on Rails
Using Mongoid with Ruby on RailsNicholas Altobelli
 
[MongoDB.local Bengaluru 2018] Just in Time Validation with JSON Schema
[MongoDB.local Bengaluru 2018] Just in Time Validation with JSON Schema[MongoDB.local Bengaluru 2018] Just in Time Validation with JSON Schema
[MongoDB.local Bengaluru 2018] Just in Time Validation with JSON SchemaMongoDB
 
The Ring programming language version 1.8 book - Part 49 of 202
The Ring programming language version 1.8 book - Part 49 of 202The Ring programming language version 1.8 book - Part 49 of 202
The Ring programming language version 1.8 book - Part 49 of 202Mahmoud Samir Fayed
 
"Android Data Binding в массы" Михаил Анохин
"Android Data Binding в массы" Михаил Анохин"Android Data Binding в массы" Михаил Анохин
"Android Data Binding в массы" Михаил АнохинFwdays
 
Михаил Анохин "Data binding 2.0"
Михаил Анохин "Data binding 2.0"Михаил Анохин "Data binding 2.0"
Михаил Анохин "Data binding 2.0"Fwdays
 
WaveEngine 2D components
WaveEngine 2D componentsWaveEngine 2D components
WaveEngine 2D componentswaveengineteam
 
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB
 

Tendances (20)

Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Hi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab PresentationHi5 Opensocial Code Lab Presentation
Hi5 Opensocial Code Lab Presentation
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODM
 
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document Mapper
 
4시간만에 따라해보는 Windows 10 앱 개발 샘플코드
4시간만에 따라해보는 Windows 10 앱 개발 샘플코드4시간만에 따라해보는 Windows 10 앱 개발 샘플코드
4시간만에 따라해보는 Windows 10 앱 개발 샘플코드
 
Java Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDBJava Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDB
 
What's new in iOS 7
What's new in iOS 7What's new in iOS 7
What's new in iOS 7
 
Dominando o Data Binding no Android
Dominando o Data Binding no AndroidDominando o Data Binding no Android
Dominando o Data Binding no Android
 
ActiveRecord vs Mongoid
ActiveRecord vs MongoidActiveRecord vs Mongoid
ActiveRecord vs Mongoid
 
MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...
MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...
MongoDB .local Munich 2019: New Encryption Capabilities in MongoDB 4.2: A Dee...
 
Dominando o Data Binding no Android
Dominando o Data Binding no AndroidDominando o Data Binding no Android
Dominando o Data Binding no Android
 
How Signpost uses MongoDB for Tracking and Analytics
How Signpost uses MongoDB for Tracking and AnalyticsHow Signpost uses MongoDB for Tracking and Analytics
How Signpost uses MongoDB for Tracking and Analytics
 
ZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODM
 
Using Mongoid with Ruby on Rails
Using Mongoid with Ruby on RailsUsing Mongoid with Ruby on Rails
Using Mongoid with Ruby on Rails
 
[MongoDB.local Bengaluru 2018] Just in Time Validation with JSON Schema
[MongoDB.local Bengaluru 2018] Just in Time Validation with JSON Schema[MongoDB.local Bengaluru 2018] Just in Time Validation with JSON Schema
[MongoDB.local Bengaluru 2018] Just in Time Validation with JSON Schema
 
The Ring programming language version 1.8 book - Part 49 of 202
The Ring programming language version 1.8 book - Part 49 of 202The Ring programming language version 1.8 book - Part 49 of 202
The Ring programming language version 1.8 book - Part 49 of 202
 
"Android Data Binding в массы" Михаил Анохин
"Android Data Binding в массы" Михаил Анохин"Android Data Binding в массы" Михаил Анохин
"Android Data Binding в массы" Михаил Анохин
 
Михаил Анохин "Data binding 2.0"
Михаил Анохин "Data binding 2.0"Михаил Анохин "Data binding 2.0"
Михаил Анохин "Data binding 2.0"
 
WaveEngine 2D components
WaveEngine 2D componentsWaveEngine 2D components
WaveEngine 2D components
 
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
 

Similaire à The Principle of Hybrid App.

CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
Google
GoogleGoogle
Googlesoon
 
After max+phonegap
After max+phonegapAfter max+phonegap
After max+phonegapyangdj
 
混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaver混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaveryangdj
 
GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4Heather Rock
 
Hi5 opensocial-code-lab-presentation-1203814696810018-3
Hi5 opensocial-code-lab-presentation-1203814696810018-3Hi5 opensocial-code-lab-presentation-1203814696810018-3
Hi5 opensocial-code-lab-presentation-1203814696810018-3Kunal Mittal
 
IndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web AppsIndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web AppsAdégòkè Obasá
 
Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolboxShem Magnezi
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsJarod Ferguson
 
Building complex User Interfaces with Sitecore and React
Building complex User Interfaces with Sitecore and ReactBuilding complex User Interfaces with Sitecore and React
Building complex User Interfaces with Sitecore and ReactJonne Kats
 

Similaire à The Principle of Hybrid App. (20)

CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Html5 For Jjugccc2009fall
Html5 For Jjugccc2009fallHtml5 For Jjugccc2009fall
Html5 For Jjugccc2009fall
 
Google
GoogleGoogle
Google
 
After max+phonegap
After max+phonegapAfter max+phonegap
After max+phonegap
 
混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaver混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaver
 
GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4GDI Seattle - Intro to JavaScript Class 4
GDI Seattle - Intro to JavaScript Class 4
 
Hi5 opensocial-code-lab-presentation-1203814696810018-3
Hi5 opensocial-code-lab-presentation-1203814696810018-3Hi5 opensocial-code-lab-presentation-1203814696810018-3
Hi5 opensocial-code-lab-presentation-1203814696810018-3
 
IndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web AppsIndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web Apps
 
Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolbox
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Ajax chap 4
Ajax chap 4Ajax chap 4
Ajax chap 4
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
 
Scala on Your Phone
Scala on Your PhoneScala on Your Phone
Scala on Your Phone
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
 
Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
 
Serverless
ServerlessServerless
Serverless
 
Building complex User Interfaces with Sitecore and React
Building complex User Interfaces with Sitecore and ReactBuilding complex User Interfaces with Sitecore and React
Building complex User Interfaces with Sitecore and React
 
Html5 Overview
Html5 OverviewHtml5 Overview
Html5 Overview
 
jQuery
jQueryjQuery
jQuery
 
Java script -23jan2015
Java script -23jan2015Java script -23jan2015
Java script -23jan2015
 

Dernier

Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 

Dernier (20)

Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 

The Principle of Hybrid App.

  • 1. The Principle of Hybrid App. @musart
  • 2. The solutions is Hybrid App...
  • 3. What is Hybrid App.? ? : http://www.phonegap.com/
  • 4. The type of Hybrid App. • Run-time Hybrid App. • phonegap • appspresso • Build-time Hybrid App. • titanium
  • 5. Build-time vs. Run-time JavaScript JavaScript, CSS, html App. WebView Graphic Graphic Context Context
  • 6. Build-time vs. Run-time JavaScript JavaScript, CSS, html Convert JS to Java, Obj-C Package App. App. WebView Graphic Graphic Context Context
  • 7. Build-time vs. Run-time JavaScript JavaScript, CSS, html Convert JS to Java, Obj-C Connect JS and Java, Obj-C Package App. Package App. App. WebView Graphic Graphic Context Context
  • 8. Magic Point in Android
  • 9. Magic Point in Android <!DOCTYPE html> <head> <script> function changeText() { document.getElementById(‘myDiv’).innerHTML = MyHybrid.hello(); } </script> </head> <body> <b id=‘myDiv’>Hello world.</b><br/> <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/> </body> </html> public class HybirdApp extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); WebView webView = findResourceById(R.id.WebView); webView.loadUrl(“file:///android_asset/www/index.html”); webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new MyHybrid(), “MyHybrid”); } class MyHybrid { public String hello() { return “Hello hybrid App.”; } } }
  • 10. Magic Point in Android <!DOCTYPE html> <head> <script> function changeText() { document.getElementById(‘myDiv’).innerHTML = MyHybrid.hello(); } </script> </head> <body> <b id=‘myDiv’>Hello world.</b><br/> <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/> </body> </html> public class HybirdApp extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); WebView webView = findResourceById(R.id.WebView); webView.loadUrl(“file:///android_asset/www/index.html”); webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new MyHybrid(), “MyHybrid”); } class MyHybrid { public String hello() { return “Hello hybrid App.”; } } }
  • 11. Magic Point in Android <!DOCTYPE html> <head> <script> function changeText() { document.getElementById(‘myDiv’).innerHTML = MyHybrid.hello(); } </script> </head> <body> <b id=‘myDiv’>Hello world.</b><br/> <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/> </body> </html> public class HybirdApp extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); WebView webView = findResourceById(R.id.WebView); webView.loadUrl(“file:///android_asset/www/index.html”); webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new MyHybrid(), “MyHybrid”); } class MyHybrid { public String hello() { return “Hello hybrid App.”; } } }
  • 12. 1. parameter type • Which type of parameter in JavaScript is suitable for Java? • numeric, boolean, string • object, array, function
  • 13. 1. parameter type <script> function changeText() { var str = MyHybrid.setInt(20) + “<br/>”; str += MyHybrid.setFloat(20.5) + “<br/>”; str += MyHybrid.setBoolean(true) + “<br/>”; str += MyHybrid.setString(“hello”) + “<br/>”; document.getElementById(‘paramTest’).innerHTML = str; } </script> <body> <div id=‘paramTest’></div> </body> class MyHybrid { public String setInt(int data) { return “setInt:” + Integer.toString(data); } public String setFloat(float data) { return “setFloat:” + Float.toString(data); } public String setBoolean(boolean data) { return “setBoolean:” + Boolean.toString(data); } public String setString(String data) { return “setString:” + data; } }
  • 14. 1. parameter type <script> function changeText() { var str = MyHybrid.setInt(20) + “<br/>”; str += MyHybrid.setFloat(20.5) + “<br/>”; str += MyHybrid.setBoolean(true) + “<br/>”; str += MyHybrid.setString(“hello”) + “<br/>”; document.getElementById(‘paramTest’).innerHTML = str; } </script> <body> <div id=‘paramTest’></div> </body> class MyHybrid { public String setInt(int data) { return “setInt:” + Integer.toString(data); } public String setFloat(float data) { return “setFloat:” + Float.toString(data); } public String setBoolean(boolean data) { return “setBoolean:” + Boolean.toString(data); } public String setString(String data) { return “setString:” + data; } }
  • 15. 1. parameter type <script> function changeText() { var str = MyHybrid.setObject({}) + “<br/>”; str += MyHybrid.setArray([]) + “<br/>”; str += MyHybrid.setFunction(func1) + “<br/>”; document.getElementById(‘paramTest’).innerHTML = str; } function func1() { var value1=0; } </script> <body> <div id=‘paramTest’></div> </body> class MyHybrid { public String setObject(String data) { return “setObject:” + data; } public String setArray(String data) { return “setArray:” + data; } public String setFunction(String data) { return “setFunction:” + data; } }
  • 16. 1. parameter type <script> function changeText() { var str = MyHybrid.setObject({}) + “<br/>”; str += MyHybrid.setArray([]) + “<br/>”; str += MyHybrid.setFunction(func1) + “<br/>”; document.getElementById(‘paramTest’).innerHTML = str; } function func1() { var value1=0; } </script> <body> <div id=‘paramTest’></div> </body> class MyHybrid { public String setObject(String data) { return “setObject:” + data; } public String setArray(String data) { return “setArray:” + data; } public String setFunction(String data) { return “setFunction:” + data; } }
  • 17. 1. parameter type <script> function changeText() { var str = MyHybrid.setObject( JSON.stringify({}) ) + “<br/>”; str += MyHybrid.setArray( JSON.stringify([]) ) + “<br/>”; str += MyHybrid.setFunction( func1.toString() ) + “<br/>”; document.getElementById(‘paramTest’).innerHTML = str; } function func1() { var value1=0; } </script> <body> <div id=‘paramTest’></div> </body> class MyHybrid { public String setObject(String data) { return “setObject:” + data; } public String setArray(String data) { return “setArray:” + data; } public String setFunction(String data) { return “setFunction:” + data; } }
  • 18. 1. parameter type <script> function changeText() { var str = MyHybrid.setObject( JSON.stringify({}) ) + “<br/>”; str += MyHybrid.setArray( JSON.stringify([]) ) + “<br/>”; str += MyHybrid.setFunction( func1.toString() ) + “<br/>”; document.getElementById(‘paramTest’).innerHTML = str; } function func1() { var value1=0; } </script> <body> <div id=‘paramTest’></div> </body> class MyHybrid { public String setObject(String data) { return “setObject:” + data; } public String setArray(String data) { return “setArray:” + data; } public String setFunction(String data) { return “setFunction:” + data; } }
  • 19. 2. asynchronous function in Java • If JavaScript is stuck ? • OMG!! • ANR!!
  • 20. 2. asynchronous function in Java <script> var start = new Date().getTime(); setInterval(function() { document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”; }, 1000); function changeText() { document.getElementById(‘tTest’).innerHTML += “call MyHybrid.hang()<br/>”; MyHybrid.hang(5); document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”; } </script> <body> <div id=‘tTest’></div> <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/> </body> class MyHybrid { public void hang(int time) { try { Thread.sleep(time*1000); } catch (InterruptedException e) { e.printStackTrace(); } } }
  • 21. 2. asynchronous function in Java <script> var start = new Date().getTime(); setInterval(function() { document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”; }, 1000); function changeText() { document.getElementById(‘tTest’).innerHTML += “call MyHybrid.hang()<br/>”; MyHybrid.hang(5); document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”; } </script> <body> <div id=‘tTest’></div> <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/> </body> class MyHybrid { public void hang(int time) { try { Thread.sleep(time*1000); } catch (InterruptedException e) { e.printStackTrace(); } } }
  • 22. 2. asynchronous function in Java <script> var start = new Date().getTime(); setInterval(function() { document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”; }, 1000); function changeText() { document.getElementById(‘tTest’).innerHTML += “call MyHybrid.asyncJob()<br/>”; MyHybrid.asyncJob(5); document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”; } </script> <body> <div id=‘tTest’></div> <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/> </body> class MyHybrid { public void asyncJob(final int time) { Thread thread = new Thread(new Runnable() { public void run() { try { Thread.sleep(time*1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread.start(); } }
  • 23. 2. asynchronous function in Java <script> var start = new Date().getTime(); setInterval(function() { document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”; }, 1000); function changeText() { document.getElementById(‘tTest’).innerHTML += “call MyHybrid.asyncJob()<br/>”; MyHybrid.asyncJob(5); document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”; } </script> <body> <div id=‘tTest’></div> <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/> </body> class MyHybrid { public void asyncJob(final int time) { Thread thread = new Thread(new Runnable() { public void run() { try { Thread.sleep(time*1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread.start(); } }
  • 24. 3. return value & callback function • When functions are changed asynchronously, how to return results to the caller exactly?
  • 25. 3. return value & callback function <script> var start = new Date().getTime(); setInterval(function() { document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”; }, 1000); function changeText() { document.getElementById(‘tTest’).innerHTML += “call MyHybrid.asyncJob()<br/>”; MyHybrid.asyncJob(5); document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”; } </script> <body> <div id=‘tTest’></div> <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/> </body> class MyHybrid { public void asyncJob(final int time) { Thread thread = new Thread(new Runnable() { public void run() { try { Thread.sleep(time*1000); // how to return results? } catch (InterruptedException e) { e.printStackTrace(); } } }); thread.start(); } }
  • 26. 3. return value & callback function <script> var start = new Date().getTime(); setInterval(function() { document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”; }, 1000); function changeText() { document.getElementById(‘tTest’).innerHTML += “call MyHybrid.asyncJob()<br/>”; MyHybrid.asyncJob(5); document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”; } </script> <body> <div id=‘tTest’></div> <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/> </body> class MyHybrid { public void asyncJob(final int time) { Thread thread = new Thread(new Runnable() { public void run() { try { Thread.sleep(time*1000); // how to return results? } catch (InterruptedException e) { e.printStackTrace(); } } }); thread.start(); } }
  • 27. 3. return value & callback function <script> var start = new Date().getTime(); setInterval(function() { document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”; }, 1000); function changeText() { document.getElementById(‘tTest’).innerHTML += “call MyHybrid.asyncJob()<br/>”; MyHybrid.asyncJob(5); document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”; } </script> <body> <div id=‘tTest’></div> <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/> </body> class MyHybrid { public void asyncJob(final int time) { Thread thread = new Thread(new Runnable() { public void run() { try { Thread.sleep(time*1000); mWebView.loadUrl(“javascript:document.getElementById(‘tTest’).innerHTML += ”finish asyncJob()<br/>””); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread.start(); }
  • 28. 3. return value & callback function <script> var start = new Date().getTime(); setInterval(function() { document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”; }, 1000); function changeText() { document.getElementById(‘tTest’).innerHTML += “call MyHybrid.asyncJob()<br/>”; MyHybrid.asyncJob(5); document.getElementById(‘tTest’).innerHTML += “hang 5secs<br/>”; } </script> <body> <div id=‘tTest’></div> <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/> </body> class MyHybrid { public void asyncJob(final int time) { Thread thread = new Thread(new Runnable() { public void run() { try { Thread.sleep(time*1000); mWebView.loadUrl(“javascript:document.getElementById(‘tTest’).innerHTML += ”finish asyncJob()<br/>””); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread.start(); }
  • 29. 3. return value & callback function <script> var start = new Date().getTime(); setInterval(function() { document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”; }, 1000); function changeText() { document.getElementById(‘tTest’).innerHTML += “call MyHybrid.aFuncJob()<br/>”; MyHybrid.aFuncJob(asyncFunction.toString().match(/^s*functions+([^s(]+)/)[1], 5); document.getElementById(‘tTest’).innerHTML += “aFuncJob 5secs<br/>”; } function asyncFunction(str) { document.getElementById(‘tTest’).innerHTML += “asyncFunction:” + str + “<br/>”; } </script> <body> class MyHybrid { public String aFuncJob(final String strFunc, final int time) { Thread thread = new Thread(new Runnable() { public void run() { try { Thread.sleep(time*1000); mWebView.loadUrl(“javascript:” + strFunc + “(”finish aFuncJob()<br/>”)”); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread.start(); } }
  • 30. 3. return value & callback function <script> var start = new Date().getTime(); setInterval(function() { document.getElementById(‘tTest’).innerHTML+=(new Date().getTime()-start)+“msec<br/>”; }, 1000); function changeText() { document.getElementById(‘tTest’).innerHTML += “call MyHybrid.aFuncJob()<br/>”; MyHybrid.aFuncJob(asyncFunction.toString().match(/^s*functions+([^s(]+)/)[1], 5); document.getElementById(‘tTest’).innerHTML += “aFuncJob 5secs<br/>”; } function asyncFunction(str) { document.getElementById(‘tTest’).innerHTML += “asyncFunction:” + str + “<br/>”; } </script> <body> class MyHybrid { public String aFuncJob(final String strFunc, final int time) { Thread thread = new Thread(new Runnable() { public void run() { try { Thread.sleep(time*1000); mWebView.loadUrl(“javascript:” + strFunc + “(”finish aFuncJob()<br/>”)”); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread.start(); } }
  • 31. 4. anonymous callback function • We use anonymous callback functions in JavaScript, normally. setInterval(function() { alert(“hello”); }, 1000); • Let’s make it possible!
  • 32. 4. anonymous callback function <script> function changeText() { var str = MyHybrid.setFunction( func1.toString() ) + “<br/>”; str += MyHybrid.setFunction((function func2() {var value2=0;}).toString()) + “<br/>”; str += MyHybrid.setFunction((function() {var value3=0;}).toString()) + “<br/>”; document.getElementById(‘paramTest’).innerHTML = str; } function func1() { var value1=0; } </script> <body> <div id=‘paramTest’></div> </body> class MyHybrid { public String setFunction(String data) { return “setFunction:” + data; } }
  • 33. 4. anonymous callback function <script> function changeText() { var str = MyHybrid.setFunction( func1.toString() ) + “<br/>”; str += MyHybrid.setFunction((function func2() {var value2=0;}).toString()) + “<br/>”; str += MyHybrid.setFunction((function() {var value3=0;}).toString()) + “<br/>”; document.getElementById(‘paramTest’).innerHTML = str; } function func1() { var value1=0; } </script> <body> <div id=‘paramTest’></div> </body> class MyHybrid { public String setFunction(String data) { return “setFunction:” + data; } }
  • 34. 4. anonymous callback function <script> function changeText() { document.getElementById(‘tTest’).innerHTML += “call HybridFunc()<br/>”; HybridFunc(function(str) { document.getElementById(‘tTest’).innerHTML += “callbackFunc:” + str + “<br/>” }, 5); } function HybridFunc(cb, arg) { CbMgr.callCbFunc(cb, arg); } var CbMgr = {}; CbMgr.cbId = 0; CbMgr.cbs = {}; CbMgr.callCbFunc = function(func, arg) { var id = “CbMgr” + CbMgr.cbId++; if(!CbMgr.cbs[id]) { CbMgr.cbs[id] = func; MyHybrid.aFuncJobWithId(id, arg); } }; CbMgr.fireCbFunc = function(id, args) { if(CbMgr.cbs[id]) { CbMgr.cbs[id](args); delete CbMgr.cbs[id]; } }; </script> <body> <div id=‘tTest’></div> <input type=‘button’ onclick=‘changeText()’ value=‘Change Text’/> </body>
  • 35. 4. anonymous callback function <script> function changeText() { document.getElementById(‘tTest’).innerHTML += “call HybridFunc()<br/>”; HybridFunc(function(str) { document.getElementById(‘tTest’).innerHTML += “callbackFunc:” + str + “<br/>” }, 5); } function HybridFunc(cb, arg) { CbMgr.callCbFunc(cb, arg); } ... </script> public String aFuncJobWithId(final String strId, final int time) { Thread thread = new Thread(new Runnable() { public void run() { try { Thread.sleep(time*1000); mWebView.loadUrl(“javascript:CbMgr.fireCbFunc(”” + strId + “”, ”finish aFuncJobWithId()<br/>”)”); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread.start(); }
  • 36. 4. anonymous callback function <script> function changeText() { document.getElementById(‘tTest’).innerHTML += “call HybridFunc()<br/>”; HybridFunc(function(str) { document.getElementById(‘tTest’).innerHTML += “callbackFunc:” + str + “<br/>” }, 5); } function HybridFunc(cb, arg) { CbMgr.callCbFunc(cb, arg); } ... </script> public String aFuncJobWithId(final String strId, final int time) { Thread thread = new Thread(new Runnable() { public void run() { try { Thread.sleep(time*1000); mWebView.loadUrl(“javascript:CbMgr.fireCbFunc(”” + strId + “”, ”finish aFuncJobWithId()<br/>”)”); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread.start(); }
  • 37. To use generally <script src=”MyHybrid.js”></script> <script> function changeText() { document.getElementById(‘tTest’).innerHTML += “call HybridFunc()<br/>”; HybridFunc(function(str) { document.getElementById(‘tTest’).innerHTML += “callbackFunc:” + str + “<br/>” }, 5); HybridFunc(function(str) { alert(str); }, 1); HybridFunc(function(str) { if(str == “handsome guy”) alert(“”); }, {age : 20, name : “musart”); } </script> class MyHybrid { public String aFuncJobWithId(final String strId, final int time) { Thread thread = new Thread(new Runnable() { public void run() { try { Thread.sleep(time*1000); mWebView.loadUrl(“javascript:CbMgr.fireCbFunc(”” +strId+ “”, ” +time+ ”)”); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread.start(); } }
  • 38. Simple Hybrid App. • If you draw 10 dots, get results from Java.
  • 39. Simple Hybird App. <!DOCTYPE html> <head> <script> /* MyHybrid.js */ function HybridFunc(action, cb, arg) { CbMgr.callCbFunc(action, cb, arg); } var CbMgr = {}; CbMgr.cbId = 0; CbMgr.cbs = {}; CbMgr.callCbFunc = function(action, cb, arg) { var id = "CbMgr" + CbMgr.cbId++; if(!CbMgr.cbs[id]) { CbMgr.cbs[id] = cb; MyHybrid.HybridFunc(action, id, arg); } }; CbMgr.fireCbFunc = function(id, args) { if(CbMgr.cbs[id]) { CbMgr.cbs[id](args); delete CbMgr.cbs[id]; } } </script> ... </head> <body> ... </body> </html>
  • 40. Simple Hybird App. <script> function startDotGame() { var canvas = document.getElementById("canvas1"); ctx = canvas.getContext("2d"); canvas.addEventListener("touchstart", function(event) { ctx.beginPath(); ctx.lineWidth = 10; ctx.moveTo(event.touches[0].pageX, event.touches[0].pageY); ctx.lineTo(event.touches[0].pageX+1, event.touches[0].pageY+1); ctx.stroke(); }); canvas.addEventListener("touchmove", function(event) {}); canvas.addEventListener("touchend", function(event) { ctx.stroke(); ctx.closePath(); ctx.save(); HybridFunc("addDot", function() {}); }); HybridFunc("startDot", function(value) { ctx.beginPath(); ctx.fillText(value, 50, 50); ctx.stroke(); ctx.closePath(); ctx.save(); }); document.getElementById('btn').value = "stop"; } </script>
  • 41. Simple Hybird App. <!DOCTYPE html> <head> ... </head> <body> <canvas id="canvas1" width=300 height=300 style="position: relative; border: 1px solid #000;"></canvas> <input id="btn" type='button' onclick='startDotGame()' value='start'/> </body> </html>
  • 42. Simple Hybird App. package com.HybridApp; import android.app.Activity; import android.os.Bundle; import android.view.ViewGroup.LayoutParams; import android.webkit.WebChromeClient; import android.webkit.WebView; import android.widget.LinearLayout; import com.HybridApp.R; public class HybridAppActivity extends Activity { /** Called when the activity is first created. */ private WebView mWebView = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //mWebView = (WebView) findViewById(R.id.webView); mWebView = new WebView(this); mWebView.setLayoutParams(new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); setContentView(mWebView); mWebView.loadUrl("file:///android_asset/www/index2.html"); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.addJavascriptInterface(new MyHybrid(), "MyHybrid"); } ... }
  • 43. Simple Hybird App. class MyHybrid { public int dotNum = 0; public void addDot(final String cbId, final String arg) { dotNum++; } public void startDot(final String cbId, final String arg) { dotNum = 0; final Thread thread = new Thread(new Runnable() { public void run() { while(true) { if(dotNum == 10) { mWebView.loadUrl("javascript:CbMgr.fireCbFunc("" + cbId + "", "finish1")"); break; } else { try { Thread.sleep(500); } catch (InterruptedException e) {} } } }}); thread.start(); } public void HybridFunc(final String strFunc, final String cbId, final String arg) { if("addDot".equals(strFunc)) { addDot(cbId, arg); } else if("startDot".equals(strFunc)) { startDot(cbId, arg); } } }
  • 44. Thank you @musart all source codes are in github. https://github.com/musart/HybridApplication

Notes de l'éditeur

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n