SL4A 之实现原理解析


关于SL4A的简介和在Android系统的安装及使用,请参考我的上一篇博文《Android 脚本设计之 SL4A》,本篇来分析其内部的实现机制。

深入理解SL4A

SL4A架构实现了本地脚本和原生态Android程序的内部消息通信,所以任何本地脚本语言,只要实现了这套兼容的JSON RPC通信接口,就可以呼叫SL4A的RPC Server端程序。至于为什么要选用JSON,及这种格式的优点和特征,此处就不详细叙述了,大家可以查看JSON官网。

“JavaScript Object Notation (JSON) is a lightweight, text-based,
language-independent data interchange format. It was derived from the
ECMAScript Programming Language Standard. JSON defines a small
set of formatting rules for the portable representation of structured data.
JSON can represent four primitive types (strings, numbers, booleans,
and null) and two structured types (objects and arrays).”

SL4A总体架构

从上图可以看出,SL4A总体包括Client和Server两部分来实现通信和整体架构的独立性,Client端负责解析本地脚本,这样只要本地脚本实现了兼容的接口,就可以方便实现脚本语言的扩展,而Server端则封装了Android原生态程序的设计,即使在android底层API发生API变化的时候,Client端也基本不会受到影响,Client把脚本中解析出来的函数调用通过RPC通信,远程呼叫Server端代理接口,然后由Server调用原生态的Android API(Android Facade架构)来完成具体的功能,在调用结束后,Server端将执行结果反馈给Client端。

整个执行过程如下:

 -­‐-­‐ 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

Local Proxy 的实现机制

其实每个本地模块都封装实现了一个android实体类,然后开放其调用接口,内部通过RPC与SL4A Server端通信。

Python 模块(android.py)之实现:

 

# 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 <damonkohler@gmail.com>'
 
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
  • 1
  • 2
  • 下一页

相关内容

    暂无相关文章