Head First Python(移动应用开发)

来源:互联网 发布:外国人在淘宝买东西 编辑:程序博客网 时间:2024/05/21 01:54

移动应用开发

按照书中的步骤安装了安卓虚拟机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 jsonimport athletemodelimport yatenames = 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 androidapp=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 androidimport jsonimport 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().resultstatus_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 cgiimport jsonimport athletemodelimport yateathletes = athletemodel.get_from_store()form_data = cgi.FieldStorage()athlete_name = form_data['which_athlete'].valueprint(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就会显示新增加的脚本。



0 0
原创粉丝点击