|
|
用户名:j2mego 笔名:江南雨 地区: 江南 行业:其他 |
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
J2ME游戏开发笔记
| J2ME游戏开发笔记 | |
|
Java手机游戏编程之MIDP图形设计篇
| Java手机游戏编程之MIDP图形设计篇 | |
|
Java教程_线程入门
线程是Java的内嵌特性,线程并不容易掌握,有专门介绍Java线程的书籍,读者可以参考。由此可见Java线程的重要性,本文将详细介绍线程的基本知识。
有的时候你可能想写一个程序,每隔一段时间执行相关的任务,这个时候你可以使用Timer和TimerTask,非常方便。你可以参考这里。
在Java中实现一个线程有两种方法,第一是实现Runnable接口实现它的run()方法,第二种是继承Thread类,覆盖它的run()方法。下面是代码示例:
public class DoSomething implements Runnable {
public void run(){
// here is where you do something
}
}
public class DoAnotherThing extends Thread {
public void run(){
// here is where you do something
}
}
这两种方法的区别是,如果你的类已经继承了其它的类,那么你只能选择实现Runnable接口了,因为Java只允许单继承的。
Java中的线程有四种状态分别是:运行、就绪、挂起、结束。如果一个线程结束了也就说明他是一个死线程了。当你调用一个线程实例的start()的方法的时候,这个时候线程进入就绪状态,注意并不是运行状态,当虚拟机开始分配给他CPU的运行时间片的时候线程开始进入运行状态,当线程进入等待状态,例如等待某个事件发生的时候,这时候线程处于挂起状态。
启动一个线程你只需要调用start()方法,针对两种实现线程的方法也有两种启动线程的方法,分别如下:
DoSomething doIt = new DoSomething();
Thread myThread = new Thread( doIt );
myThread.start();
DoAnotherThing doIt = new DoAnotherThing();
doIt.start();
由于安全等因素Thread中的stop()方法已经不推荐使用了,因此如果你想要停止一个线程的时候可以通过设置一个信号量,例如:
public class MyThread implements Runnable {
private boolean quit = false;
public void run(){
while( !quit ){
// do something
}
}
public void quit(){
quit = true;
}
}
如果每个线程只做它自己的事情,那么就很简单了,但是有的时候几个线程可能要同时访问一个对象并可能对它进行修改,这个时候你必须使用线程的同步在方法或者代码块使用关键字synchronized,例如:
public class Counter {
private int counter;
public synchronized int increment(){
return ++counter;
}
public synchronized int decrement(){
if( --counter < 0 ){
counter = 0;
}
return counter;
}
}
每个java对象都可以最为一个监视器,当线程访问它的synchronized方法的时候,他只允许在一个时间只有一个线程对他访问,让其他得线程排队等候。这样就可以避免多线程对共享数据造成破坏。记住synchronized是会耗费系统资源降低程序执行效率的,因此一定要在需要同步的时候才使用,尤其在J2ME的开发中要小心。
如果你要是想让线程等待某个事件的发生然后继续执行的话,那么这就涉及到线程的调度了。在java中通过wait(),notify(),notifyAll()来实现,这三个方法是在Object类中定义的,当你想让线程挂起的时候调用obj.wait()方法,在同样的obj上调用notify()则让线程重新开始运行。 最后以SUN提供的Producer/Consumer的例子来结束这篇文章,内容是Producer产生一个数字而Consumer消费这个数字,这个小程序里面基本覆盖了本文所有的知识点。请详细研究一下代码
public class Producer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Producer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
for (int i = 0; i < 10; i++) {
cubbyhole.put(i);
System.out.println("Producer #" + this.number
+ " put: " + i);
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
}
}
}
public class CubbyHole {
private i
nt contents;
private boolean available = false;
public synchronized int get() {
while (available == false) {
try {
wait();
} catch (InterruptedException e) { }
}
available = false;
notifyAll();
return contents;
}
public synchronized void put(int value) {
while (available == true) {
try {
wait();
} catch (InterruptedException e) { }
}
contents = value;
available = true;
notifyAll();
}
}
public class Consumer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Consumer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = cubbyhole.get();
System.out.println("Consumer #" + this.number
+ " got: " + value);
}
}
}
public class ProducerConsumerTest {
public static void main(String[] args) {
CubbyHole c = new CubbyHole();
Producer p1 = new Producer(c, 1);
Consumer c1 = new Consumer(c, 1);
p1.start();
c1.start();
}
}
SUN说输出的结果应该是如下形式,但是在我的机器上却不是这样的,做了一些改动才正确,有兴趣的朋友可以运行一下看看结果,欢迎和我讨论一下!
Producer #1 put: 0
Consumer #1 got: 0
Producer #1 put: 1
Consumer #1 got: 1
Producer #1 put: 2
Consumer #1 got: 2
Producer #1 put: 3
Consumer #1 got: 3
Producer #1 put: 4
Consumer #1 got: 4
Producer #1 put: 5
Consumer #1 got: 5
Producer #1 put: 6
Consumer #1 got: 6
Producer #1 put: 7
Consumer #1 got: 7
Producer #1 put: 8
Consumer #1 got: 8
Producer #1 put: 9
Consumer #1 got: 9
Java代码编写30条建议
例如:
ThisIsAClassName
thisIsMethodOrFieldName
若在定义中出现了常数初始化字符,则大写static final基本类型标识符中的所有字母。这样便可标志出它们属于编译期的常数。
Java包(Package)属于一种特殊情况:它们全都是小写字母,即便中间的单词亦是如此。对于域名扩展名称,如com,org,net或者edu等,全部都应小写(这也是Java 1.1和Java 1.2的区别之一)。
(2) 为了常规用途而创建一个类时,请采取"经典形式",并包含对下述元素的定义:
equals()
hashCode()
toString()
clone()(implement Cloneable)
implement Serializable
(3) 对于自己创建的每一个类,都考虑置入一个main(),其中包含了用于测试那个类的代码。为使用一个项目中的类,我们没必要删除测试代码。若进行了任何形式的改动,可方便地返回测试。这些代码也可作为如何使用类的一个示例使用。
(4) 应将方法设计成简要的、功能性单元,用它描述和实现一个不连续的类接口部分。理想情况下,方法应简明扼要。若长度很大,可考虑通过某种方式将其分割成较短的几个方法。这样做也便于类内代码的重复使用(有些时候,方法必须非常大,但它们仍应只做同样的一件事情)。
(5) 设计一个类时,请设身处地为客户程序员考虑一下(类的使用方法应该是非常明确的)。然后,再设身处地为管理代码的人考虑一下(预计有可能进行哪些形式的修改,想想用什么方法可把它们变得更简单)。
(6) 使类尽可能短小精悍,而且只解决一个特定的问题。下面是对类设计的一些建议:
一个复杂的开关语句:考虑采用"多形"机制;
数量众多的方法涉及到类型差别极大的操作:考虑用几个类来分别实现;
许多成员变量在特征上有很大的差别:考虑使用几个类.
(7) 让一切东西都尽可能地"私有"--private。可使库的某一部分"公共化"(一个方法、类或者一个字段等等),就永远不能把它拿出。若强行拿出,就可能破坏其他人现有的代码,使他们不得不重新编写和设计。若只公布自己必须公布的,就可放心大胆地改变其他任何东西。在多线程环境中,隐私是特别重要的一个因素--只有private字段才能在非同步使用的情况下受到保护。
(8) 谨惕"巨大对象综合症"。对一些习惯于顺序编程思维、且初涉OOP领域的新手,往往喜欢先写一个顺序执行的程序,再把它嵌入一个或两个巨大的对象里。根据编程原理,对象表达的应该是应用程序的概念,而非应用程序本身。
(9) 若不得已进行一些不太雅观的编程,至少应该把那些代码置于一个类的内部。
(10) 任何时候只要发现类与类之间结合得非常紧密,就需要考虑是否采用内部类,从而改善编码及维护工作(参见第14章14.1.2小节的"用内部类改进代码")。
(11) 尽可能细致地加上注释,并用javadoc注释文档语法生成自己的程序文档。
(12) 避免使用"魔术数字",这些数字很难与代码很好地配合。如以后需要修改它,无疑会成为一场噩梦,因为根本不知道"100"到底是指"数组大小"还是"其他全然不同的东西"。所以,我们应创建一个常数,并为其使用具有说服力的描述性名称,并在整个程序中都采用常数标识符。这样可使程序更易理解以及更易维护。
(13) 涉及构建器和异常的时候,通常希望重新丢弃在构建器中捕获的任何异常--如果它造成了那个对象的创建失败。这样一来,调用者就不会以为那个对象已正确地创建,从而盲目地继续。
(14) 当客户程序员用完对象以后,若你的类要求进行任何清除工作,可考虑将清除代码置于一个良好定义的方法里,采用类似于cleanup()这样的名字,明确表明自己的用途。除此以外,可在类内放置一个boolean(布尔)标记,指出对象是否已被清除。在类的finalize()方法里,请确定对象已被清除,并已丢弃了从RuntimeException继承的一个类(如果还没有的话),从而指出一个编程错误。在采取象这样的方案之前,请确定finalize()能够在自己的系统中工作(可能需要调用System.runFinalizersOnExit(true),从而确保这一行为)。 (15) 在一个特定的作用域内,若一个对象必须清除(非由垃圾收集机制处理),请采用下述方法:初始化对象;若成功,则立即进入一个含有finally从句的try块,开始清除工作。
(16) 若在初始化过程中需要覆盖(取消)finalize(),请记住调用super.finalize()(若Object属于我们的直接超类,则无此必要)。在对finalize()进行覆盖的过程中,对super.finalize()的调用应属于最后一个行动,而不应是第一个行动,这样可确保在需要基础类组件的时候它们依然有效。
(17) 创建大小固定的对象集合时,请将它们传输至一个数组(若准备从一个方法里返回这个集合,更应如此操作)。这样一来,我们就可享受到数组在编译期进行类型检查的好处。此外,为使用它们,数组的接收者也许并不需要将对象"造型"到数组里。
(18) 尽量使用interfaces,不要使用abstract类。若已知某样东西准备成为一个基础类,那么第一个选择应是将其变成一个interface(接口)。只有在不得不使用方法定义或者成员变量的时候,才需要将其变成一个abstract(抽象)类。接口主要描述了客户希望做什么事情,而一个类则致力于(或允许)具体的实施细节。
(19) 在构建器内部,只进行那些将对象设为正确状态所需的工作。尽可能地避免调用其他方法,因为那些方法可能被其他人覆盖或取消,从而在构建过程中产生不可预知的
(20) 对象不应只是简单地容纳一些数据;它们的行为也应得到良好的定义。
(21) 在现成类的基础上创建新类时,请首先选择"新建"或"创作"。只有自己的设计要求必须继承时,才应考虑这方面的问题。若在本来允许新建的场合使用了继承,则整个设计会变得没有必要地复杂。
(22) 用继承及方法覆盖来表示行为间的差异,而用字段表示状态间的区别。一个非常极端的例子是通过对不同类的继承来表示颜色,这是绝对应该避免的:应直接使用一个"颜色"字段。
(23) 为避免编程时遇到麻烦,请保证在自己类路径指到的任何地方,每个名字都仅对应一个类。否则,编译器可能先找到同名的另一个类,并报告出错消息。若怀疑自己碰到了类路径问题,请试试在类路径的每一个起点,搜索一下同名的.class文件。
(24) 在Java 1.1 AWT中使用事件"适配器"时,特别容易碰到一个陷阱。若覆盖了某个适配器方法,同时拼写方法没有特别讲究,最后的结果就是新添加一个方法,而不是覆盖现成方法。然而,由于这样做是完全合法的,所以不会从编译器或运行期系统获得任何出错提示--只不过代码的工作就变得不正常了。
(25) 用合理的设计方案消除"伪功能"。也就是说,假若只需要创建类的一个对象,就不要提前限制自己使用应用程序,并加上一条"只生成其中一个"注释。请考虑将其封装成一个"独生子"的形式。若在主程序里有大量散乱的代码,用于创建自己的对象,请考虑采纳一种创造性的方案,将些代码封装起来。
(26) 警惕"分析瘫痪"。请记住,无论如何都要提前了解整个项目的状况,再去考察其中的细节。由于把握了全局,可快速认识自己未知的一些因素,防止在考察细节的时候陷入"死逻辑"中。
(27) 警惕"过早优化"。首先让它运行起来,再考虑变得更快--但只有在自己必须这样做、而且经证实在某部分代码中的确存在一个性能瓶颈的时候,才应进行优化。除非用专门的工具分析瓶颈,否则很有可能是在浪费自己的时间。性能提升的隐含代价是自己的代码变得难于理解,而且难于维护。
(28) 请记住,阅读代码的时间比写代码的时间多得多。思路清晰的设计可获得易于理解的程序,但注释、细致的解释以及一些示例往往具有不可估量的价值。无论对你自己,还是对后来的人,它们都是相当重要的。如对此仍有怀疑,那么请试想自己试图从联机Java文档里找出有用信息时碰到的挫折,这样或许能将你说服。
(29) 如认为自己已进行了良好的分析、设计或者实施,那么请稍微更换一下思维角度。试试邀请一些外来人士--并不一定是专家,但可以是来自本公司其他部门的人。请他们用完全新鲜的眼光考察你的工作,看看是否能找出你一度熟视无睹的问题。采取这种方式,往往能在最适合修改的阶段找出一些关键性的问题,避免产品发行后再解决问题而造成的金钱及精力方面的损失。
(30) 良好的设计能带来最大的回报。简言之,对于一个特定的问题,通常会花较长的时间才能找到一种最恰当的解决方案。但一旦找到了正确的方法,以后的工作就轻松多了,再也不用经历数小时、数天或者数月的痛苦挣扎。我们的努力工作会带来最大的回报(甚至无可估量)。而且由于自己倾注了大量心血,最终获得一个出色的设计方案,成功的快感也是令人心动的。坚持抵制草草完工的诱惑--那样做往往得不偿失
J2ME开发的一些体会
游戏学院培训模式
游戏被称为“第九艺术”,游戏开发是集剧情、美术、音乐、动画、程序等为一体的复合技术,因此,需要多样化的游戏从业人员。其中高中学历人员可向游戏运营与管理、市场营销方面发展;女生、文科生、大专生在游戏策划、架构设计等领域占优势;美术特长生可在 3D游戏动画设计方面一展身手;应届毕业生先通过职业培训,掌握职业技能后,顺利进入游戏行业工作;而计算机及相关专业则从事手机游戏、网络游戏开发等职位。
由北京汇众益智科技有限公司联合信息产业部电子教育中心、香港职业训练局举办的游戏学院项目,在教学模式上比较韩国、日本、美国等游戏培训课程的优势后,采用案例教学、实例教学、实践项目开发相结合的教学模式, 设立游戏运营管理、游戏架构设计、 3D 游戏设计、移动(手机)游戏开发、在线游戏设计与开发等多个方向的培养。
游戏学院与国际游戏开发教育联合会合作推出 2005新版课程体系 是国内市场上率先推出的系统化游戏专业培训体系,避免了某些培训机构的单一课程使学员与游戏企业实际要求相脱节的问题。过硬的国际国内双重认证、极强的实际开发操作能力,使游戏学院培养出来的学员具备在游戏公司一年开发经验的综合实力,成为各大游戏开发公司争抢对象。同时, 为游戏企业定制培训急需的游戏人才, 8个月成为游戏开发高手,更有游戏工厂与创业孵化器助学员自主创业。
8-10个月成就游戏设计与开发高手,快到游戏学院来!
就读游戏学院,将获以下职业技能:
就业职位 | 薪资 (元/月) | 入学条件 | |
游戏 运营与客服 | 2000 - 4000 |
| |
游戏策划与架构设计师 | 4000 - 10000 | ||
游戏动画设计师 | 4000 - 10000 | ||
手机游戏开发工程师 | 5000 - 10000 | ||
网络游戏开发工程师 | 5000 - 10000 |
主办机构: 北京汇众益智科技有限公司 信息产业部电子教育中心 香港职业训练局
专家型师资: 全部教师均具有多年游戏经验,并持有信息产业部电子教育中心及香港职业训练局高级培训师资格证书
学习成果:
1 、学习期间完成多款手机、网络游戏设计与开发;
2 、合格学员将获得国家、国际双重权威认证。
就业单位:
7000 余家手机、网络游戏开发及增值服务商;
年接受实习就业 4000 人以上的“游戏工厂。
专业名称 | 课程 | 课程名称 | 课程科目 | 课时数 | 课程目标 |
游 | GC01 | 游戏架构设计与策划 |
| 60 | 掌握不同类型游戏架构,精通游戏设计及规划,掌握游戏运营管理,熟悉国际国内知名游戏公司成功运营模式,成为合格的游戏运营管理人员,游戏架构设计师。 |
GC02 | 游戏运营管理 |
| 60 | ||
GC03 | 3D游戏设计与制作 (上) |
| 60 | 熟练掌握 3dsmax的多边形建模工具、UV展开贴图工具和骨骼动画制作工具等,具备制作游戏道具、场景、角色和动画技能,成为合格的3D游戏设计师。 | |
GC04 | 3D游戏设计与制作 (下) |
| 60 | ||
GC05 | 手机游戏开发 (上) |
| 60 | 具备 JAVA编程能力,掌握手机游戏设计模式精通J2ME开发,熟悉国内手机游戏开发规范,运营模式等,成为合格的手机游戏开发工程师。 | |
GC06 | 手机游戏开发 (下) |
| 60 | ||
GC07 | 网络游戏引擎实现 |
| 120 | 具有 D3D编程、开发应用,网络游戏客户端编程能力;掌握网络游戏引擎实现技术;具备利用引擎建模、编程、脚本编辑等开发能力;掌握网络游戏脚本编程技术;成为合格的网络游戏开发工程师。 | |
GC08 | 网络游戏脚本编程 |
| 120 | ||
GC09 | 拓展与职业素质培养 |
| 46 | 增强学员自信心,掌握职业礼仪、沟通技巧、面试、应聘等就业技巧,增强学员就业竞争力。 | |
|
|
| 600+46 |
|
给J2ME初学者的建议
给J2ME初学者的建议
最近几天,有很多初学J2ME的朋友向我询问初学J2ME应该注意些什么东西,我仔细想了一下,给大家如下的几点建议:
1.首先要基本了解面向对象的编程方法,对类和方法要有一定的理解,特别是继承,派生,多态等特性, 这个是最根本的基础。
2.最好手边有一本J2ME开发参考手册,里面有J2ME的所有内部类的详细介绍,J2ME能不能做好,根本上是你对内部类的理解和应用。对于初学者来说,java.lang.*,javax.microedition.lcdui.*,javax.mijcroedition.midlet.*是最先要掌握的包,对这个包里的内部类的基本用法都要有足够的了解。J2ME的游戏编程在我看来就是一个主MIDlet类加上若干Canvas类再加上其他的辅助类(包括自己定义的类)组成的一个整体。
3.用别人的代码来学习,但不要看太多代码,也不要一开始就看很复杂的代码(超过3000行的代码),因为你对面向对象编程的不熟悉,一开始就看由很多类,并且有的类的代码超过几千行的话,只会让你一头雾水,得到的指导也不会太多。在学习的时候,自己为代码加上自己的注释,只有这样才真正说明你看懂了这些代码。
4.在学习的过程要自己做例子,曾经有朋友跟我抱怨说自己不知道做什么项目来训练,其实自己做练习并不一定要一个很完整的项目,可以从一些最基本的游戏模块开始练习,比如,如何在屏幕上显示一张图片或者多张图片,如何来实现这些图片的重叠和移动(手动控制移动或者自动移动),如何在显示图片的时候调出一个Form来显示一些信息,然后又能够切换回图片,这些小的练习虽然不能够形成一个完整的游戏,但他是做游戏的基础,所以初学者一定不要一开始就拿一个很大的项目来做,那样只会让你总是做得似是而非,要踏踏 实实从小做起,每个高手都是这样走过来的,像我们离高手还有很远的距离,只能够从这些点滴的练习中积累自己的经验。
5.程序的优化,算法设计这些不是初学者应该去研究的东西,这些是当你已经能够独立完成一个完整的小游戏之后才要考虑的东西,程序的优化也不是三言两语能够说清的,很多优化上的数据和办法都是前人在作过无数次实验之后才得出的结论,是非常珍贵的,至于算法,在J2ME中设计算法其实比在C++中更累,因为你设计的算法最起码要保证在手机上运行不至于死掉(这就是为什么传统的A*算法基本不能够直接移植到手机上的原因)。
6.多和别人交流,在交流的过程中,你会得到更多的经验,事实上就算是水平不高的编程者也会在某些方面有自己独到的见解,这会教会你很多的东西。
J2ME应用程序内存优化三招
| J2ME应用程序内存优化三招 |
作者:佚名 来自:天极网 out momory 一阵天旋地转内存又溢出了。在手机上这种痛苦经常都有,套一句俗话在手机上用内存必须勒紧裤腰带。虽然现在pc内存上G都不奇怪,可是在手机上却只能以K来记,可能某位同志会马上跳出来说也有上M的,记住中国还不富大多数手机都是低端手机。写手机程序让我仿佛回到了dos时代(自我安慰一下那个时代也炼出了不少高手说不定我是下一个)。言归正传做内存优化可以归结为以下几种方法。代码优化,图片优化,第三方工具优化等… 一.代码优化 内存会溢出肯定和代码逃不了关系,99.99%学java的人都知道垃圾回收器是java的一大优点并据此来嘲笑C++。显然这个特性为代码编写者省了不少事,但这个特性却带来了不少隐患。举个例子在游戏当中经常有不同场景的切换,如从游戏逻辑退到主菜单逻辑,对游戏逻辑对象的态度很多人会选择忘记等待垃圾回收器来收尸。乍看之下似乎并无不妥垃圾回收器会来善后。实际上垃圾回收器并非实时的,它不像C++的Delete语句马上释放不用的内存。当从游戏逻辑切换到主菜单逻辑这时两个对象同时存在很可能这时内存就不够用了。读到这里很多人会发现实际上垃圾回收器在j2me上并不怎么好用,从一个角度上来讲在j2me上所有垃圾必须由手工释放,除简单类型以外所有对象都必须显式地置空例如 imgs=null; 实际上java提供了一个不错的工具用来查找内存溢出,java.lang.Runtime.freeMemory() 。它可以返回当前的剩余内存数,将它适当的安放在代码中可以有效的监测内存使用状况。很大一部份的j2me程序员之前都是从事pc软件开发工作,充裕的内存掩盖了许多写代码的不良习惯。如下所示: //a 不为空 a=new Logic(); 很多人可能对此有异议,他们会认为新的对象会把旧的对象冲掉并且释放内存。这里面包含两个问题:1. 该段代码是先创建对象然后再进行赋值操作的,也就是说在这期间有两个对象同时存在这就很可能会产生溢出。2. 这样做也会妨碍垃圾回收器的工作 较好的写法如下: a=null; a=new Logic(); 虽然麻烦了点但在j2me中还是必要的。接着看下例。 drawString("游戏时间:" + time ,50,50,Graphics.LEFT|Graphics.TOP); "游戏时间:" + time 很完美在paint()方法当中每次都被刷一遍显示在屏幕上。危机往往隐藏在美丽的外表,该语句会引起新的内存重新分配来存储 "游戏时间:" + time 而显示完以后又必须由垃圾回收器释放,用了双倍时间,并且容易发生内存溢出。依此类推在重复执行的方法里应尽量避免重复定义对象。与paint()方法类似在循环里也有类似的情况存在。 把所有对象的初始化放在构造函数里想必是再正当不过了,大多数人通常的做法是把当前逻辑所要用到的资源通通初始化完毕。 很大一部份的内存溢出都是发生在构造函数中。内存使用的高峰期都是在构造函数中所以避开这个高峰能有效的防止溢出。建议最好的办法是第一次使用时初始化。如下所示 if (img==null){ 现在做游戏很多时候都需要地图数组,声音数组,还有一些其它资源这些资源很多可以放在代码中也有的可以放在文件当中。 强烈建议将这些资源放在文件中需要时在load进来。这些资源文件如果放在代码中则会占用不小的代码段空间,而代码一般是程序一运行就装载到内存当中。 除上面列举的方法外还有一些大家所熟知的顺便一提, 比如关闭没用的rms ,关闭没用的网络连接,关闭没用的流。正确地停止线程。良好的程序架构减少代码偶合性也是一个不错的方法,无论在代码调式,内存释放都可以做到非常清析。 二.图片优化 j2me的内存杀手无疑非图片莫属,一张3k的图片可以占用20多k的内存不信大家把load前后的内存剩余打印出来对比看看。所以防止内存溢出最直接的办法就是从图片入手。 1.图片压缩: 多数人马上会想到这个办法。不错这个办法是最有效的。在photoshop里图片制作完成后不要选择 "存储为",而是选择 "存储为 web 所用格式" 可以根据里面的选项进行压缩,特别是颜色这一项越小越好不过相应的图像会有所失真。不要认为这样就完了。 实际上该图片还可以再次压缩,在网上有许多类似的工具。推荐一款可以压缩png格式的软件 xat.com Image Optimizer 效果不错。经常都有 70% 的压缩率且图像不会失真。 假如你有多张规格一样的图片,那么建议你把它做成一张长条图片。有两个原因: 1、 这样节省存储空间和内存空间。大家可做个试验将10张图片的内容放在一张当中对比看看文件大小有没有变化。 作图时还有一些细节需要注意,颜色数量,分辩率,图像模式(最好是索引颜色),画布大小都会影响到图片大小。 三.工具优化 谁都知道混淆器是用来保护代码的以加大反编译的难度(个人认为这是在嘲笑程序员的智商)。实际上用它来优化程序也是不错的选择,至少有两点好处: 1、 压缩程序大小。一个60k的程序经常可以压掉10k左右。10k的空间对于写低端手机的程序员简直是雪中送碳,多少超过64k限制的游戏都受过它的恩惠; |
全面认识JAVA
| 全面认识JAVA |
作者:刘静 来自:沈阳银河网络教育中心 作SCJP培训已经有一段时间了,到我这学习的有在校的大学生,也有在职的开发人员。通常这些学员此前都对Java已有一些了解,但普遍对Java缺乏总体的认识。于是学员总是问,Java应该怎么学?Java能做什么?什么是Applet?什么是Servlet、Jsp、EJB?还有Webspere、Weblogic又是做什么的等等。之所以学员会有这些疑问,是因为大家普遍对Java相关概念听说的太多而了解的又相对少的缘故。 学通Java语言需要一个过程,所有Java相关的概念都会在学习的过程中逐渐变得清昕。这个过程的开始就是要先学会标准的Java技术(J2SE),然后是学Java的简单Web运用,然后分布式运用,再以后对Java的移动技术运用就很容易理解了。 以下是Java标准技术的一些要点: 一、Java的跨平台性,即一次编译到处运行 简单地说Java的跨平台性就是指,编译后的Java程序可直接在不同的平台上运行而不用重新编译,这一特性使得Java随着Web应用的普及而迅速普及起来。而Java的跨平台性是如何实现的呢?这就要理解Java虚拟机和字节码的概念。 实际上,编译后的Java代码并不是传统的二进制代码(如Windows下的.exe文件),而是Java字节码,这种字节码文件是不能直接在操作系统上执行的。要想在一个操作系统上运行一个Java程序必须有一个中间环节来负责将Java字节码解释成二进制码,这个中间环节就是Java虚拟机(简称JVM)。由于目前大多数操作系统已经实现了JVM,所以Java轻松实现跨平台性。 二、面象对象技术 Java全面支持面象对象技术,这体现在Class(类)是Java程序构成的基本单元,一个Java程序通常由许多Class组成,而且这些Class还会有一定的继承关系,Java支持Class的单继承,从而使类之间的继承关系更明确。继承的结果产生类的多态性,类的多态本质上讲就是可以用父类的引用访问继承类的实现(子类对象),类的这种多态性最终形成了组件对象模型的基础,即通过接口(父类)访问实现(子类)。 三、Java中的I/O操作 Java中以字节流(InputStream和OutputStream)、节符流(Reader和Writer)来分别读写二进制数据和字符数据,使用非常简单有效。Java类库中的File类不仅提供文件操作而且还包含文件夹操作,如下面这几行代码可以列出C盘根目录下的所有文件: File f=new File("c://"); 四、Java中的图形及事件处理 可以用awt包或swing包的Java类来进行大部分的Java图形界面设计,下面的几行代码将产生一个200*200像素的窗体: Frame f=new Frame("Welcome"); 默认情况下,Frame窗体的关闭按钮不起作用,这也是Java初学者迷惑的地方。为了使用户按下关闭按钮时能关闭Frame窗体,需要让这个窗体响应一个WindowEvent事件,具体的做法就是给这个窗体添加一个事件监听器对象,这个事件监听器就是WindowListener接口的实现。在上面的代码中插入如下代码就可以关闭窗体: f.addWindowListener(new WindowAdapter(){ 这里用到一个无名内部类,无名内部类是Java中内部类的一种灵活运用方式。 五、Java中线程及同步控制 线程概念的引入是为了实现并行处理,从而提高程序的效率。Java中的线程实现非常简单,可以用两种方式来创建线程,一种是实现Runnable接口,另一种是继承Thread类重写run()方法。两种方式唯一的不同就是前者保留了继承一个类的可能(因为Java只支持类的单继承,但接口没有此限制)。 永远都用start()方法来启动一个线程,线程类中的run()可以被直接调用,但决不是启动一个线程,二者有着本质的区别。 用同步控制关键字synchronized来保护线程敏感数据,synchronized块中的内容可以保证同一时刻只能被一个线程访问,所以其中的数据是线程安全的。 用Object类中的wait()和notify()方法可以实现线程间交互,但要记住wait()和notify()方法只有发生在同一个对象上才能真正实现线程间交互。被某一对象wait()方法阻塞的线程需要另外一个调用了同一对象notify()的线程干预才能恢复运行。notify()方法一次唤醒一个被wait()方法阻塞的线程,notifyAll()方法可以一次唤醒所有被wait()方法阻塞的线程。 六、Java本地方法(native方法)的实现 Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。 可以将native方法比作Java程序同C程序的接口,其实现步骤: 1、在Java中声明native()方法,然后编译; 上述所提及的一些Java技术具有一定的普遍性,它们基本上是在Java各个方面的运用中都需要掌握的术。实际上Java的运用非常广泛,而且每个方面都需要遵循不同的规范。以下是对Java应用的简要介绍。 (一)理解Java SDK的三个版本: Java SDK Micro Edition (J2ME) 用于开发掌上电脑、手机等移动通信设备上使用的应用程序。并不是所有的移动设备都支持Java,只有具备J2ME运行环境(JVM+J2ME API)的设备才能运行Java程序。J2ME的集成开发工具(通常都有带有一些访真器)有 Sun 的J2ME Wireless Toolkit 、IBM的Visul Age Micro Edition 等。 Java SDK Standard Edition(J2SE) 主要用于开发一般台式机应用程序。我们平时所说的JDK就指J2SE,而我们学Java就是从学习J2SE开始的。 Java SDK Enterprise Edition (J2EE) 用于开发分布式的企业级大型应用程序。其中的核心是Entetprise Java Beans(EJB,分布式Java组件)的开发。 (二)Java小程序 (Applet) Java小程序是一个继承了Applet类并重写了init()、paint()、stop()等方法的的Java类,它被布署在Web服务器(如IIS)上,当客户端请求Web页时,浏览器从Web服务器上将其下载到本地客户端,然后,浏览器创建该Applet类的实例并调用其init()方法,从安全角度考虑,Applet没有访问本地文件的权限。由于Applet是被浏览器执行的,所以Applet不需要一个main()方法。实际上,除了Java Application之外,所有其它Java应用都不需要一个main()方法。 (三)服务器端Java小程序 (Servlet) Servlet也是一个Java类,和Applet形成对比,Servlet是运行于服务器端的Java小程序,而且Servlet需要一个单独的Web服务器(如Tomcat)做容器。除此之外,Servlet中用到的一些类(如HttpServlet)并不包含在J2SE API中,所以需要将Servlet.jar(在Tomcat的common\lib文件夹下)加到环境变量中去。下面是一个简单的Servlet例子: public class Myservlet extends HttpServlet{ public void doGet(HttpServletRequest request,HttpServletResponse response) 将这个Class文件编译后放至Tomcat\webapps\examples\WEB-INF\classes下,然后在浏览器地址栏里输入http://127.0.0.1:8080/examples/servlet/Myservlet即可看到 Hello world出现在浏览器中。 (四)Java Server Page (JSP) 同Servlet相似的是,JSP运行于Web服务器端,并且也需要Tomcat之类的容器。不同的是,由于JSP是将Java代码嵌在html标记里(同ASP一样用<% ...%>),JSP的界面设计同后台开发人员的工作可以有效分离。可以想像让开发人员用Servlet写一个花捎的Web页面有多困难,所以JSP+Servlet混合Web应用是比较理想的选择。 看起来JSP同ASP的实现机制大同小异,其实也存在着本质的区别。所有的ASP页面都是解释运行的,而JSP页在第一次被请求时会被编译,再以后的客户请求都是直接运行服务器上的.class文件(在Tomcat的Work文件夹下),所以JSP要比ASP速度上快许多。 (五)Java Beans Java Bean 是可复用的组件,对Java Bean并没有严格的规范,理论上讲,任何一个Java类都可以是一个Bean。但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。 (六)Enterprise Java Beans (EJB) Java Bean实际上相当于微软COM模型中的本地进程内COM组件,它是不能被跨进程访问的。Enterprise Java Bean 相当于DCOM,即分布式组件。它是基于Java的远程方法调用(RMI)技术的,所以EJB可以被远程访问(跨进程、跨计算机)。但EJB必须被布署在诸如Webspere、WebLogic这样的容器中,EJB客户从不直接访问真正的EJB组件,而是通过其容器访问。EJB容器是EJB组件的代理,EJB组件由容器所创建和管理。客户通过容器来访问真正的EJB组件。 这种模型很像COM+管理器,其实EJB容器正是起到COM+管理器的作用,只是EJB组件相对COM组件来说更易用、更安全。 总的说来,Java作为面象对象技术的一个代表,在当今商业应用中更容易开发出高效的、多层的分布式应用程序,而且,由于Java技术有很强的健壮性和易用性,加上同UML应用的结合,开发一个商业应用软件的周期会大大缩短,所以Java会有不错的前景。 |