您的位置:首页 > 编程语言 > Python开发

Head First Python(移动应用开发)

2014-12-18 16:18 330 查看
移动应用开发

按照书中的步骤安装了安卓虚拟机AVD,但是发现AVD的运行速度非常慢。索性直接在安卓手机上运行程序。前期的准备使得android运行python程序,详细在http://blog.csdn.net/cfcf0517/article/details/42002485。

测试驱动

首先为athletemodel增加一个函数get_names_from_store()

def get_names_from_store():
athletes = get_from_store()  #从pickle得到数据
response = [athletes[each_ath].name for each_ath in athletes]#从数据抽取一个选手名列表
return(response)
编写generate_names.py

import json
import athletemodel
import yate
names = athletemodel.get_names_from_store()  #从模型得到数据
print(yate.start_response('application/json')) #适当的"content-type:"行
print(json.dumps(sorted(names)))  #对"names"排序,转换为json,发送到stdout。
运行web服务器,在web浏览器的localhost:8080可以查看到一个名字列表。

SL4A Android API

通过6个Android API调用,可以在对话框中创建一个选项列表。

import android
app=android.Android()
app.dialogCreatAlert("Select an athlete")
app.dialogSetSingChoiceItems(['mikey','sarah','james','julie'])
app.dialogSetPositiveButtonText("Select")
app.dialogSetNegativeButtonText("Quit")
app.dialogShow()
resp=app.dialogGetResponse().result
向Web服务器查询名字列表,作为一个JSON数组返回,在智能手机上显示这个列表。原书中的代码是导入urilib和urllib2,开始一直不能运行起来,在sl4a中使用shell运行可以看到urlopen报错,后来查询发现在python3.x版本中没有urllib2,所以在源码的中做了修改,用红色标出。

import android
import json
import time
<span style="color:#ff0000;">import urllib</span>

hello_msg="Welcome to Coach Kelly's Timing App"
list_title='Here is your list of athletes:'
quit_msg="Quitting Coach Kelly's App."

web_server='http://10.10.138.89:8080'

get_names_cgi='/cgi-bin/generate_names.py'

def send_to_server(url,post_data=None):
if post_data:
page=<span style="color:#ff0000;">urllib.urlopen</span>(url,<span style="color:#ff0000;">urllib.urlencode</span>(post_data))
else:
page=<span style="color:#ff0000;">urllib.urlopen</span>(url)
return(page.read().decode("utf8"))

app=android.Android()

def status_update(msg,how_long=2):
app.makeToast(msg)
time.sleep(how_long)

athlete_names=sorted(json.loads(send_to_server(web_server+get_names_cgi)))
status_update(hello_msg)
app.dialogCreateAlert(list_title)
app.dialogSetSingleChoiceItems(athlete_names)
app.dialogSetPositiveButtonText("Select")
app.dialogSetNegativeButtonText("Quit")
app.dialogShow()
resp=app.dialogGetResponse().result
status_update(quit_msg)
在sl4a中运行会先显示一个hello_msg,然后出现下面的结果,退出是会显示一个quit_msg。



在android上选择列表

点击第一个按钮时,dialogGetResponse()调用的结果会设置为positive(正),点击第二个设置为negative(负)。

dialogGetSelectedItesm()调用会返回所选选手列表项的索引值。

如果点击了positive按钮,可以索引选手名列表查看选择的选手,然后使用send_to_server()将所选的名字返送到web服务器,请求这个选手的其余数据。

下面在一个android对话框中显示从服务器返回的时间列表。

<pre name="code" class="cpp">if resp['which'] in ('positive'):
selected_athlete = app.dialogGetSelectedItems().result[0]
which_athlete = athlete_names[selected_athlete]
#下个语句将请求发送到web服务器,并提供选手名
athlete = json.loads(send_to_server(web_server + get_data_cgi,
{'which_athlete': which_athlete}))

athlete_title = athlete['Name'] + ' (' + athlete['DOB'] + '), top 3 times:'
app.dialogCreateAlert(athlete_title)
app.dialogSetItems(athlete['Top3'])
app.dialogSetPositiveButtonText('OK')
app.dialogShow()
resp = app.dialogGetResponse().result



选手数据CGI脚本

import cgi
import json
import athletemodel
import yate

athletes = athletemodel.get_from_store()
form_data = cgi.FieldStorage()
athlete_name = form_data['which_athlete'].value
print(yate.start_response('application/json'))
print(json.dumps(athletes[athlete_name].as_dict))
使用Python shell运行会出现一个TypeError。

JSON无法处理定制数据类型

解决方法是为AthleteList增加一个方法,将数据转换为一个字典,再把这个字典发回应用。

@property #修饰之后,对于类用户来说这个方法好像是一个新的属性
def as_dict(self):
return({'Name':  self.name,
'DOB':   self.dob,
'Top3':  self.top3})
还要修改generate_data.py来响应web请求是返回一个字典,而不是对象实例。

print(json.dumps(athletes[athlete_name]<span style="color:#ff0000;">.as_dict</span>))#红色标注修改增加代码部分
coachapp.py中将选手的name和DOB值包含在第二个对话框的标题中

athlete_title = athlete['Name'] + ' (' + athlete['DOB'] + '), top 3 times:'
在sl4a中运行coachapp.py,得到选手的前三个时间。



至于用手机登录电脑的ssh服务器,一直没有成功,直接USB将文件放在手机的/sl4/scripts中,打开sl4a就会显示新增加的脚本。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: