4JPlayer.Ver1.0-需求分析与实现方法

一、需求来源

我最近正在找android开发方面的工作,并将GTalk的状态设置为“找工作:Android开发”。A公司通过GTalk联系到我,但由于我身在魔都,而A公司位在帝都,故面试方面可能会有所不便;最终想到一个解决方案:给我出一道题,就是以图片的形式展示一小应用的需求,然后由我来实现其功能;由于A公司了解我目前还在上班中,只能利用业余时间来完成,就以一个星期为期。需求如下:4jplayer-需求

二、功能概要

  1. 欢迎界面显示图片和动态点状进度条
  2. 欢迎界面停留一段时间之后跳转到主界面
  3. 主界面由两部分组成:上面3个Tab、下面5个Button
  4. ListItem由三部分组成:图片、文字和按钮
  5. 罗列sdcard中mp3文件
  6. 从服务器获取mp3文件列表
  7. 后台下载mp3文件,并给予提示

三、需求分析与现实方法

1. 欢迎界面显示图片和动态点状进度条,停留一段时间之后跳转到主界面

  • 需求分析
    • 运行app时,首先显示的是欢迎界面
    • 欢迎界面居中显示一张静态图片和一串动态点状进度条
    • 点状进度条循环2轮之后跳转到主界面
  • 实现方法
    • 静态图片和“Loading”字符可以通过配置文件解决
    • 动态点的5种不同状态分别来自于string.xml文件中5个不同的字符串;例如:
      <string name="tv_welcome_dot_1">.</string>
      <string name="tv_welcome_dot_2">..</string>
      <string name="tv_welcome_dot_3">...</string>
      <string name="tv_welcome_dot_4">....</string>
      <string name="tv_welcome_dot_5">.....</string>
    • 新建1个名为LoadHandler的class,该class继承android.os.Handler并重写handleMessage()方法,该方法中通过接收参数使用switch-case进行分类显示string.xml中的5个不同字符串。
    • 新建1个名为LoadThread的class,该class继承java.lang.Thread并重写run()方法,在该方法中调用LoadHandler实例的sendEmptyMessageDelayed()方法来间隔性的发送消息。
    • 在该Activity的onCreate()中调用new LoadThread(loadHandle).start()开启线程。

2. 主界面由两部分组成:上面3个Tab、下面5个Button

  • 需求分析
    • 切换Tab时,中间数据变化,底部button不动。
  • 实现方法
    • 利用1个TabHost组件和1个LinearLayout组件来完成布局,其中LinearLayout组件中包含5个Button组件。
    • 通过以下方法来添加4个不同的Tab:
      // add tab named Remote
      Intent remoteIntent = new Intent();
      remoteIntent.setClass(this, RemoteListActivity.class);
      TabHost.TabSpec remoteSpec = tabHost.newTabSpec("Remote");
      remoteSpec.setIndicator("", res.getDrawable(R.drawable.tab_remote_64));
      remoteSpec.setContent(remoteIntent);
      tabHost.addTab(remoteSpec);

3. 从服务器上下载数据

  • 需求分析
    • 该过程分为两部分:第一,读取服务器上的文件;第二,将读取到的数据写入sdcard中。
  • 实现方法
    • 提供1个字符串形式的URL,通过HttpURLConnection类的getInputStream()得到InputStream。
    • 将得到的InputStream通过FileOutputStream类的write()写入到sdcard中去,当然其中会涉及到File的相关操作。

4. 从服务器获取mp3文件列表

  • 需求分析
    • 该过程分为两部分:第一,读取服务器上承载mp3文件列表的xml文件;第二,通过解析读取到的xml文件来获得mp3文件列表。
  • 实现方法
    • 该xml文件的来源为:
      http://7xl53s.com1.z0.glb.clouddn.com/download/2015/08/server/4jplayer/resources.xml
      代码片段如下:

      <resources> 
      	<resource> 
      		<id>0001</id> 
      		<mp3.name>Vincent.mp3</mp3.name> 
      		<mp3.size>7685487</mp3.size> 
      		<lrc.name>Vincent.lrc</lrc.name> 
      		<lrc.size>2428</lrc.size> 
      	</resource>
      	<resource>...</resource>
      <resources>
    • 通过继承org.xml.sax.helpers.DefaultHandler,并重写其中的startElement()、endElement()和characters()方法来新建1个名为Mp3ListContentHandler类;然后通过以下代码来实现具体的解析:
      /**
       * 传入一String,通过解析其中的标签,返回一个ArrayList对象。
       */
      public static ArrayList parserXML(String xmlContent) {
      	ArrayList mp3InfoList = new ArrayList();
      
      	SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
      	try {
      		XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader();
      		Mp3ListContentHandler mp3ListContentHandler = new Mp3ListContentHandler(mp3InfoList);
      		xmlReader.setContentHandler(mp3ListContentHandler);
      		xmlReader.parse(new InputSource(new StringReader(xmlContent)));
      
      		for (Iterator iterator = mp3InfoList.iterator(); iterator.hasNext();) {
      			Mp3Info mp3Info = (Mp3Info) iterator.next();
      			//System.out.println("mp3Info --> " + mp3Info.toString());
      		}
      	} catch (Exception e) {
      		e.printStackTrace();
      	}
      
      	return mp3InfoList;
      }

5. ListItem由三部分组成:图片、文字和按钮

  • 需求分析
    • 图片位于最左端,文字其次,按钮位于最右端。
  • 实现方法
    • 通过继承android.widget.BaseAdapter,并重写其中的getCount()、getItem()、getItemId()和getView()方法来完成布局。

6. 后台下载mp3文件,并给予提示。

  • 需求分析
    • 点击下载按钮之后,后台启动下载线程;而不是让当前界面停留,直至等到下载完成。
  • 实现方法
    • 通过继承android.app.service,并重写其中的onStartCommand()方法,在该方法中启动线程进行下载;并通过Toast.makeText()方法给予提示。

四、尚欠缺的功能

  1. 播放控制:播放、暂停、上一首、下一首
  2. 显示播放进度条,并能拖动选择播放
  3. 歌词同步
  4. 下载目录可选
  5. 扫描目录可选
  6. 多播放列表

五、源码

http://7xl53s.com1.z0.glb.clouddn.com/download/2015/08/src/4jplayer-1.0.zip

利用迅雷快速下载官方Android SDK

一、Android SDK一般的安装方法

1. 下载Adding SDK Components

访问网址developer.android.com/sdk(当然得通过特殊途径才能正常访问),下载Adding SDK Components,该路径有完整地址,可以直接通过迅雷进行快速下载;如下图所示:

2. 通过Adding SDK Components自动下载并安装Android SDK

该步骤所涉及的内容均为傻瓜操作,就不再罗嗦,截张图于下:

二、总结: Adding SDK Components为何能自动下载Android SDK

所涉及到如下两个网址:
网址一:https://dl-ssl.google.com/android/repository/repository.xml
网址二:http://dl.google.com/android/repository/

网址一对应的页面中以XML的形式展示Android SDK各个版本对应的版本号、名称、数据大小等信息;Adding SDK Components访问网址一,并将可用的SDK一并罗列出来;然后再根据对应的文件名,与网址二拼接得到SDK的完整地址,并将其下载到名为“temp”的文件夹之中,然后再进行安装。

三、迅雷快速下载Android SDK

1. 下载Adding SDK Components(与一中1完全相同)

2. 利用迅雷下载Android SDK

在浏览器中打开二中的网址一,我个人习惯的做法是:在Chrome中打开网址(将会出现未经过排版的一大堆杂乱无章的文字),然后右击页面,选择“审查元素”菜单,将出现如下所示内容:

假定用户需要下载Android SDK 2.2,找到该SDK对应的文件名“android-2.2_r02-windows.zip”,然后拼接到二中的网址二之上,即为:
http://dl.google.com/android/repository/android-2.2_r02-windows.zip
接着在迅雷中直接输入该URL进行快速下载。

3. 利用Adding SDK Components进行SDK自动安装

在Adding SDK Components解压缩的根目录下,即与“SDK Manager.exe”文件同级目录,新建名为“temp”的文件夹,再将2中的下载文件复制到该文件夹之下。

最后,重复一中2的步骤即可。

说明:Adding SDK Components自动安装Android SDK;当“temp”文件夹里的某个压缩包安装完成之后,该组件会随之删除该包;也就是说,按方法一安装无法保存SDK的安装包。

Update:

@ 2011-03-15 :
Android Developers Mirror: http://androidappdocs.appspot.com

@ 2011-04-07 :
Android SDK Source(SDK源码) : http://rgruet.free.fr/public/

教程:HomeZZ之自助更换机房

很早就对HomeZZ的“自助更换机房”感兴趣,想尝试一把,今天终于把它给做了。刚好今天又收到cosbeta的群发邮件,他提及到:现在homezz可以自助更换机房,您可以到后台去查看并操作,但是请注意,我们的自助更换只是删除您原来的主机,同时给您在指定的机房创建新的主机,所以数据需要自己备份,搬家需要自己完成,我们稍后会有详细的搬家教程!e,我不是刚搬完家嘛,不如我来写写,为HomeZZ出点微薄之力。

一、自助更换机房的实质

1. 4J的空想主义

我最开始对这功能很感兴趣,可能是由于给它YY出一套自认为完美的流程:用户新建主机 –> 系统自动将数据库和程序从旧主机移植到新主机之上 –> 系统自动删除旧主机 –> 用户手动修改A和CName记录

2. HomeZZ的实际流程

用户手动备份数据库和程序 –> 用户驱使系统删除旧主机 –> 用户新建主机 –> 用户手动移植数据库和程序与新主机之上 –> 用户手动修改A和CName记录

3. 对4J空想主义的自我批斗

我的想法太过于天真,这样实现起来难度太大,流程也太过于复杂
,移植过程中可能会出现不可预见的疑难杂症。

二、自助更换机房前的那点事儿

1. 备份数据库

首先,进入菜单:cPanel –> 数据库 –> MySQL数据库,记录下待删除数据库名、数据库用户名和用户对应密码,例如:
数据库:vcfoujco_dbnwp
用户名:vcfoujco_dbavc4j
密码:123456

其次,进入菜单:cPanel –> 数据库 –> phpMy管理,手动备份数据库中表结构和数据,具体操作如下:


注意:名为“information_schema”的数据库为默认数据库,应该不予理睬;备份其他所有由用户自行创建的数据库;例如,上文提到的vcfoujco_dbnwp。

执行完上面的5步操作之后,会下载一个包含数据库表结构和数据的sql文件到本地;这样就完成数据库备份。

解释:按上述规则进行数据备份之后,在以后执行该SQL Script进行数据还原时,将按如下步骤进行(以一张名为t的数据表为例进行阐述):
a. 判断当前数据库中表t是否存在;如果存在,就先Drop该表;如果不存在,不做操作。
b. 判断当前数据库中表t是否存在;如果不存在,就先Create表t;如果存在,不做操作。
c. insert数据到表t中。

勾选“添加 DROP TABLE / VIEW / PROCEDURE / FUNCTION”的作用就是上述的a。如果不勾选的话,就会有隐患:一开始就进行步骤b,表t不存在倒一切正常;但如果表t已经存在,并且数据结构与原来备份时不一致,例如较之前缺少名为columndel的一列,那进行步骤c时就会出现错误,因为对应columndel字段数据无法写入当前的表t中。

勾选“添加 IF NOT EXISTS”的作用就是上述的b。如果不勾选的话,一上来,不管三七二十一,直接CREATE TABLE t,但如果表t已经存在,将会报错;而勾选的话,将会执行CREATE TABLE IF NOT EXISTS t。

所以较保险之法就是同时勾选上述两项,当然碰到具体问题还得具体分析。

2. 备份程序

进入菜单:cPanel –> 文件 –> 文件管理器,将需要备份的文件夹先压缩,然后再通过页面客户端或ftp客户端下载到本地。切忌:一定不要通过ftp客户端直接下载文件夹,因为它里面包含太多单个文件,ftp客户端会去one-by-one的进行下载,你可就惨啦。压缩示意图如下:

三、自助更换机房进行时

1. 删除当前主机

进入菜单:HomeZZ –> 我的主机 –> 详细信息 –> 改变机房,一步步走下去就完事儿;有一点需要注意一下,就是确认删除之前一定得仔细阅读注意事项,千万不要养成无视说明性文字,见到next按钮就一个劲往下点的坏习惯。

2. 新建主机

这个操作挺容易,不做过多的解释;但有一点小技巧:在选主机之前,将候选列表中的所有主机都ping一遍,哪个最快就选哪个;当然啦,不同地域访问同一主机的速度可能不一,但对于像我这样的平庸者来说,访问自己域名最频繁的当然应该是自己本人。

3. 还原数据库

首先,在新主机对应的cPanel上,新建数据库、数据库用户,当然都应与原主机数据库数据一致。其次,进入到菜单:cPanel –> 数据库 –> phpMy管理,选择待还原数据库,可以采用以下两种方法进行还原:
a. “SQL”菜单,具体步骤如下:

b. “导入”菜单,具体步骤如下:

这样数据库就还原成功,接下来就是还原程序。

4. 还原程序

这个步骤与备份程序恰好相反,即先上传压缩文件于主机的public_html目录,然后利用cPanel在线解压,这样就o啦。同样切忌:使用ftp客户端上传文件夹是一个不明智的选择。

四、自助更换机房后的那点事儿

登录域名的管理界面,例如4jplus.com域名管理界面godaddy.com,将@的A记录和www的CName记录对应的IP修改成当前主机IP即可。

个人认为较靠谱的转载格式

4J个人不太习惯转载,别人辛辛苦苦撰下的劳动果实——就我个人针对一篇日志而言,单单从开始撰写到成功发表大概就得花费2个来小时,就更不用说选材方面的耗时——就让我给“一键转载”掉,感觉有点掠夺他人果实之意;还有另一个原因,随着转载的数量增加,原创的比例也将会随之下降,而我却恰恰是一根筋——“坚持原创,内容为王”。

但基于近段时间的接触,我觉得以前的观点太过于死板,转载其实也不失是一种很管用的推广策略,双方可能都能从中获利;就拿我所接触到的来说,正是由于XJP的文章呈现于月光博客之上(我至今还依旧对“转载”和“供稿”两概率范晕),我才能发现又一个值得订阅的原创站点;当然啦,对转载的看法,仁者见仁、智者见智;而我现在的观点是,即不打压也不鼓励,当然我也没能力去打压别人,但我一般是不会轻易去转载;遇到好文章我习惯用notebook@google或gmail进行全文收藏。

当今中国互联网现zhuang,没有对网络版权的官方说明,感觉也不太可能有;而博主们一般只会做一些简单的转载声明:“转载请注明原文出处”;而一篇文章被转载,与原创仅仅只有一点不同,那就是在文章最后吝啬滴贴上一句:“文章转载于…(当然附带原文链接)”,好像目前大多数都是这么干的,最具代表的xxBeta,进而促使千鸟的“严禁转载”。

就如前面所说,我个人觉得这样做太过于吝啬,但能规避掉舆论;当然也许有些可能是无意——没太注意转载版权问题,别人咋整我也咋整。我个人感觉,既然你想要转载别人文章,就必须得让读者很轻易滴知道该文章是转载并且标明原文出处;我个人总结如下:

1. 必须得有转载的相关声明,并且应该位于最醒目的位置,我的建议是正文之前,而不是置于其后;至于声明的详细程度就可以因人而异。

2. 必须是全文转载,而不应该是节选自己喜欢的段落,那样很可能导致最后读者从此获得的信息非原文作者本意。如果你对部分段落有异议的话,建议以评论的形式粘贴在正文之后。

3. 必须关闭评论,并注明“请到原文出处评论”,原因你懂的。

====转载格式样本 – 开始====

一、转载声明

1. 来源博客名称:SocialBeta
2. 来源博客主页:http://www.socialbeta.cn
3. 日志原文出处:SocialBeta分享会@上海2011#微创业#沙龙现场报道
4. 转载日期:2011-01-13

二、日志原文正文

—-转载正文 – 开始—-

2011年SocialBeta分享会又开始了,一直非常给力的@Ekstasis这么迅速的组织了一次聚会,让我刚到很惭愧,我去年和他说过,会在杭州也搞一次聚会的,却一直没有去落实,而举办过的这么多次分享会,我自己一次也没有参加过,非常的遗憾。我虽然对social的东西很感兴趣,可是自己却一点都不social,希望2011年能让自己变得更加social一些,不多说,看看今天的活动情况吧:

……(由于仅仅是为了举例说明,所以原文全文4J就不去一一粘贴,而是选取第一段以作示例;但真正转载当中可不能怎么干,有断章取义之嫌,可能不太厚道。)

—-转载正文 – 结束—-

三、4J的补充内容

这是4J继ifanrevent@上海,开心聚会之后参加的第二次互联网线下活动,从中受益颇多:
第一个周浩,讲的没太弄明白,可能我对涉及到的知识了解的很少的缘故。
第二个王维托,这个家伙真低调和真实,完全不屑于去对自己加任何修饰。
第三个钟士杰,虽然之前没准备,临场发挥,确实不错,最赞,讲述他和他团队的创业历程,说的我都有些许冲动,一听就知道是经历过事的人。
第四个夏卫,我也没太听懂,可能原因同第一吧。
第五个,大牌,开心农场,这么年轻就家喻户晓,N人。
第六个庄明浩,id:@rosicky311,这id我比较熟,M2论坛版主。
感谢SocialBeta和@Ekstasis等人的组织,谢谢以上数人的分享,谢过了。还有,期待下一次的分享会。

四、评论说明

出于珍惜劳动人民果实的初衷,该日志在本博客中的评论被关闭,如果你有感而发,请猛击“转载声明”中的原文链接,谢谢。

====转载格式样本 – 结束====