测试环境:Ubuntu 14.04.5 LTS

J2ME背景知识及PhoneME介绍

J2ME相关介绍

在正式开始介绍J2ME之前,这里我列出一些常见名词,方便与下文参照:
J2ME(Java2 Platform, Micro Edition) Java2平台微型版
CLDC(Connected, Limited Device Configuration) 连接受限设备配置
CDC(Connected Device Configuration)连接设备配置
MIDP(Mobile Information Device Profile) 移动信息设备描述
KVM(The K Virtual Machine) K虚拟机
JSR(Java Specification Requests)意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。

Java版本主要分为三个:J2EE ,J2SE和J2ME,分别对应与不同的目标设备,如下图所示。

图1 Java不同版本的配置

SUN把J2me的实现分为两层:configuration 和 pofile。
configuration包括虚拟机(virtual machine),核心的类库与API。configuration层定义一个java虚拟机的特性与java类库的最小子集。也就是说,configuration层提供了开发人员一个最基础,最核心的Java平 台。因为j2me把设备分为两类:联接设备(connected device)和有限联接设备(Connected, Limited Device)。对应这两种设备就有了两种J2ME configuration。分别为CDC(Connected Device Configuration)和CLDC(Connected, Limited Device Configuration)。这里请注意,CDC使用经典的javaVM,而CLDC使用的是KVM(The K Virtual Machine)。KVM是sun专门为使用16/32位RISC/CISC微处理器或控制器,并其可用内存为160kb~512kb的的设备而开发的。 KVM比较小,通常只有128K或更少。
Profile层也包含一组API,主要针对于特定的某一族系的设备而定义。profile层在特定的configuration层上实现,而我们程序员则负责在特定的profile上编写应用程序。对于手机,pda等Connected, Limited Device。它们的profile层称为MIDP(Mobile Information Device Profile)。于是MIDP与CLDC合在一起就构成了一个完整的J2ME架构。顺便说一句,对于MIDP上的应用程序sun也有独特的叫法,它们被 称为MIDlet。你是不是觉得有点眼。想想java中的applet。下图显示了开发手机应用的结构。

图2 CLDC/MIDP的结构

深入理解CLDC/MIDP

CLDC的目的
  为小型的,且资源有限,Connected Limited的设备定义一个标准的Java平台。
  允许动态的向这些设备发布内容与应用程序。
  方便第三方软件厂商与开发者向这些设备移植内容与应用程序。
CLDC的范围
      Java语言与虚拟机的特性
  核心Java类库(如java.lang.*, java.util.*)
  输入/输出
  对网络的支持
  对安全性的支持
  对国际化的支持
CLDC不包括的范围(即由MIDP解决的)
  对应用程序life-cycle的管理(就是指一个应用程序是如何安装,运行,删除的)
UI界面(User Interface)
Event处理
  高级应用程序模式(这里指用户与应用程序的交互)。
CLDC的安全性
低端的基于虚拟机的安全性由下载时对class文件的审核(verification)步骤来保证。(如果你写过并编译过MIDlet程序,就会知道这 一步是必须的。这里有一个概念就行了,我会在后面讲述如何创建MIDlet程序时,详细介绍具体的步骤)。基于应用程序的安全性通过使每个应用程序分别运 行在相对独立的封闭环境中来保证并且处于被保护的系统package中的类不能被应用程序重载(overridded)。

对于Java语言支持的特殊方面
CLDC总的来说是与Java语言完全兼容的,但需注意以下几点:
  不支持浮点数据类型(即没有float和double)(这实际上主要是由于CLDC所面向的设备,其硬件因其内存限制或是基于安全性的考虑不支持浮点运算)
 不支持类实例(class instance)的终结(finalization),即不存Object.finalize()方法。(注:finalization指的是java 中提供的有别与garbage collection的另外的一种对象清理方法。具体可参看侯捷老师译的Bruce Eckel的《Thinking in Java 第二版》,可以在www.jjhou.com中下载)
  有限的错误处理,即大部分Java.lang.Error的子类都未被支持。与此相反,CLDC包括了相当完备的异常(exception)类。
  对于Java虚拟机(Java Virtual Machine)支持的特殊的方面
  实质上CLDC在其严格的内存限制下达到了对Java虚拟机相当程度的兼容性。不过还是有下列不同点:
  不支持浮点数据类型(没有float和double)
  不支持JNI (the Java Native Interface )不支持用户自定义的Java级的类载入器(class loaders )
  没有反射(reflection)特性(注:reflection指java通过java.lang.reflect提供的,可以对类的能力进行分析的功能。常用来对类的结构进行检查,在JavaBeans上有广泛运用可参见Gary Cornell的Core Java2 volumeI,II,机工有出中译本)
  不支持线程组(thread groups)或守护线程(daemon threads)
  不支持类实例(class instance)的终结(finalization)
  没有弱参考(weak references)(注:weak reference提供了一种解决指向已经被garbage collector清除的对象的方法。在Java2中被介绍。具体请参考java.lang.ref API 文档,和sun网站上关于Reference Objects和Garbage Collection的文章。)
  有限的错误处理(error handling)
  类文件审核过程(classfiles Verification)
CLDC要求其下层的虚拟机能够辨别并拒绝非法的class文件。但由于CLDC本身面向小内存消耗的小型设备这一前提。其类文件检测机制与J2SE中定义的标准类文件审核机制还有所不同。请注意看下图:

图3 CLDC的类审核机制

请注意上图所示CLDC中的预审核(preverification)过程。这是CLDC区别于通常的类文件审核过程的关键。如上图所示,当源程序被编 译后,必须被预审核器预审核,然后才能被下载到目标设备上去。之所以有这一步骤,主要是为了减轻KVM中审核器的负担,加快审核速度。就像我前文提到的, 这是出于对CLDC支持的硬件的考虑(毕竟手机和PDA并没有我们PC机那样奔腾的“芯”呀!^-^)。

常用JSR

JSR139 - CLDC
JSR118 - MIDP
JSR120 – WMA1.1
JSR135 – MMAPI1.2
JSR75 – File
JSR75 - PIM
JSR179 - LocationAPI
JSR184 – 3D
JSR205 – WMA2.0
JSR211- CHAPI

PhoneMe介绍

phoneMe主页:https://java.net/projects/phoneme

phoneME Feature software是一个优化了的Java ME架构。它的核心是支持多任务的MIDP2.1规范实现。

当phoneME Feature software运行多个MIDlet时,它只使用一个系统进程,因为一个Java虚拟机实例可以执行几个应用,并提供独立的运行时空间。所有运行的应用都是独立的,看起来好象每个应用都在自己的虚拟机中执行一样。

phoneME Feature software提供给为MIDP或者是移动信息设备相关的开发人员。

以下是phoneME Feature software MR2版本包含的内容特性:

高性能的Java ME平台架构

支持每个功能领域(存储,网络和用户界面等)的模块化实现

子系统,目录和便携性类库

最小的特定平台实现代码

多任务能力和支持并发应用(MIDlet)

本地应用管理API

本地资源管理API

支持德州仪器P2SAMPLE64-V6平台

CLDC 1.1 (JSR 139)和MIDP 2.1 (JSR 118)实现

以下可选包实现:

Wireless Messaging 1.0 (JSR 120)

Mobile Media APIs (JSR 135)

J2ME™ Web Services support (JSR 172)

Security and Trust Services API support (JSR 177)

Content Handler API (JSR 211)

Java Binding for the OpenGL ES API (JSR 239)

深度阅读:http://wenku.baidu.com/link?url=b7SgAw-w645dQcJC6XTRGkBwBR4gI8_aZyUjF9C9Qv-9CZVJxPtns2431qOdilisual07zj76s2c45lMTaHx4jmDcwx8BE-Rlm_F9Iesrpe

PhoneMe编译

原始的Code在:https://github.com/borman/phoneme-qtopia

Fork一个工程:https://github.com/arnoldlu/phoneme-qtopia,会将修改部分push到这里。

由于PhoneMe中部分代码进行的类型强制转换是基于i386进行的,在x86_64系统编译会报错。

在进行编译前就需要将部分库切换到i386,调用switch_to_i386.sh即可通过编译。

在编译完成后使用switch_to_x64.sh即可复原。

在工程里执行make,生成编译文件在build_output_fb_i386中;make clean会将生成文件清空。

qvfb介绍及编译

由于PhoneMe需要基于虚拟的framebuffer进行显示,同时还依赖于虚拟鼠标、键盘作为输入设备,这些功能需要qvfb的支持。

Qvfb是为qtopia做的一个虚拟frambuffer的应用程序,它的最终目的就是把qtopia应用程序运行的的结果显示在qvfb上(实际中是要通过linux的frambuffer驱动显示在lcd屏上的),并提供键盘、鼠标的外设仿真。从而方便研发阶段,用户在pc端就可以完成qtopia的调试工作,极大的提高了工作效率。

qvfb小工具可以通过安装qt-dev-tools的工具获得。

或者可以到这里获取:https://github.com/arnoldlu/qvfb-1.1/blob/master/qvfb/qvfb

sudo ln -s /usr/lib/x86_64-linux-gnu/qt4/bin/qvfb /usr/bin/qvfb

也可以通过从源码编译生成,编译方法就是./configure->make->make install,中间会有一些编译依赖问题,可以针对性百度一下解决。

QVFB代码:https://github.com/arnoldlu/qvfb-1.1.git

使用步骤

运行qvfb环境

在运行PhoneMe之前需要先启动qvfb。

qvfb -depth 16 &

之后会创建两个节点,模拟鼠标键盘输入。通过lsof –p xxx可以看到如下谅解文件:

/tmp/.qtvfb_keyboard-0

/tmp/.qtvfb_mouse-0

这两个节点是fifo型文件:

/tmp/.qtvfb_keyboard-0: fifo (named pipe)

/tmp/.qtvfb_mouse-0: fifo (named pipe)

运行PhoneMe

编译phoneMe之后会生成build_output_fb_i386目录,这里面包括整个编译生成文件。

进入build_output_fb_i386/midp_,执行./runPhoneME:

安装MIDLet

默认情况下,Preinstalled apps里面是空的。执行build_output_fb_i386/midp_/bin/i386下的./installMidlet.sh xxx.jad之后:

此时,就可以使用鼠标键盘进行操作了。

基本示例MIDLet放在:https://github.com/arnoldlu/phoneme-qtopia/tree/master/MIDLets

显示已安装MIDLet

./listMidlets.sh

VFB info: 240x320, depth=16
Suite: 5
  Name: QQ???
  Version: 1.4.92
  Vendor: Tencent
  MIDlets:
    QQ???: com.qq.main.MainMidlet
Suite: 4
  Name: 5ud0ku
  Version: 1.8
  Vendor: midlet@wintermute.de
  Description: A Su Doku game.
  MIDlets:
    5ud0ku: de.wintermute.sudoku.SudokuMidlet
Suite: 3
  Name: JBenchmark2
  Version: 2.1.1
  Vendor: Kishonti LP
  Description: Graphical java benchmark for mobile devices
  MIDlets:
    JBenchmark2: JBenchmark2.JBenchmark2
Suite: 2
  Name: JBenchmark
  Version: 1.1.1
  Vendor: Kishonti LP
  Description: Graphical Benchmark for Mobile Java Devices
  MIDlets:
    JBenchmark: JBenchmark.JBenchmark

删除安装MIDLet

usage: removeMidlet <suite ID>

一个数独游戏

PhoneME资源占用情况评估

ROM占用

PhoneMe的ROM占用主要是bin文件的大小,约为2.0M,其他都是动态库。

lsof: WARNING: can't stat() tracefs file system /sys/kernel/debug/tracing
      Output information may be incomplete.
COMMAND    PID      USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
runMidlet 1808 lubaoquan  cwd    DIR    8,5     4096 21766264 /home/lubaoquan/java/phoneme/phoneme-qtopia/build_output_fb_i386/midp_/bin/i386
runMidlet 1808 lubaoquan  rtd    DIR    8,1     4096        2 /
runMidlet 1808 lubaoquan  txt    REG    8,5  2033266 21761463 /home/lubaoquan/java/phoneme/phoneme-qtopia/build_output_fb_i386/midp_/bin/i386/runMidlet
runMidlet 1808 lubaoquan  DEL    REG    0,5          11206658 /SYSV620105be
runMidlet 1808 lubaoquan  mem    REG    8,1  1754876  3670118 /lib/i386-linux-gnu/libc-2.19.so
runMidlet 1808 lubaoquan  mem    REG    8,1   114372  3677720 /lib/i386-linux-gnu/libgcc_s.so.1
runMidlet 1808 lubaoquan  mem    REG    8,1   134614  3670110 /lib/i386-linux-gnu/libpthread-2.19.so
runMidlet 1808 lubaoquan  mem    REG    8,1   134380  3670111 /lib/i386-linux-gnu/ld-2.19.so
runMidlet 1808 lubaoquan    0u   CHR 136,45      0t0       48 /dev/pts/45
runMidlet 1808 lubaoquan    1u   CHR 136,45      0t0       48 /dev/pts/45
runMidlet 1808 lubaoquan    2u   CHR 136,45      0t0       48 /dev/pts/45
runMidlet 1808 lubaoquan    3r  FIFO    8,1      0t0  2885054 /tmp/.qtvfb_mouse-0
runMidlet 1808 lubaoquan    4r  FIFO    8,1      0t0  2884891 /tmp/.qtvfb_keyboard-0

RAM占用

procmem分析进程内存使用情况如下,runMidlet占用内存在1632KB:

procmem可以在这里获取:https://github.com/arnoldlu/phoneme-qtopia/blob/master/procmem

procmem -p xxx

Vss      Rss      Pss      Uss     ShCl     ShDi     PrCl     PrDi  Name
-------  -------  -------  -------  -------  -------  -------  ------- 
12696K    1636K    1636K    1636K       0K       0K    3572K     108K 
  1748K    1632K    1632K    1632K       0K       0K    1632K       0K  /home/lubaoquan/java/phoneme/phoneme-qtopia/build_output_fb_i386/midp_/bin/i386/runMidlet
  1696K    1184K    1184K    1184K       0K       0K    1184K       0K  /lib/i386-linux-gnu/libc-2.19.so
   128K     128K     128K     128K       0K       0K     128K       0K  /lib/i386-linux-gnu/ld-2.19.so
   132K     112K     112K     112K       0K       0K     112K       0K  [heap]
   112K     108K     108K     108K       0K       0K     108K       0K  /lib/i386-linux-gnu/libgcc_s.so.1
    96K      96K      96K      96K       0K       0K      96K       0K  /lib/i386-linux-gnu/libpthread-2.19.so
   152K     152K      76K       0K       0K     152K       0K       0K  /SYSV620105be
    56K      56K      56K      56K       0K       0K      56K       0K 
   136K      20K      20K      20K       0K       0K      20K       0K  [stack]
    16K      16K      16K      16K       0K       0K      16K       0K 
     8K       8K       8K       8K       0K       0K       8K       0K  /lib/i386-linux-gnu/libc-2.19.so
     8K       8K       8K       8K       0K       0K       8K       0K  /home/lubaoquan/java/phoneme/phoneme-qtopia/build_output_fb_i386/midp_/bin/i386/runMidlet
     8K       8K       8K       8K       0K       0K       8K       0K 
     4K       4K       4K       4K       0K       0K       4K       0K  /lib/i386-linux-gnu/libpthread-2.19.so
     4K       4K       4K       4K       0K       0K       4K       0K  /lib/i386-linux-gnu/libpthread-2.19.so
     8K       4K       4K       4K       0K       0K       4K       0K 
     4K       4K       4K       4K       0K       0K       4K       0K  /home/lubaoquan/java/phoneme/phoneme-qtopia/build_output_fb_i386/midp_/bin/i386/runMidlet
     4K       4K       4K       4K       0K       0K       4K       0K  /lib/i386-linux-gnu/libc-2.19.so
     4K       4K       4K       4K       0K       0K       4K       0K 
     4K       4K       4K       4K       0K       0K       4K       0K  /lib/i386-linux-gnu/libgcc_s.so.1
     8K       4K       4K       4K       0K       0K       4K       0K  [vdso]
     4K       4K       4K       4K       0K       0K       4K       0K  /lib/i386-linux-gnu/ld-2.19.so
     4K       4K       4K       4K       0K       0K       4K       0K  /lib/i386-linux-gnu/ld-2.19.so
     8K       0K       0K       0K       0K       0K       0K       0K  [vvar]
     4K       0K       0K       0K       0K       0K       0K       0K  /lib/i386-linux-gnu/libc-2.19.so
     4K       0K       0K       0K       0K       0K       0K       0K 
-------  -------  -------  -------  -------  -------  -------  ------- 
17056K    5204K    5128K    5052K       0K     152K    6988K     108K  TOTAL

CPU占用情况

pidstat -u  -p 2875 1结果如下,可知在PC环境下占用率很低:

15时31分16秒   UID       PID    %usr %system  %guest    %CPU   CPU  Command
15时31分17秒  1002      2875    0.00    0.00    0.00    0.00     2  runMidlet
15时31分18秒  1002      2875    0.00    0.00    0.00    0.00     1  runMidlet
15时31分19秒  1002      2875    0.00    0.00    0.00    0.00     2  runMidlet
15时31分20秒  1002      2875    0.00    1.00    0.00    1.00     1  runMidlet
15时31分21秒  1002      2875    0.00    0.00    0.00    0.00     3  runMidlet
15时31分22秒  1002      2875    1.00    1.00    0.00    2.00     1  runMidlet
15时31分23秒  1002      2875    0.00    0.00    0.00    0.00     1  runMidlet
15时31分24秒  1002      2875    0.00    0.00    0.00    0.00     2  runMidlet
15时31分25秒  1002      2875    0.00    1.00    0.00    1.00     0  runMidlet
15时31分26秒  1002      2875    0.00    0.00    0.00    0.00     1  runMidlet
15时31分27秒  1002      2875    0.00    0.00    0.00    0.00     2  runMidlet
15时31分28秒  1002      2875    0.00    0.00    0.00    0.00     2  runMidlet
15时31分29秒  1002      2875    1.00    0.00    0.00    1.00     3  runMidlet
15时31分30秒  1002      2875    0.00    1.00    0.00    1.00     3  runMidlet

移植到RTOS?

如果将phoneMe移植到ARM RTOS,可能存在的风险包括:

不同架构x86和ARM下bin文件大小?

增加动态库后增加的ROM大小?

ARM下指令执行效率和x86对比?

RTOS动态库变成静态之后增加的RAM空间?

最新文章

  1. js判断网页是否加载完毕 包括图片
  2. google开发者工具调试技巧
  3. SharePoint 2013 状态机工作流之扩展自定义状态
  4. 分布式架构高可用架构篇_08_MyCat在MySQL主从复制基础上实现读写分离
  5. MOPSO 多目标例子群优化算法
  6. UVA 10735 Euler Circuit 混合图的欧拉回路(最大流,fluery算法)
  7. [Objective-c 基础 - 2.5] .h和.m文件,点语法,成员变量作用域
  8. 监听Web容器启动与关闭
  9. Redis Cluster高可用集群在线迁移操作记录【转】
  10. httpd-vhosts.conf配置
  11. Nginx 指令目录(中文版)
  12. MySQL数据库----存储过程
  13. MyEclipse *的下载
  14. OPenGL 库文件的添加
  15. Spring bean管理器 bean实例化的三种方式
  16. JS调用AngularJS中的方法
  17. 「模板」 FHQ_Treap
  18. 2017-2018-1 20179205《Linux内核原理与设计》第十周作业
  19. Registering Components--&gt;Autofac registration(include constructor injection)
  20. UVA 11881 Internal Rate of Return(数学+二分)

热门文章

  1. go语言结构体
  2. CSS常见居中讨论
  3. react-native 简单的导航
  4. 怎么调试lua性能
  5. Redis简单案例(四) Session的管理
  6. 数据库插入数据返回当前主键ID值方法
  7. 学会给你的类(及成员)来定制一套自己的Attribute吧
  8. .NET 实现并行的几种方式(二)
  9. window下使用Redis Cluster部署Redis集群
  10. entityframework学习笔记--006-表拆分与实体拆分