J2ME Polish

一篇


 如果本文的读者还不知道polish所为何物,那么请可以去j2mepolish的官方网站看下,它到底是用来干嘛的,我们这里只谈它其中的一个build功能。本人接触polish的时间也不长,可以说是小菜鸟,所以文章中难免出现问题,希望读者能够不吝指正。

        问题的提出:我们为什么要用polish来build我们的程序?其实build程序我们可以用很多IDE来完成,但是我们利用polish是为了解决一个问题,而这个问题可能同样困扰着你。由于不同手机平台的不同,而往往这些不同手机上实现程序会有一定的差异性,即使同一个平台,比如Nokia来说,它的不同型号不同机型也不尽相同,比如老40(s40E1)播放mid和新s40以及s60就很不相同,就是因为这个原因,我们在开发的过程中会先在某一款机型上实现所有的代码、所有的功能,然后适配到不同的机型中,这样一来我们是不是得到了很多这样的代码,他们有这样几个特点:

         1>都是实现了一个有戏,代码差异性不大

         2>由于平台差异,手机差异,不同机型上的代码的差异性又不相同

         好了,现在问题出来了,如果对于这些代码进行维护,哪怕只是修改其中的几张图片,你该做什么样的工作?你可能会说,把图片放到资源文件夹内,替换原来的图片,然后在每个版本里修改一定的代码,在模拟器上调试成功后,然后重新build打包,装真机测试。那么如果这样的不同机型有15款,乃至20款,你的工作量是不是相当大,而当你改完了,你又发现其实很多机型修改的内容一摸一样,而你做了好多重复累赘的工作。这个时候,你就需要polish了。

        利用polish我们可以把这些不同的版本整合到一起,让他变成一个代码体,当然了它包含了不容机型里的所有内容,当然polish有他的办法来区分他们之间的不同。这里我举个简单的例子,比如我们的游戏中存在一个背景音乐(mid),但是我们知道并不是所有的机型都支持播放mid,再具体一点,我要做的游戏里Moto C650是能播放mid的,但是Nokia-7210却不支持,这两个机型屏幕大小完全一样(FullCanvas大小不一样,主要因为moto机型无法真正全屏,屏幕上方的状态条无法除去),游戏的代码体一摸一样,7210里不能播放声音,那么我们可以用polish简单的来判断控制来区分,看下面的代码:

//#if polish.midp2
     /**//*播放音乐代码/*
//#else
    /*不播放音乐操作/*
//#endif

        简单分析一下这段代码,我们的polish做了这么一步工作--根据你的要求,提取代码,然后打包,同样它也可以提取资源文件,我们以后慢慢讨论这些问题,这里我们继续分析代码,当机型是midp2.0时,执行播放音乐代码,因为一般的2.0机型都能播放mid,如果为1.0那么我们就不播放音乐,转而执行其他的代码,这些看似C里面宏定义的代码的作用就是能根据你的控制代码,来瓜分你的代码,而且在build/real/Nokia/7210/source下看到build后的原代码,并不包含播放声音那一段,因为7210是1.0的机子。现在你猜猜moto C650的放在那里?它就放在build/real/Motorola/C650/source下面,这个过程由polish自动完成,你不用操心,当然不播放音乐的代码也不会被包含在C650的代码中。(注明:所有的目录结构都是根据eclipse)。讲到现在,你可能知道了一点polish的build功能的魅力了。

      一句话,用polish的语言,把不同的机型代码完美的整合到一起,方便我们以后管理,修改。当然同样带来的项目上的风险,有利有弊吧,看读者怎么思考这个问题了。

 


二篇

上一篇文章,我们大致讲了polish的一个基本应用,但我们手头上有同一个游戏不同版本的代码的时候,我们就开始利用polish进行整合,那么在利用polish之前,我们必须把环境搭配好,接下来简单的谈谈polish环境的搭建。
     1、eclipse me+jdk+wtk这是开发环境,一般移动百宝箱需要我们用wtk1.0.4,而一般我们开发可以用更高的版本wtk2.2.
     2、ant工具(ant是一个基于JAVA的自动化脚本引擎,脚本格式为XML。除了做JAVA编译相关任务外,ANT还可以通过插件实现很多应用的调用。)
     3、polish安装文件
     4、build.xml文件
     对于第一条,我想这样的文章已经很多了,我就不说了。关于ant工具,大家可以去下ant的免安装包,解压缩路径假如是E:/ant/,那么把E:/ant/bin;添加到系统环境变量中的path中就可以了。这个时候你打开cmd,敲入ant后如果提示:
Warning:   JAVA_HOME environment variable is not set.
  If build fails because sun.* classes could not be found
  you will need to set the JAVA_HOME environment variable
  to the installation directory of java.

  Buildfile: build.xml does not exist!
  Build failed
则说明安装成功,警告没有可供解析的build.xml文件,这个工具到底用来干嘛的,等我们最后分析完build.xml的时候,大家就知道了。
    polish的下载安装也很简单,大家可以搜索一下,安装就可以了,笔者的安装路径是E:/JAVA/J2ME-Polish。
    接下来就是定制自己的build.xml了。笔记给出一个简单例子,并简单给出解释,希望对大家有所帮助:
 <project   
    name="KalaPolish" ------------------------------------------>你的项目名称
    default="j2mepolish">
    <property file="${user.name}.properties" />   
    <property name="polish.home" location="E:/JAVA/J2ME-Polish" />--------------------------->你的polish安装路径
    <property name="wtk.home" location="E:/JAVA/WTK22" />--------------------------->你的wtk安装路径
    <property file="${polish.home}/global.properties" />
   
<!-- Definition of the J2ME Polish task:-->
    <taskdef name="j2mepolish"
        classname="de.enough.polish.ant.PolishTask"
        classpath="${polish.home}/import/enough-j2mepolish-build.jar:${polish.home}/import/jdom.jar:${polish.home}/import/proguard.jar:${polish.home}/yguard-lib.jar:${wtk.home}/wtklib/kenv.zip"/>

       
   
<!-- build targets, each target can be called via "ant [name]",
     e.g. "ant clean", "ant test j2mepolish" or just "ant" for calling the default-target -->
   
    <target name="setdeploy"
        description="Call this target first to set the OTA download-URL, e.g. ant setdeploy j2mepolish"
        >
        <property name="deploy-url" value="http://www.company.com/download/" />
    </target>
   
    <target name="enableDebug"
        description="Call this target first to skip the obfuscation step, call the emulator and start the debugger, e.g. ant enableDebug j2mepolish"
        >
        <property name="debug" value="true" />
    </target>
   
       
<target name="test"
        description="Call this target first to skip the obfuscation step and call the emulator, e.g. ant test j2mepolish"
        >
        <property name="test" value="true" />
    <property name="dir.work" value="build/test" />
</target>
<target name="init">
      <property name="test" value="false" />
    <property name="dir.work" value="build/real" />
    <property name="deploy-url" value="" />
</target>
<!-- In this target the J2ME Polish task is used.            -->
<!-- 此任务分3部分:                                                -->
<!--    1. The info-section 定义一般信息                          -->
<!--    2. The deviceRequirements-section 定义适配的机型         -->
<!--    3. The build-section 定义build过程                     -->
<!--       depends分别为test或者init用于切换是否处于测试阶段.         -->
<target name="j2mepolish"
        depends="init"
        description="这是build过程的控制部分."
        >
    <j2mepolish>

        <info
            license="GPL"
            name="杀手"--------------------------->MIDlet-Name
            version="1.0.0"--------------------------->项目版本
            vendorName="Air Long(C)"--------------------------->项目供应商
            icon="/icon.png"--------------------------->项目图标
            jarName="Kala${polish.Name}.jar"
            ------>jar的名字,注意因为我们会同时打很多不同的版本,${polish.Name}来区分,“Kala”你可以自己定义         
            copyright="Copyright 2007 Air Long(C). All rights reserved." --------------------->项目版权          
        />
        <deviceRequirements >
            <requirement name="Identifier" value="Panasonic/X800,Nokia/7610,Nokia/6230i,Nokia/7260,Nokia/6101,Motorola/E398,Motorola/L7,Motorola/C650,Motorola/V600,Samsung/SGH-D508,Sony-Ericsson/K700,Sony-Ericsson/K506"/>--------------------------->需要打包的机型,注意机型必须在polish中有定义。
        </deviceRequirements>

            <!-- build settings -->
        <build
            symbols=""
            usePolishGui="no"
            workDir="${dir.work}"
            >
            <!-- midlets definition -->
            <midlet class="Kala" name="杀手" number="1"/> ----------------->MIDlet class的名字,必须正确
            <resources
                dir="res"
                defaultexcludes="yes"
                excludes="readme.txt">
                <fileset
                        dir="res/Sound"
                        includes="*.bin"
                        if="polish.Identifier == Nokia/7210"
                    />---------------------------><fileset />内定义了一些具体的资源文件的应用,比如这里如果打包时候判断是Nokia/7210,那么就自动包含res/Sound文件下的*.bin文件。*为通配符,如果包含全部文件,那就是*.*。其余的几个大家自己分析一下就知道怎么用了。
                <fileset
                        dir="res/Sound"
                        includes="*.bin"
                        if="polish.Identifier == Nokia/N-Gage_QD"
                    />
                <fileset
                        dir="res/Sound"
                        includes="*.mid"
                        if="polish.Identifier == Nokia/7260"
                    />
                <fileset
                        dir="res/Sound"
                        includes="*.mid"
                        if="polish.Identifier == Motorola/C650"
                    />
                <fileset
                        dir="res/Sound"
                        includes="*.mid"
                        if="polish.Identifier == Sony-Ericsson/K506"
                    />
                <!--
                <root dir="resources/base/images" />
                <root dir="resources/base/sounds" />
                <root dir="resources/customization1" if="cfg.customization1" />
                <root dir="resources/customization1/images" if="cfg.customization1" />
                <root dir="resources/customization1/sounds" if="cfg.customization1" />
                <root dir="resources/customization2" if="cfg.customization2" />
                <root dir="resources/customization2/images" if="cfg.customization2" />
                <root dir="resources/customization2/sounds" if="cfg.customization2" />
                 add the localization element for created localized
                versions of your application:
                <localization>
                    <locale name="en_US" />
                    <locale name="de_DE" encoding="utf-8" unless="test" />
                </localization>
                    -->
            </resources>

            <!--midlet class="MenuMidlet" name="Example" /-->
            <!-- project-wide variables - used for preprocessing.  -->
            <!-- You can set localized variables in the resources/messages.txt files as well.  -->
            <!-- Here you can set the dir attribute to "resources2" for an alternative design. -->
            <!--
           
            -->
            <!-- obfuscator settings: do not obfuscate when the test-property is true -->
            <obfuscator  name="ProGuard"  useDefaultPackage="false" unless="test"  >
            ----------->混淆器设置,我们这里用ProGuard,wtk2.2下面的一个混淆器
            <!--
            You can set additional parameters here, e.g.:
            <parameter name="optimize" value="false" />
            -->
            </obfuscator>
                <!-- log settings: only use debug setting when the test-property is true -->
            <debug if="test" showLogOnError="true" verbose="true" level="error">
                <filter pattern="de.enough.polish.example.*" level="debug" />
                <filter pattern="de.enough.polish.ui.*" level="warn" />
                    <!-- example for writing log entries to the Recordstore Management System:
                    <handler name="rms" />
                    -->
            </debug>
            <!-- user defined JAD attributes can also be used: -->
            <jad>   
                <attribute name="SMS_NUM" value="1065816730107" />---------->这里定义了jad里面的信息
                <attribute name="SMS_GAMEID" value="02" />
                <attribute name="SMS_CHANNELID" value="07" />
            </jad>           
        </build>
        <!-- execution of emulator(s) -->
            <emulator
            wait="true"
                securityDomain="trusted"
            enableProfiler="true"
            enableMemoryMonitor="true"
            enableNetworkMonitor="true"
                if="debug"
                >
                <!-- this is an example for connecting to a debugger - use the ${polish.debug.port} Ant property
                     for getting to know the port of the debugger. In this example the
                     "connect-debugger" target is also required.
                -->
                <!--
                <debugger name="antcall" target="connect-debugger" port="6001" />
                -->
            </emulator>
                       
            <emulator
                wait="true"
                trace="none"
                securityDomain="trusted"
                enableProfiler="false"
                enableMemoryMonitor="false"
                enableNetworkMonitor="false"
                if="test and not debug"
                >
            </emulator>   
    </j2mepolish>
</target>

    <target
        name="emulator"
        depends="test,j2mepolish"
        description="invokes the emulator"
    >
    </target>

<target name="clean"
          description="allows a clean build. You should call [ant clean] whenever you made changes to devices.xml, vendors.xml or groups.xml">
    <delete dir="build" />
        <delete dir="dist" includes="**/*" />----------->clean dist文件夹下面内容功能,可以让用户删除打包文件,这点很有用,有的时候版本更新,必须先clear
</target>

    <target 
        name="cleanbuild"
        description="allows a clean build. You should call [ant cleanbuild] whenever you made changes to devices.xml, vendors.xml or groups.xml"
        depends="clean, j2mepolish"
    />----------->clean build文件夹下面内容功能,可以让用户删除打包文件,这点很有用,有的时候版本更新,必须先clear
   
    <target name="debug" description="debugs the project" depends="enableDebug, test, j2mepolish" />
   
    <target name="enableCustomization1">
        <property name="dir.work" value="build/customization1" />
        <property name="cfg.customization1" value="true" />
    </target>
       
    <target name="customization1"
            description="customizes this project with the settings found in resources/customization1"
            depends="enableCustomization1, j2mepolish"
    />
   
    <target name="enableCustomization2">
        <property name="dir.work" value="build/customization2" />
        <property name="cfg.customization2" value="true" />
    </target>
       
    <target name="customization2"
            description="customizes this project with the settings found in resources/customization2"
            depends="enableCustomization2, j2mepolish"
    />
   

</project>

     以上红色比分,大家修改成自己的就可以了,当然,玩家也可以把打包工具改成wtk1.0.4,注意的是,无论你的打包工具,bin目录下面是否安放了混淆器,都没有关系,因为打包用的混淆器并不是利用wtk里面的混淆器,而是利用了,polish自带的混淆器,具体polish怎么解析这个build文档,大家可以看polish的原文件。有点提醒大家,混淆器的定义的时候,本文中是ProGuard,第一个字母必须大写,否则就出错,想知道问什么的,可以去看polish的代码实现中关于混淆器的代码。
     好了,把这个文档放到你的项目目录下面,就可以在eclipse中点击这个build.xml选择ant构建来打包我们的程序了。到这里我们的环境就配置好了。文章写的很粗略,希望对大家有所帮助。文章红色部分为注释,用的时候,必须删除。

 

 

三篇


有了以上两篇文章的铺垫,我想大家基本上就可以使用polish了,但在使用过程中,或许还会遇到很多问题,比如:我要打包的机型在polish中没有找到,我要用的api在polish中没有,我的手机厂商在polish中也没有,在代码中一些polish的标签如何用等等,这篇文章,我们带着这些问题,给读者解答这些问题,游戏问题解决方法很多,不是唯一的,仅供参考。
     第一类问题:我的项目中,有几个机型中用到的资源有些不一样,比如7210放不了mid,我要用Nokia提供api里的sound,所以打包的时候我不想把mid文件打包进去,而是要把data.bin文件打包进去,如何解决呢?
     答案:在我的第二篇文章里,就给出了答案,这里回顾一下:
     <resources
                dir="res"
                defaultexcludes="yes"
                excludes="readme.txt">
                <fileset
                        dir="res/Sound"
                        includes="*.bin"
                        if="polish.Identifier == Nokia/7210"
                    />
       </resources>
       这段build内容我不多解释了,我想大家应该明白了,具体放在build那个位置,大家可以参考文章二。
       第二类问题:我的机型涉及到很多屏幕大小,比如有C650 128*128的,有7610 176*208的,他们用的图片文件不一样,那么在一个polish中整合后,如果让polish知道,应该用那一张图片呢?
       在将这个问题之前,我想先说明一下polish的一个机制,放在res里面的文件,表示polish打包时候不同的型号都会被包含,那么当然如果我们把不同的屏幕大小的都放在一个目录下面,打包的后的jar包含了不需要的图片,会很大,我们当然不能容忍这样的事情发生,给出几个解决方法,大家可以结合使用,效果很不错。其实在polish在给N7210打包的过程中,他会自动去寻找res目录下面Nokia目录下面的7210文件夹下面是否有内容,如果有,就会包含进去,如果在res目录下面已经有了,也会覆盖,用res/Nokia/7210下的文件来取代。当然默认环境下没有res/Nokia/7210这个目录,但你的程序N7210上有一些特别的资源的时候,不要放在其他地方,放这个目录下面就对了。接下来大家应该知道怎么做其他的机型了吧?哈哈,当然,有的人会说用问题一中的方法也会可以的,但是如果你打包的机型用到的资源不统一,你要写很长的build来进行区分了,不可取。当然,这样会有有一个问题,那就是一般同一个屏幕大小的,图片会是一样的,那么我如果用上面两个方法,就没有办法简单的根据屏幕来区分,其实polish给我们提供了一个机制,那就是根据屏幕大小来获取自由,在res下面创建一个FullCanvasSize.170+x200+目录,什么意思?一看就懂的吧,哈哈,这样你的176*208的机型的图片就会在这个文件夹下面找了,而不会包含128*128的图片了,这里给出一个例子说明可以这么做,具体效果怎么样,大家还是要自己去尝试一下的。这样利用上面的三个方法,灵活应用,自由的区分问题就可以完美解决了。
       第三类问题:如何在polish里面添加手机厂商?
       比如和你想添加一个手机厂商,比如叫XXX,那么你在polish的安装目录下面找到vendors.xml,添加如下代码就可以了:
<vendor>
        <name>xxx</name>
        <features></features>
</vendor>
        第四类问题:如何添加手机型号?
        一样的道理,找到安装目录下面的devices.xml。稍微解释一下需要添加的代码段:
        <device>
        <identifier>Nokia/7210</identifier>--------------->vendor和型号,build里面需要打包机型必须好这里一直
        <groups>Series40</groups>--------------->被分在Series40机型这个组里面,这里如果定义了这个,那么在polish中判断是否是40机型的时候,会把这个机型包含进去
        <capability name="ScreenSize" value="128x128"/>--------------->屏幕大小
        <capability name="BitsPerPixel" value="12"/>
        <capability name="JavaPlatform" value="MIDP/1.0" />--------------->MIDP平台
        <capability name="SoundFormat" value="midi" />--------------->支持声音类型
        <capability name="HeapSize" value="200kb" />--------------->堆内存大小
        <capability name="MaxJarSize" value="64kb" />--------------->最大jar支持大小
        <capability name="Emulator.Class" value="NokiaEmulator" />
        <capability name="Emulator.Skin" value="Nokia_7210_MIDP_SDK_v1_0" />   
        </device>
       

         <capability name="JavaPackage" value="siemens-game-api" />--------------->这个属性在7210中没有,在有些机型中有,主要是说明机型支持那些特殊的api,当然必须是polish的import目录下面有的类了。
          第四类问题:如果让polish更加强大,让它支持更多的api,比如,但我们在三星的D508上开发关于SMS的应用的时候,利用j2me自带的mmapi发送失败,我们必须利用三星自己的开发包,假如手头上我们下载了三星的开发包samsung.zip,那么如何让polish支持和呢?很简单,第一步,把开发包放到polish安装目录下面的import目录下面,然后需要注册这个api包,打开安装目录下面的apis.xml文件,添加如下内容:
     <api>
        <name>Samsung User Interface API</name>--------------->名称,并不重要
        <description>The Samsung User Interface API provides
            some advanced Message functionalities.
        </description>--------------->描述,也不是很很重要
        <names>samsung-api,samsungapi</names>--------------->我们在代码里面用的时候,就用这个名字
        <symbol>samsung-api</symbol>
        <files>samsung.zip</files>--------------->开发包名称,这个必须和import下的名字一样
        <path>import/samsung.zip</path>--------------->路径,也必须属性正确
    </api>

     给个简单的例子说明如何应用吧
     //#if polish.api.samsung-api  ----------------->注意这里红色部分,必须和api中定义的names一样
     import javax.wireless.messaging.*;
     //#else
     //#= import com.samsung.util.*;
     //#endif
     好了,接下来简单的介绍一些代码用到的常用标签,希望给初学者一些帮助:
     //#if polish.api.nokia-ui  判断机型是否支持nokia的开发包
     //#if polish.api.mmapi || polish.midp2  如果支持mmapi或者是2.0机型
     //#if polish.Vendor == Nokia   如果是Nokia机型
     //#if (polish.Identifier == Nokia/7210) || (polish.Identifier == Nokia/N-Gage_QD)   如果是打包Nokia/7210或者Nokia/N-Gage_QD,注意两个都必须用括号,否则会报错。
     //#if (polish.ScreenWidth < 176)  如果屏幕宽度小于176
     //#ifdef BUY_SMS  如果定义了BUY_SMS

     好了,文章就写到这里

你可能感兴趣的:(J2ME Polish)