Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
Cordova Android Native»ìºÏ¿ª·¢Öµ´«µÝ
 
×÷Õߣºtangjiarao À´×ÔÓÚ£ºCSDN ·¢²¼ÓÚ 2015-11-3
  5656  次浏览      28
 

±¾ÈËÖ»ÊDz˼¦Ò»Ã¶£¬Ð´²©¿ÍÖ»ÊÇΪÁË×öһϱʼǣ¬Äê¼Í´óÁË¡£Èç¹ûÓÐ˵µÃ²»×¼È·»òÕß²»ºÃµÄµØ·½ÇëÖ¸³ö£¡£¡ÐéÐÄÇë½Ì´óÉñÖ¸µã¡£Èç¹ûÄã¾õµÃ±¾ÎÄÕÂÌ«»ù´¡Ã»Ê²Ã´ÒâÒ壬Ҳ¸øµãÕÆÉù¹ÄÀø¹ÄÀø¡£

ÉÏһƪÎÄÕÂÓÃcordovaµÄpluginʹµÃhtml¿ÉÒÔµ÷ÓÃActivity²¢ÇÒ»ñÈ¡Activity»Øµ÷µÄÊý¾Ý£¬Ç°ÎÄÁ¬½Ó£ºµ«ÊÇÉÏһƪÎÄÕ³öÏÖÒÔÏÂһЩÎÊÌ⣺

1¡¢Ã»ÓÐʵÏÖ»ìºÏ¿ª·¢

ÉÏһƪÎÄÕ¼ÓÔØhtmlµÄÒ³ÃæÊÇcordovaActivity£¬Ëü¼Ì³ÐActivity£¬ÇÒÓÐÒ»¸öCordovaWebView¶ÔÏó¡ªappView£¬appView²¢²»ÊÇÒ»¸öÕæÕýµÄView£¬ËüÊÇÒ»¸öInterface¡£µ±cordovaActivityµ÷ÓÃloadUrl()·½·¨È¥¼ÓÔØÒ³ÃæµÄʱºò£¬ÆäʵÊÇͨ¹ýappViewÀ´¼ÓÔØ¡£ÒÔÏÂÊÇCordovaActivity µÄ²¿·ÖÔ´Â룺

public class CordovaActivity extends Activity {  
......
protected CordovaWebView appView;
......

/**
* Load the url into the webview.
*/
public void loadUrl(String url) {
if (appView == null) {
init();
}

// If keepRunning
this.keepRunning = preferences.getBoolean("KeepRunning", true);

appView.loadUrlIntoView(url, true);
}

CordovaWebViewÊÇÒ»¸ö½Ó¿Ú£¬Ëü²»ÊÇÒ»¸öView£¬ËüÐèÒªÒ»¸öÏñwebViewÒ»ÑùµÄÈÝÆ÷¸øËüÈ¥ÏÔʾhtmlÒ³Ãæ£¬ËùÒÔÐèҪͨ¹ýÒ»¸öÏÔʾÈÝÆ÷ȥʵÀý»¯Ëü¡£ÆäÖеÄappView.getView();·½·¨¾ÍÊÇÓÃÀ´ÏÔʾhtmlµÄÕæÊµµÄView¡£ÒÔÏÂÊÇCordovaActivity µÄ²¿·ÖÔ´Â룺

protected void init() {  
appView = makeWebView();
createViews();
if (!appView.isInitialized()) {
appView.init(cordovaInterface, pluginEntries, preferences);
}
cordovaInterface.onCordovaInit(appView.getPluginManager());

// Wire the hardware volume controls to control media if desired.
String volumePref = preferences.getString("DefaultVolumeStream", "");
if ("media".equals(volumePref.toLowerCase(Locale.ENGLISH))) {
setVolumeControlStream(AudioManager.STREAM_MUSIC);
}
}

......

protected void createViews() {
//Why are we setting a constant as the ID? This should be investigated
appView.getView().setId(100);
appView.getView().setLayoutParams(new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));

setContentView(appView.getView());

if (preferences.contains("BackgroundColor")) {
int backgroundColor = preferences.getInteger("BackgroundColor", Color.BLACK);
// Background of activity:
appView.getView().setBackgroundColor(backgroundColor);
}

appView.getView().requestFocusFromTouch();
}

/**
* Construct the default web view object.
*
* Override this to customize the webview that is used.
*/
protected CordovaWebView makeWebView() {
return new CordovaWebViewImpl(makeWebViewEngine());
}

protected CordovaWebViewEngine makeWebViewEngine() {
return CordovaWebViewImpl.createEngine(this, preferences);
}

protected CordovaInterfaceImpl makeCordovaInterface() {
return new CordovaInterfaceImpl(this) {
@Override
public Object onMessage(String id, Object data) {
// Plumb this to CordovaActivity.onMessage for backwards compatibility
return CordovaActivity.this.onMessage(id, data);
}
};
}

......

´ÓÒÔÏ´úÂë¿´³ö£¬appViewµÄ´óСÒѾ­ÊÇÉ趨ΪȫÆÁÄ»¸²¸ÇÁË£¬ËùÓÐÐÞ¸ÄappViewµÄ´óСºÍλÖö¼ºÜ²»·½±ã£¬ÉõÖÁÓëÔ­ÉúµÄ¿Ø¼þ½áºÏ¶¼ºÜÄÑ

<span style="font-size:10px;">ppView.getView().setLayoutParams(new FrameLayout.LayoutParams(  
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));</span>

ÄÇÓ¦¸ÃÔõô½â¾ö£¿

2.javaÖ»Êǻص÷½«Öµ·µ»Ø¸øhtmlµÄjs»Øµ÷·½·¨£¬µ«ÊÇȴûÓÐÕæÕýµØÖ÷¶¯È¥µ÷ÓÃjs·½·¨¡£

3.¶¨Òå²å¼þµÄ·½·¨²»¹æ·¶

ËùÒÔËùÒÔ£¡£¡ÏÈÀ´¿´¿´ÑÝʾЧ¹û£º

FirstActivity£¬°üº¬ÁËÒ»¸önative°´Å¥£¬»¹ÓÐÒ»¸öhtmlÒ³Ãæ¡£ÔÚ¶Ô»°¿òÊäÈëÄÚÈÝ£¬µã»÷enter¡£

 

Ìø×ªµ½NAtive SecondActivity£¬²¢ÇÒÏÔʾÐÅÏ¢£¬ÔÚÊäÈë¿òÖÐÊäÈëÄÚÈÝ£¬sendBack

 

SecondActivity MessageÏ·½µÄºìÉ«×ÖÌ壬¾ÍÊÇ´ÓSecondActivity»Øµ÷»ØÀ´µÄ

 

µã»÷È·Èϰ´Å¥£¬ÔÚButton MessageÏ·½ÏÔʾµÄ¾ÍÊÇÖ÷¶¯µ÷ÓÃJS·½·¨Êä³öµÄÄÚÈÝ

 

ʵÏÖ²½Ö裺

£¨1£©¸Õ¸Õ˵µ½ÓÃCordovaActivityÀ´½áºÏÔ­ÉúºÜ¸´ÔÓ£¬ËùÒÔÓÃcordovaÌṩµÄÒ»¸ö¿Ø¼þ¡ª¡ªSystemWebView¡£ËüÊǼ̳ÐWebViewµÄ£¬ÔÚCordovaActivityÖеÄappView.getView();ʵ¼ÊÉÏ·µ»ØµÄÊÇËü¡£ÓÉÓÚËüÊǼ̳ÐwebViewµÄ£¬Ëü¾ÍÏ൱ÓÚÒ»¸ö¿Ø¼þ£¬Äã¿ÉÒÔÔÚxmlÖж¨ÒåËü£¬Ê¹ÓÃËü£¬È·¶¨ËüµÄλÖá£ÒÔÏÂÊÇxml²¼¾ÖÎļþ£º

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
android:id="@+id/bt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="È·¶¨"/>
<org.apache.cordova.engine.SystemWebView
android:id="@+id/cordovaView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
¡¡¡¡
</LinearLayout>

ÔÙÀ´¿´¿´FirstActivityµÄʵÏÖ£º

public class FirstActivity extends Activity {  
/**
* Ò»¸ö¼ÓÔØÍøÒ³µÄÈÝÆ÷£¬¼Ì³ÐWebView
*/
private SystemWebView systemWebView;

private CordovaWebView cordovaWebView;


private ConfigXmlParser parser;

private MyCordovaInterfaceImpl myCordovaInterface;

private Button b;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);

b =(Button)findViewById(R.id.bt1);

systemWebView =(SystemWebView)findViewById(R.id.cordovaView);

//Ϊ³õʼ»¯CordovaWebViewÌṩ²ÎÊý
parser=new ConfigXmlParser();

//ÕâÀï»á½âÎöres/xml/config.xmlÅäÖÃÎļþ
parser.parse(this);

//ʵÀý»¯CordovaWebView
cordovaWebView= new CordovaWebViewImpl(new SystemWebViewEngine(systemWebView));

//Ϊ³õʼ»¯CordovaWebViewÌṩ²ÎÊý,´«Èë±¾Activity
myCordovaInterface =new MyCordovaInterfaceImpl(this);

//³õʼ»¯CordovaWebView
cordovaWebView.init(myCordovaInterface, parser.getPluginEntries(), parser.getPreferences());

//Ö´ÐмÓÔØ¶¯×÷
cordovaWebView.loadUrl("file:///android_asset/www/InputData.html");


b.setOnClickListener(new View.OnClickListener() {

public void onClick(View v) {

//µ÷ÓÃhtmlµÄJS·½·¨
cordovaWebView.loadUrl("javascript:javaCallJs()");
}
});
}

/**
* Ϊ³õʼ»¯CordovaWebViewÌṩ²ÎÊý
*/
private static class MyCordovaInterfaceImpl extends CordovaInterfaceImpl {

private Activity mActivity;

public MyCordovaInterfaceImpl(Activity activity) {

super(activity);

mActivity = activity;
}
public Activity getActivity() {

return mActivity;
}

}

/**
* ½ÓÊÕ´ÓSecondActivity´«À´µÄÊý¾Ý£¬²¢ÇÒµ÷ÓÃhtmlJS·½·¨À´ÏÔʾ
* @param requestCode
* @param resultCode
* @param intent
*/
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);

switch (resultCode) {

case Activity.RESULT_OK:

Bundle b=intent.getExtras();
String str=b.getString("flags");
cordovaWebView.loadUrl("javascript:javaCallBackJs('"+str+"')");

break;
default:
break;
}

}

}

ÓÐûÓоõµÃʵÀý»¯CordovaWebViewµÄ·½Ê½ºÜÑÛÊ죬Æäʵ¾ÍÊǰÑCordovaActivityʵÀý»¯appViewµÄ·½·¨³éÀë³öÀ´£¬ÔÙ¸øËüÒ»¸ö¿ÉÒÔ×Ô¶¨ÒåÐÞ¸ÄλÖõÄSystemWebView£¬ÄÇÄã¾Í¿ÉÒÔ×ÔÓɵطÅÖÃËüµÄλÖÃ

ÒÔÏ´úÂëÊÇÖ÷¶¯µ÷ÓÃhtmlÀïÃæµÄJS·½·¨£¬Í¨¹ýloadUrl(javascript:+jscode);·½Ê½£¬Õâ¸öjscode¿ÉÒÔÊÇÒ»¸ö·½·¨Ò²¿ÉÒÔÊÇÒ»´®js´úÂë¡£

b.setOnClickListener(new View.OnClickListener() {  

public void onClick(View v) {

//µ÷ÓÃhtmlµÄJS·½·¨
cordovaWebView.loadUrl("javascript:javaCallJs()");
}
});

onActivityResult()ÊÇÓÃÀ´½ÓÊÕ´ÓSecondActivity»Ø´«µÄÐÅÏ¢£¬ÔÚÉÏһƪÎÄÕÂÀïÃæ£¬ÎÒÃǰÑËüдÔÚ²å¼þÀïÃæÀ´½ÓÊջص÷£¬ÄÇÏÖÔÚΪʲôҪ°ÑonActivityResult()·½·¨Ð´ÔÚFirstActivityÄØ£¿¶ÔÓÚÕâ¸öÎÊÌâÎÒÒ²ºÜ·³ÄÕ£¬ÎÒÊÔÁ˺ܶà´Î£¬²éÕÒÁËÍøÉϺܶà×ÊÁÏ£¬¿´ÁËÔ´ÂëÓָĹýÔ´Â룬µ«ÊÇSecondActivity»Ø´«µÄÐÅϢȴһֱ·µ»Øµ½FirstActivityÖУ¬ËùÒÔÎÒΨÓÐÔÚFirstActivityÖнÓÊÕÕâ¸ö»Øµ÷Intent£¬È»ºóÖ÷¶¯µ÷ÓÃJS·½·¨À´´ïµ½ÐÞ¸ÄhtmlµÄЧ¹û¡£µ«ÊÇÈç¹ûÓÃcordovaActivity¼ÓÔØµÄʱºòÈ´²»»á³öÏÖÕâ¸öÎÊÌâ¡££¨Õâ¸öÎÊÌâÒ²ÒòΪÎÒÄÜÁ¦²»¹»£¬¶øÇÒҲûÓÐÉîÇÐÀí½âÔ´Âë¶øÎÞ·¨½â¾ö£¬µ«ÊÇÎÒ»áŬÁ¦È¥¸ú½øµÄ£¡£¡£©

ºÃ£¡·´ÕýÎҵĽâ¾ö·½·¨ÊÇÔÚFirstActivityÀï½ÓÊջص÷ÐÅÏ¢£º

public void onActivityResult(int requestCode, int resultCode, Intent intent) {  
super.onActivityResult(requestCode, resultCode, intent);

switch (resultCode) {

case Activity.RESULT_OK:

Bundle b=intent.getExtras();
String str=b.getString("flags");
cordovaWebView.loadUrl("javascript:javaCallBackJs('"+str+"')");

break;
default:
break;
}

}

InputData.html

<!DOCTYPE html>  
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />

<title>InputData</title>

<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8">

document.addEventListener("deviceready", onDeviceReady, true);

function onDeviceReady(){
//»ñÈ¡ÊäÈë¿òºÍ°´Å¥¶ÔÏó
var text1 = document.getElementById("name");
var text2 = document.getElementById("Number");
var text3 = document.getElementById("Age");
var btn =document.getElementById("Enter");
var output = document.getElementById("output");
//¸ø¶ÔÏó¼ÓÉϼàÌý
btn.addEventListener('click', onClick);

function onClick(){
//»ñÈ¡ÊäÈë¿òÖµ
var Name =text1.value;
var Number =text2.value;
var Age =text3.value;
var success = function(message) {
alert("Success" + message);
output.innerHTML = message;
};
var error = function(message) { alert("Oopsie! " + message); };

//Óòå¼þµ÷ÓÃÖµ
//dataTransportPlugins.createEvent(Name, Number, Age, success, error);
navigator.dataTransportJs.demo(Name, Number, Age, success, error);
}
}
</script>
<script type="text/javascript" charset="utf-8">
function javaCallBackJs(str){

var output = document.getElementById("output2");
output.innerHTML = str;
}
function javaCallJs(){

var output = document.getElementById("output1");
output.innerHTML = "this is from Button of FirstActivity"
}
</script>
</head>


<body>

<p>
<label for="name"> Name: </label>
<input type="text" name="input" id="name" value="" />
</p>
<p>
<label for="name"> Number: </label>
<input type="text" name="input" id="Number" value="" />
</p>
<p>
<label for="name"> Age: </label>
<input type="text" name="input" id="Age" value="" />
</p>

<button id="Enter">Enter</button>
<p>
Button Message : <div id="output1" style="color:red;"></div>
</p>
<p>
SeconeActivity Message : <div id="output2" style="color:red;"></div>
</p>
</body>
</html>

ÏÂÃæÁ½¸öJS·½·¨·Ö±ðÊÇsecondActivity»Ø´«Ê±ºòµ÷ÓõĺͰ´È·ÈÏButtonʱºòµ÷Óõķ½·¨

<script type="text/javascript" charset="utf-8">  
function javaCallBackJs(str){

var output = document.getElementById("output2");
output.innerHTML = str;
}
function javaCallJs(){

var output = document.getElementById("output1");
output.innerHTML = "this is from Button of FirstActivity"
}
</script>

×îºó¾Í¿´¿´Ôõô¹æ·¶µÄ×¢²á²å¼þ£¬ÔÚÉÏһƪÎÄÕÂÊÇͨ¹ý±©Â¶js½Ó¿ÚÀ´ÒýÈë²å¼þ£º

<script type="text/javascript" src="js/dataTransportJs.js"></script>  

ÏÖÔڵķ½·¨ÊÇͨ¹ýÔÚassets/www/cordova_plugins.jsÒýÈ붨ÒåµÄjsÎļþ

cordova.define('cordova/plugin_list', function(require, exports, module) {  
module.exports = [
{
"file": "plugins/cordova-plugin-whitelist/whitelist.js",
"id": "cordova-plugin-whitelist.whitelist",
"runs": true
},
{
"file": "plugins/cordova-plugin-whitelist/dataTransportJs.js",
"id": "org.apache.cordova.dataTransportJs",
"merges": [
"navigator.dataTransportJs"
]
},
];
module.exports.metadata =
// TOP OF METADATA
{
"cordova-plugin-whitelist": "1.0.0"
}
// BOTTOM OF METADATA
});

module.exportsÖеڶþ¸öʵÌå¾ÍÊǶ¨ÒåµÄjs,ÆäÖУº

file£ºÊÇjs²å¼þ½Ó¿ÚµÄ·¾¶,ͳһ¶¼·ÅÔÚpluginsÎļþ¼ÐÏÂ

id£ºÊǶ¨ÒåµÄÒ»¸öid

merges£ºÊÇÔÚhtmlÖе÷ÓõIJå¼þ(¿ÉÒÔ¿´htmlÖе÷ÓõĵÄÓï¾ä)

dataTransportJs.js´úÂëÆäʵ¸úÉÏһƪÎÄÕÂÖеIJ¶à£¬Ö»ÊǶàÁËһЩ¶¨Ò壬Èç¹ûÄã»ánode.js¾ÍºÜÈÝÒ×ÄÜÀí½â¡£

dataTransportJs.jsʵÏÖ´úÂ룺

//¶¨ÒåÒ»¸öÄ£¿é  
cordova.define("org.apache.cordova.dataTransportJs", function(require, exports, module) {

//¼ÓÔØÄ£¿é
var exec = require('cordova/exec');


module.exports = {

demo: function(Name, Number, Age, successCallback, errorCallback) {
exec(
successCallback,
errorCallback,
'DataTransportPlugin',
'dataTransport',
[{
"Name": Name,
"Number": Number,
"Age": Age,
}]
);
},
};
});

×îºó»¹ÊÇÐèÒªÔÚconfig.xmlÖж¨Ò壺

<feature name="DataTransportPlugin">  
<param name="android-package" value="ivy.cordova.example.plugins.DataTransportPlugin" />
</feature>

¿´µ½ÕâÀïÄã¿ÉÄÜ»áÓиöÒÉÎÊ£¬¼ÈȻֻÊÇÓÃÒ»¸öSystemWebView£¬ÄÇΪʲôҪÓÃcordova£¬Ö±½ÓÔÚActivityÀïÃæÓÃWebView¾ÍºÃÁË¡£Êǵģ¡ÎÒÒ²ÕâôÈÏΪ£¡ËùÒÔµ½ÏÖÔÚÎÒ¶¼»¹Ã»ÓÐÌå»áµ½cordovaµÄºÃ´¦= =¡£µÈÏîÄ¿×öÍêºóÓ¦¸Ã¾ÍÓнáÂÛÁË£¡

   
5656 ´Îä¯ÀÀ       28
 
Ïà¹ØÎÄÕÂ

ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖÓë̽ÌÖ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
 
Ïà¹ØÎĵµ

Android_UI¹Ù·½Éè¼Æ½Ì³Ì
ÊÖ»ú¿ª·¢Æ½Ì¨½éÉÜ
androidÅÄÕÕ¼°ÉÏ´«¹¦ÄÜ
Android½²ÒåÖÇÄÜÊÖ»ú¿ª·¢
Ïà¹Ø¿Î³Ì

Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
Androidϵͳ¿ª·¢
AndroidÓ¦Óÿª·¢
ÊÖ»úÈí¼þ²âÊÔ
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

androidÈË»ú½çÃæÖ¸ÄÏ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
AndroidÊÖ»ú¿ª·¢£¨¶þ£©
AndroidÊÖ»ú¿ª·¢£¨Èý£©
AndroidÊÖ»ú¿ª·¢£¨ËÄ£©
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖ̽ÌÖ
ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
ÊÖ»úÈí¼þ×Ô¶¯»¯²âÊÔÑо¿±¨¸æ

Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
AndroidÓ¦Óÿª·¢
Androidϵͳ¿ª·¢
ÊÖ»úÈí¼þ²âÊÔ
ǶÈëʽÈí¼þ²âÊÔ
AndroidÈí¡¢Ó²¡¢ÔÆÕûºÏ

ÁìÏÈIT¹«Ë¾ android¿ª·¢Æ½Ì¨×î¼Ñʵ¼ù
±±¾© Android¿ª·¢¼¼Êõ½ø½×
ijÐÂÄÜÔ´ÁìÓòÆóÒµ Android¿ª·¢¼¼Êõ
ijº½Ì칫˾ Android¡¢IOSÓ¦ÓÃÈí¼þ¿ª·¢
°¢¶û¿¨ÌØ LinuxÄÚºËÇý¶¯
°¬Ä¬Éú ǶÈëʽÈí¼þ¼Ü¹¹Éè¼Æ
Î÷ÃÅ×Ó Ç¶Èëʽ¼Ü¹¹Éè¼Æ