<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>润物无声 &#187; Script</title>
	<atom:link href="http://blog.zhourunsheng.com/tag/script/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.zhourunsheng.com</link>
	<description>天空一朵雨做的云</description>
	<lastBuildDate>Sat, 08 May 2021 05:17:21 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.41</generator>
	<item>
		<title>SL4A 之实现原理解析</title>
		<link>http://blog.zhourunsheng.com/2011/09/sl4a-%e4%b9%8b%e5%ae%9e%e7%8e%b0%e5%8e%9f%e7%90%86%e8%a7%a3%e6%9e%90/</link>
		<comments>http://blog.zhourunsheng.com/2011/09/sl4a-%e4%b9%8b%e5%ae%9e%e7%8e%b0%e5%8e%9f%e7%90%86%e8%a7%a3%e6%9e%90/#comments</comments>
		<pubDate>Sun, 11 Sep 2011 13:17:08 +0000</pubDate>
		<dc:creator><![CDATA[润物无声]]></dc:creator>
				<category><![CDATA[移动开发]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[SL4A]]></category>

		<guid isPermaLink="false">http://blog.zhourunsheng.com/?p=748</guid>
		<description><![CDATA[<p>关于SL4A的简介和在Android系统的安装及使用，请参考我的上一篇博文《Android 脚本设计之 SL4 [&#8230;]</p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2011/09/sl4a-%e4%b9%8b%e5%ae%9e%e7%8e%b0%e5%8e%9f%e7%90%86%e8%a7%a3%e6%9e%90/">SL4A 之实现原理解析</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></description>
				<content:encoded><![CDATA[<p>关于SL4A的简介和在Android系统的安装及使用，请参考我的上一篇博文<a title="Android 脚本设计之 SL4A" href="http://blog.zhourunsheng.com/2011/09/android-%e8%84%9a%e6%9c%ac%e8%ae%be%e8%ae%a1%e4%b9%8b-sl4a/">《Android 脚本设计之 SL4A》</a>,本篇来分析其内部的实现机制。</p>
<h3>深入理解SL4A</h3>
<p>SL4A架构实现了本地脚本和原生态Android程序的内部消息通信，所以任何本地脚本语言，只要实现了这套兼容的JSON RPC通信接口，就可以呼叫SL4A的RPC Server端程序。至于为什么要选用JSON，及这种格式的优点和特征，此处就不详细叙述了，大家可以查看<a href="http://www.json.org/">JSON</a>官网。</p>
<blockquote><p>“JavaScript Object Notation (JSON) is a lightweight, text-based,<br />
language-independent data interchange format. It was derived from the<br />
ECMAScript Programming Language Standard. JSON defines a small<br />
set of formatting rules for the portable representation of structured data.<br />
JSON can represent four primitive types (strings, numbers, booleans,<br />
and null) and two structured types (objects and arrays).”</p></blockquote>
<p><span id="more-748"></span></p>
<h3>SL4A总体架构</h3>
<p><a href="http://blog.zhourunsheng.com/wp-content/uploads/2011/09/SL4A_architecture_overview.png"><img class="alignnone size-full wp-image-750" title="SL4A_architecture_overview" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/09/SL4A_architecture_overview.png" alt="" width="734" height="342" /></a></p>
<p>从上图可以看出，SL4A总体包括Client和Server两部分来实现通信和整体架构的独立性，Client端负责解析本地脚本，这样只要本地脚本实现了兼容的接口，就可以方便实现脚本语言的扩展，而Server端则封装了Android原生态程序的设计，即使在android底层API发生API变化的时候，Client端也基本不会受到影响，Client把脚本中解析出来的函数调用通过RPC通信，远程呼叫Server端代理接口，然后由Server调用原生态的Android API（Android Facade架构）来完成具体的功能，在调用结束后，Server端将执行结果反馈给Client端。</p>
<p>整个执行过程如下：</p>
<pre> -­‐-­‐ Script Interpreter
-­‐-­‐-­‐-­‐ Client/Caller/Consumer Script
-­‐-­‐-­‐-­‐-­‐-­‐ "Android" Script Object (locally wraps RPC calls) -­‐ Local Proxy
-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ Remote Procedure Calls (RPC) – Exchanges contain a JSON payload
-­‐-­‐-­‐-­‐-­‐-­‐ Android API Java Facade -­‐ Remote Proxy
-­‐-­‐-­‐-­‐ API Server/Provider -­‐ Android Java application
-­‐-­‐ The Android Platform itself</pre>
<h3>Local Proxy 的实现机制</h3>
<p>其实每个本地模块都封装实现了一个android实体类，然后开放其调用接口，内部通过RPC与SL4A Server端通信。</p>
<p><strong>Python 模块（android.py）之实现</strong>：</p>
<pre># Copyright (C) 2009 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

__author__ = 'Damon Kohler &lt;damonkohler@gmail.com&gt;'

import collections
import json
import os
import socket
import sys

PORT = os.environ.get('AP_PORT')
HOST = os.environ.get('AP_HOST')
HANDSHAKE = os.environ.get('AP_HANDSHAKE')
Result = collections.namedtuple('Result', 'id,result,error')

class Android(object):

  def __init__(self, addr=None):
    if addr is None:
      addr = HOST, PORT
    self.conn = socket.create_connection(addr)
    self.client = self.conn.makefile()
    self.id = 0
    if HANDSHAKE is not None:
      self._authenticate(HANDSHAKE)

  def _rpc(self, method, *args):
    data = {'id': self.id,
            'method': method,
            'params': args}
    request = json.dumps(data)
    self.client.write(request+'n')
    self.client.flush()
    response = self.client.readline()
    self.id += 1
    result = json.loads(response)
    if result['error'] is not None:
      print result['error']
    # namedtuple doesn't work with unicode keys.
    return Result(id=result['id'], result=result['result'],
                  error=result['error'], )

  def __getattr__(self, name):
    def rpc_call(*args):
      return self._rpc(name, *args)
    return rpc_call</pre>
<p><strong>BeanShell 模块（android.bsh）之实现</strong>：</p>
<pre>// Copyright (C) 2009 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

import org.json.*;

Android() {
  String AP_PORT = System.getenv().get("AP_PORT");
  String AP_HOST = System.getenv().get("AP_HOST");
  String AP_HANDSHAKE = System.getenv().get("AP_HANDSHAKE");
  Socket conn = new Socket(AP_HOST, Integer.decode(AP_PORT));
  BufferedReader in = new BufferedReader(
      new InputStreamReader(conn.getInputStream(), "8859_1"), 1 &lt;&lt; 13);
  OutputStream out_stream = new BufferedOutputStream(
      conn.getOutputStream(), 1 &lt;&lt; 13);
  PrintWriter out = new PrintWriter(
      new OutputStreamWriter(out_stream, "8859_1"), true);
  int id = 0;

  call(String method, JSONArray params) {
    JSONObject request = new JSONObject();
    request.put("id", id);
    request.put("method", method);
    request.put("params", params);
    out.write(request.toString() + "n");
    out.flush();
    String data = in.readLine();
    if (data == null) {
      return null;
    }
    return new JSONObject(data);
  }

  call(String method) {
    JSONArray args = new JSONArray();
    call(method, args);
  }

  call(String method, Object arg1) {
    JSONArray args = new JSONArray();
    args.put(arg1);
    call(method, args);
  }

  call(String method, Object arg1, Object arg2) {
    JSONArray args = new JSONArray();
    args.put(arg1);
    args.put(arg2);
    call(method, args);
  }

  call(String method, Object arg1, Object arg2, Object arg3) {
    JSONArray args = new JSONArray();
    args.put(arg1);
    args.put(arg2);
    args.put(arg3);
    call(method, args);
  }

  call(String method, Object arg1, Object arg2, Object arg3, Object arg4) {
    JSONArray args = new JSONArray();
    args.put(arg1);
    args.put(arg2);
    args.put(arg3);
    args.put(arg4);
    call(method, args);
  }

  JSONArray handshake = new JSONArray();
  handshake.put(AP_HANDSHAKE);
  call("_authenticate", handshake);

  return this;
}</pre>
<p><strong>JavaScript 模块（android.js）之实现</strong>：</p>
<pre>/*
 * Copyright 2009 Brice Lambson
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

var AP_PORT = java.lang.System.getenv("AP_PORT");
var AP_HOST = java.lang.System.getenv("AP_HOST");
var AP_HANDSHAKE = java.lang.System.getenv("AP_HANDSHAKE");

load('/sdcard/com.googlecode.rhinoforandroid/extras/rhino/json2.js');

function Android() {

  this.connection = new java.net.Socket(String(AP_HOST), AP_PORT),
  this.input = new java.io.BufferedReader(
      new java.io.InputStreamReader(this.connection.getInputStream(), "8859_1"),
                                    1 &lt;&lt; 13),
  this.output = new java.io.PrintWriter(new java.io.OutputStreamWriter(
      new java.io.BufferedOutputStream(this.connection.getOutputStream(),
                                       1 &lt;&lt; 13),
      "8859_1"), true),
  this.id = 0,

  this.rpc = function(method, args) {
    this.id += 1;
    var request = JSON.stringify({'id': this.id, 'method': method,
                                  'params': args});
    this.output.write(request + 'n');
    this.output.flush();
    var response = this.input.readLine();
    return eval("(" + response + ")");
  },

  this.__noSuchMethod__ = function(id, args) {
    var response = this.rpc(id, args);
    if (response.error != null) {
      throw response.error;
    }
    return response.result;
  }

  this._authenticate(String(AP_HANDSHAKE));
}</pre>
<p><strong>android-cruft（ndk-to-sl4a.c）之C语言实现</strong>：</p>
<pre>// Released into the public domain, 15 August 2010

// This program demonstrates how a C application can access some of the Android
// API via the SL4A (Scripting Languages for Android, formerly "ASE", or Android
// Scripting Environment) RPC mechanism.  It works either from a host computer
// or as a native binary compiled with the NDK (rooted phone required, I think)

// SL4A is a neat Android app that provides support for many popular scripting
// languages like Python, Perl, Ruby and TCL.  SL4A exposes a useful subset of
// the Android API in a clever way: by setting up a JSON RPC server.  That way,
// each language only needs to implement a thin RPC client layer to access the
// whole SL4A API.

// The Android NDK is a C compiler only intended for writing optimized
// subroutines of "normal" Android apps written in Java.  So it doesn't come
// with any way to access the Android API.

// This program uses the excellent "Jansson" JSON library to talk to SL4A's
// RPC server, effectively adding native C programs to the list of languages
// supported by SL4A.

// To try it, first install SL4A: http://code.google.com/p/android-scripting/
//
// Start a private server with View-&gt;Interpreters-&gt;Start Server
//
// Note the port number the server is running on by pulling down the status
// bar and tapping "SL4A service". 

// This program works just fine as either a native Android binary or from a
// host machine.

// ------------

// To compile on an ordinary linux machine, first install libjansson.  Then:

// $ gcc -ljansson ndk-to-sl4a.c -o ndk-to-sl4a

// To access SL4A on the phone use "adb forward tcp:XXXXX tcp:XXXXX" to port
// forward the SL4A server port from your host to the phone.  See this
// page for more details:
// http://code.google.com/p/android-scripting/wiki/RemoteControl

// ------------

// To compile using the NDK:
//   1. Make sure you can compile "Hello, world" using the NDK.  See:
//      http://credentiality2.blogspot.com/2010/08/native-android-c-program-using-ndk.html
//
//   2. If you followed the above instructions, you have a copy of the agcc.pl
//      wrapper that calls the NDK's gcc compiler with the right options for
//      standalone apps.
//
//   3. Unpack a fresh copy of the jansson sources.  Tell configure to build for
//      Android:
//
// $ CC=agcc.pl ./configure --host=arm
// $ make
//
//   4. Cross your fingers and go!  (I'm quite certain there's a more elegant
//      way to do this)
//
// $ agcc.pl -I/path/to/jansson-1.3/src -o ndk-to-sl4a-arm ndk-to-sl4a.c /path/to/jansson-1.3/src/*.o
//
//   5. Copy to the phone and run it with the port of the SL4A server!

#include &lt;stdio.h&gt;
#include &lt;jansson.h&gt;
#include &lt;unistd.h&gt;
#include &lt;string.h&gt;

#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;netinet/in.h&gt;
#include &lt;netdb.h&gt; 

// This mimics SL4A's android.py, constructing a JSON RPC object and
// sending it to the SL4A server.
int sl4a_rpc(int socket_fd, char *method, json_t *params) {
  static int request_id = 0; // monotonically increasing counter

  json_t *root = json_object();

  json_object_set(root, "id", json_integer(request_id));
  request_id++;

  json_object_set(root, "method", json_string(method));

  if (params == NULL) {
    params = json_array();
    json_array_append(params, json_null());
  }

  json_object_set(root, "params", params);

  char *command = json_dumps(root, JSON_PRESERVE_ORDER | JSON_ENSURE_ASCII);
  printf("command string:'%s'n", command);

  write(socket_fd, command, strlen(command));
  write(socket_fd, "n", strlen("n"));

  // At this point we just print the response, but really we should buffer it
  // up into a single string, then pass it to json_loads() for decoding.
  printf("Got back:n");
  while (1) {
    char c;
    read(socket_fd, &amp;c, 1);
    printf("%c", c);
    if (c == 'n') {
      break;
    }
  }
  fflush(stdout);
  return 0;
}

// This function is just boilerplate TCP socket setup code
int init_socket(char *hostname, int port) {
  int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
  if (socket_fd == -1) {
    perror("Error creating socket");
    return 0;
  }

  struct hostent *host = gethostbyname(hostname);
  if (host == NULL) {
    perror("No such host");
    return -1;
  }

  struct sockaddr_in socket_address;

  int i;
  for (i=0; i &lt; sizeof(socket_address); i++) {
    ((char *) &amp;socket_address)[i] = 0;
  }

  socket_address.sin_family = AF_INET;

  for (i=0; i &lt; host-&gt;h_length; i++) {
    ((char *) &amp;socket_address.sin_addr.s_addr)[i] = ((char *) host-&gt;h_addr)[i];
  }

  socket_address.sin_port = htons(port);

  if (connect(socket_fd, (struct sockaddr *) &amp;socket_address, sizeof(socket_address)) &lt; 0) {
    perror("connect() failed");
    return -1;
  }

  return socket_fd;
}

main(int argc, char **argv) {
  int port = 0;
  if (argc != 2) {
    printf("Usage: %s portn", argv[0]);
    return 1;
  }
  port = atoi(argv[1]);

  int socket_fd = init_socket("localhost", port);
  if (socket_fd &lt; 0) return 2;

  json_t *params = json_array();
  json_array_append(params, json_string("w00t!"));
  sl4a_rpc(socket_fd, "makeToast", params);
}</pre>
<h3>Hello Android之多语言实现</h3>
<p>在文章的最后，给大家一个经典的Hello Android多语言实现，O(∩_∩)O哈哈~</p>
<pre>BeanShell:
source("/sdcard/com.googlecode.bshforandroid/extras/bsh/android.bsh");
droid = Android();
droid.call("makeToast", "Hello Android!");

JavaScript:
load("/sdcard/com.googlecode.rhinoforandroid/extras/rhino/android.js");
var droid = new Android();
droid.makeToast("Hello Android!");

Perl:
use Android;
my $a = Android--&gt;new();
$a--&gt;makeToast("Hello Android!");

Python:
import android
andy = android.Android()
andy.makeToast("Hello Android!")

Ruby:
droid = Android.new
droid.makeToast "Hello Android!"

TCL:
package require android
set android [android new]
$android makeToast "Hello Android!"</pre>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2011/09/sl4a-%e4%b9%8b%e5%ae%9e%e7%8e%b0%e5%8e%9f%e7%90%86%e8%a7%a3%e6%9e%90/">SL4A 之实现原理解析</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zhourunsheng.com/2011/09/sl4a-%e4%b9%8b%e5%ae%9e%e7%8e%b0%e5%8e%9f%e7%90%86%e8%a7%a3%e6%9e%90/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Android 脚本设计之 SL4A</title>
		<link>http://blog.zhourunsheng.com/2011/09/android-%e8%84%9a%e6%9c%ac%e8%ae%be%e8%ae%a1%e4%b9%8b-sl4a/</link>
		<comments>http://blog.zhourunsheng.com/2011/09/android-%e8%84%9a%e6%9c%ac%e8%ae%be%e8%ae%a1%e4%b9%8b-sl4a/#comments</comments>
		<pubDate>Sun, 11 Sep 2011 03:33:27 +0000</pubDate>
		<dc:creator><![CDATA[润物无声]]></dc:creator>
				<category><![CDATA[移动开发]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[SL4A]]></category>

		<guid isPermaLink="false">http://blog.zhourunsheng.com/?p=719</guid>
		<description><![CDATA[<p>什么是SL4A SL4A的全称为Scripting Layer for Android, 顾名思义就是Andr [&#8230;]</p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2011/09/android-%e8%84%9a%e6%9c%ac%e8%ae%be%e8%ae%a1%e4%b9%8b-sl4a/">Android 脚本设计之 SL4A</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></description>
				<content:encoded><![CDATA[<h3>什么是SL4A</h3>
<p>SL4A的全称为Scripting Layer for Android, 顾名思义就是Android的脚本架构层，它的目的就是可以用熟知的脚本开发语言来开发Android应用程序。其工作原理基于RPC远程调用，通过本地的脚本解析器和远端的原生态Android Server层的APK进行信息交互，即实现一个远程代理，把本地脚本的函数调用通过json格式的封装，传递给远程原生态Server APK进行实际的android系统函数呼叫，最后将操作的执行结果反馈给本地脚本解析器，然后再在终端显示出运行结果。</p>
<h3>SL4A适用场景</h3>
<ul>
<li>RAD programming，即 rapid application development，快速原型开发，进行工程项目的可行性分析</li>
<li>编写测试脚本，通常代码量都比较小，可方便实现</li>
<li>开发工具软件包，来实现一些快捷的功能</li>
</ul>
<p><span id="more-719"></span></p>
<h3>SL4A环境安装</h3>
<ol>
<li>下载安装 <a href="http://code.google.com/p/android-scripting/downloads/list">sl4a</a>  APK，目前的版本是 <a href="http://android-scripting.googlecode.com/files/sl4a_r4.apk">sl4a_r4.apk</a>
<pre>C:UsersCarey.RS.Zhou&gt;adb install -r C:UsersCarey.RS.ZhouDesktopsl4a_r4.apk
156 KB/s (858471 bytes in 5.355s)
        pkg: /data/local/tmp/sl4a_r4.apk
Success</pre>
</li>
<li>在APP列表中找到 sl4a 并运行,接受 Usage Tracking，选择 Accept<br />
<img class="alignnone size-medium wp-image-725" title="sl4a-run-usage-tracking" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/09/sl4a-run-usage-tracking-200x300.png" alt="" width="200" height="300" /></li>
<li>程序默认只安装了一个shell环境，进入的步骤为【Menu】【View】【Interpreters】【Shell】<br />
在shell命令行中执行ps命令后的执行结果如下，说明程序安装正确<br />
<img class="alignnone size-medium wp-image-727" title="sl4a-shell-ps" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/09/sl4a-shell-ps-300x200.png" alt="" width="300" height="200" /></li>
<li>安装sl4a的本地脚本解析器，我们以安装python环境为例来说明，其他解析器的安装类似<br />
进入的步骤为【Menu】【View】【Interpreters】【Add】<br />
<img class="alignnone size-medium wp-image-729" title="sl4a-add-python" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/09/sl4a-add-python-200x300.png" alt="" width="200" height="300" /></li>
<li>选择Python之后，后台开始下载PythonForAndroid的APK，完成后点击安装<br />
<img class="alignnone size-medium wp-image-731" title="sl4a-python-download" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/09/sl4a-python-download-200x300.png" alt="" width="200" height="300" /></li>
<li>安装PythonForAndroid的APK之后，依次选择【Open】【Install】按钮，此时会进入第二阶段的安装过程，即安装python的附加module<br />
<img class="alignnone size-medium wp-image-733" title="sl4a-python-open" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/09/sl4a-python-open-200x300.png" alt="" width="200" height="300" /><img class="alignnone size-medium wp-image-734" title="sl4a-python-install-modules" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/09/sl4a-python-install-modules-200x300.png" alt="" width="200" height="300" /><img class="alignnone size-medium wp-image-735" title="sl4a-pyhon-download-modules" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/09/sl4a-pyhon-download-modules-200x300.png" alt="" width="200" height="300" /></li>
<li>全部安装之后回到该界面，按钮由刚才的Install变成现在的Uninstall，<span style="color: #ff0000;">特别提醒，千万别点击Uninstall按钮</span>，不然就把刚才下载的module都卸载了，然后就悲剧啦，退出该界面即可<br />
<img class="alignnone size-medium wp-image-737" title="sl4a-pythomodeul-install" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/09/sl4a-pythomodeul-install-200x300.png" alt="" width="200" height="300" /></li>
<li>我们再次进入Interpreters，发现不只是Shell了，还多了一个Python 2.6.2，说明python环境搭建好了，现在就可以在android上面进行python脚本编写了，点击进去看看<br />
<img class="alignnone size-medium wp-image-739" title="sl4a-python-allok" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/09/sl4a-python-allok-200x300.png" alt="" width="200" height="300" /><img class="alignnone size-medium wp-image-740" title="sl4a-python-print-carey" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/09/sl4a-python-print-carey-300x200.png" alt="" width="300" height="200" /></li>
<li>到此为止，环境都ok了，我们小小测试一下，显示个Toast出来，看看是多么的简单，剩下的就请大家好好发挥吧，比起Java原生态程序的编写是不是方便了很多啊<br />
<img class="alignnone size-medium wp-image-742" title="sl4a-pyhon-maketoast" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/09/sl4a-pyhon-maketoast-300x200.png" alt="" width="300" height="200" /></li>
</ol>
<h3>参考文献</h3>
<ul>
<li>SL4A Home：<a href="http://code.google.com/p/android-scripting/">http://code.google.com/p/android-scripting/</a></li>
</ul>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2011/09/android-%e8%84%9a%e6%9c%ac%e8%ae%be%e8%ae%a1%e4%b9%8b-sl4a/">Android 脚本设计之 SL4A</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zhourunsheng.com/2011/09/android-%e8%84%9a%e6%9c%ac%e8%ae%be%e8%ae%a1%e4%b9%8b-sl4a/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>巧用DOS脚本删除工程的SVN信息</title>
		<link>http://blog.zhourunsheng.com/2011/07/%e5%b7%a7%e7%94%a8dos%e8%84%9a%e6%9c%ac%e5%88%a0%e9%99%a4%e5%b7%a5%e7%a8%8b%e7%9a%84svn%e4%bf%a1%e6%81%af/</link>
		<comments>http://blog.zhourunsheng.com/2011/07/%e5%b7%a7%e7%94%a8dos%e8%84%9a%e6%9c%ac%e5%88%a0%e9%99%a4%e5%b7%a5%e7%a8%8b%e7%9a%84svn%e4%bf%a1%e6%81%af/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 12:33:52 +0000</pubDate>
		<dc:creator><![CDATA[润物无声]]></dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[DOS]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[SVN]]></category>

		<guid isPermaLink="false">http://blog.zhourunsheng.com/?p=376</guid>
		<description><![CDATA[<p>从网络上的SVN服务器上面把代码下载下来，有时候想完全去除掉该工程项目的svn信息，我们都知道svn信息保存在 [&#8230;]</p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2011/07/%e5%b7%a7%e7%94%a8dos%e8%84%9a%e6%9c%ac%e5%88%a0%e9%99%a4%e5%b7%a5%e7%a8%8b%e7%9a%84svn%e4%bf%a1%e6%81%af/">巧用DOS脚本删除工程的SVN信息</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></description>
				<content:encoded><![CDATA[<p>从网络上的SVN服务器上面把代码下载下来，有时候想完全去除掉该工程项目的svn信息，我们都知道svn信息保存在工程项目中的每个隐藏的.svn文件夹下面，如果手动删除的话，有可能删除不完全，导致重新导入的时候会出现错误，本文分享一个实用的dos脚本，只要将其放置到工程项目的根目录下，单击运行一次即可，就会全部清除掉隐藏的svn文件信息。</p>
<p>代码如下：</p>
<pre>@echo off
for /r %%a in (.) do if exist %%a.svn rd /s/q %%a.svn
pause
@echo on</pre>
<p>将其拷贝到本地的文本文件中，命名为removesvn.bat即可。</p>
<p>然后将 removesvn.bat 放到需要清除svn信息的工程文件夹中运行一次就ok。</p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2011/07/%e5%b7%a7%e7%94%a8dos%e8%84%9a%e6%9c%ac%e5%88%a0%e9%99%a4%e5%b7%a5%e7%a8%8b%e7%9a%84svn%e4%bf%a1%e6%81%af/">巧用DOS脚本删除工程的SVN信息</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zhourunsheng.com/2011/07/%e5%b7%a7%e7%94%a8dos%e8%84%9a%e6%9c%ac%e5%88%a0%e9%99%a4%e5%b7%a5%e7%a8%8b%e7%9a%84svn%e4%bf%a1%e6%81%af/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
