Thursday, February 24, 2011

Tạo image header (hay title bằng image) của ứng dụng trên android

Bài trước tôi đã giới thiệu cách control một layout với Image và title. Lần này thêm một bài nữa về layout nhé :D.
Vì vấn đề thương hiệu, các sếp đã bắt Tên của ứng dụng nên để logo của ứng dụng chứ ko chỉ là để chữ không. Mặc định thì nó chỉ hiển thị tên ứng dụng bạn khai báo trong file Manifest. Nhưng bạn hoàn toàn có thể control nó theo ý của mình.

Trước hết tôi design layout main_header cho Title đó như sau.


 

  
 

Ở đây tôi chỉ đưa một image vào đó, nhưng bạn hoàn toàn có thể cho những thứ mà bạn thích vào đây.

Có layout rồi, nhưng làm thế nào để load được nó đây. Bạn để ý thấy trong thẻ Application của file Manifest có thuộc tính sau android:label="@string/app_name":



Cái này chính là cái hiển thị title của ứng dụng.
Ta sẽ ghi đè lên title như sau.
Tạo một style TitleCustomTheme như sau:


 
  
  
 

Và thêm thuộc tính android:theme="@style/TitleCustomTheme" vào trong thẻ application như sau.



Trong class Activity ta load layout đã design như sau:

getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.main_header);

Xem thử kết quả nhé. Nhắc bạn luôn nhớ rằng, thương hiệu luôn là vấn đề sống còn của doanh nghiệp :D.

Xem ảnh demo:

Tuesday, February 22, 2011

Xây dựng grid layout cho android với mỗi phần tử bao gồm Icon + title.

Do dạo này bận dự án quá nên chưa viết loạt bài lập trình game 3D tiếp được, loạt bài này tôi sẽ chỉ các bạn một số thủ thuật trong khi tôi làm dự án của mình.
Giới thiệu sơ qua về dự án của tôi, nó được xây dựng cho mảng bán content cho người dùng giống như Sóc Bay hay một số các phần mềm khác.
Hôm nay tôi sẽ chỉ cách cho các bạn thiết kế layout cho màn hình chính của chương trình. Đó là Grid Layout mỗi phần tử bao gồm các Icon + title bên dưới.
Trước hết chúng ta phải xây dựng được layout cho phần tử bên trong, cái này thì đơn giản quá nhỉ, chỉ cần một ImageView và một TextView là được. Nó trông giống như:

 
  
  
  
  
 

Trong main Activity bạn load View như sau
GridView gridview = (GridView) findViewById(R.id.gridview);
 gridview.setAdapter(new ImageAdapter(this, dictionary, dictionary.getChildList().size()));

Trong đó class ImageAdapter load các phần tử ta xây dựng bên trên và xây dựng lớp đó như sau

package vn.vdco.mzone;

import vn.vdco.mzone.util.DictionaryNode;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * 
 * @author TanNM
 *
 */
public class ImageAdapter extends BaseAdapter {
 private Context mContext;
 private DictionaryNode dictionary;
 private int sizeArray;
 private Integer[] mThumbIds = null;
 private String[] mTitle = null;

 /**
  * 
  * @param c
  * @param dictionary
  * @param sizeArray
  */
 public ImageAdapter(Context c, DictionaryNode dictionary, int sizeArray) {
  this.mContext = c;
  this.dictionary = dictionary;
  this.sizeArray = sizeArray;
  mTitle = new String[sizeArray];
  mThumbIds = new Integer[sizeArray];
 }

 public int getCount() {
  return mThumbIds.length;
 }

 public Object getItem(int position) {
  return null;
 }

 public long getItemId(int position) {
  return 0;
 }

 /**
  * Load layout for Item with Icon and title
  * @param position
  * @param convertView
  * @param parent
  * @return View
  * @author tannm
  */
 public View getView(int position, View convertView, ViewGroup parent) {
  ImageView iv;
  TextView tv;
  View v;
  init();
  if (convertView == null) {
   LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   v = li.inflate(R.layout.main_icon, null);
   tv = (TextView)v.findViewById(R.id.icon_text);
   tv.setText(mTitle[position]);
   iv = (ImageView)v.findViewById(R.id.icon_image);
   iv.setImageResource(mThumbIds[position]);
  } else {
   v = convertView;
  }

  return v;
 }

 /**
  * Load title and icon in config file to array
  * @author tannm
  */
 private void init()
 {
  if(dictionary != null && dictionary.getChildList() != null && dictionary.getChildList().size() >0)
  {
   for (int i = 0; i < sizeArray; i++) {
    DictionaryNode node = (DictionaryNode)dictionary.getChildList().get(i);
    int resID = this.mContext.getResources().getIdentifier("vn.vdco.mzone:drawable/" + node.getString("$Image$"), null, null);
    mThumbIds[i] = resID;
    mTitle[i] = node.mstrValue;
   }
  }
 }
}

Ở trên tôi có dùng một đối tượng DictionaryNode để lưu trữ cấu hình các image và title cho các phần tử. Bạn có thể xem cách load nó trong phương thức init().
Cấu trúc của nó kiểu như sau:
MainMenu
     NEWS==Đọc báo
          $Image$==n
     FUNNY==Hài hước
          $Image$==hh
....
Khi đó ta sẽ load động các hình ảnh và title từ file cấu hình vào. Chú ý, nếu cái này ko cần thiết bạn nên Fix vì trong điện thoại cần tiết kiệm dung lượng và các sử lý không cần thiết tới mức tối đa do bộ nhớ và CPU nhỏ.

Chúc bạn có một layout tuyệt vời cho ứng dụng của bạn.

Sunday, December 12, 2010

Chỉ dẫn lập trình game 3D trên Android (P5)

Đang chờ deploy cái web viết tiếp loạt bài về OpenGL vậy.
Bài hôm nay tôi sẽ giới thiệu cho các bạn cách vẽ một hình đa giác cách xoay chúng như thế nào. Bài trước các bạn đã được học về GLSurfaceView và hãy chắc chắn rằng bạn đã đọc nó vì nó rất quan trọng cho bài hôm nay.
Loạt bài trước tôi cũng đã giới thiệu với các bạn một số khái niệm về đỉnh, tam giác, đa giác. Hôm nay trước khi vào vẽ đa giác tôi sẽ giới thiệu cho các bạn thêm một số khái niệm khác.
1, Cạnh:
Cạnh là một đường thẳng nối 2 đỉnh với nhau. Chúng là đường viền của mặt và đa giác. Trong không gian 3D một cạnh có thể là một đường giao nhau của 2 mặt, do đó khi cạnh này chuyển đổi sẽ dẫn đến sự thay đổi theo của các đỉnh, các mặt kết nối với chúng.
Trong OpenGL ES bạn không định nghĩa các cạnh, thay vào đó bạn định nghĩa các mặt bởi các đỉnh khi đó ta sẽ có các cạnh.
Nếu bạn muốn sửa, thay đổi mộ cạnh bạn có thể thay đổi 2 đỉnh tạo nên cạnh đó.
2, Mặt:
Một cách tổng quát, mặt trong toán học là đa tạp n-1 chiều trong không gian n chiều. Trong tô pô, một mặt hai chiều được gọi là mặt đơn giản nếu nó đồng phôi với một hình vuông trên mặt phẳng hai chiều.
Ví dụ: mặt bán cầu là một mặt đơn giản, còn toàn bộ mặt cầu lại không phải là một mặt đơn giản.
Trong không gian ba chiều, mặt được mặc định là đa tạp hai chiều, là tập hợp những điểm trong hệ tọa độ Đề các ba chiều Oxyz thỏa phương trình: z = f(x,y).
Trong OpenGL ES ta hiểu rằng có thể chia mặt tới mức nhỏ nhất khi đó một mặt chỉ là một tam giác, chúng được tạo lên bởi 3 đỉnh, một chuyển đổi của mặt sẽ ảnh hưởng tới các đỉnh, cạnh liên kết với nó.
Khi uốn khúc trên bề mặt của bạn điều này rất quan trọng để thực hiện các điều khiển đúng hướng của nó. Khi đó bạn phải điều khiển những gì sẽ sảy ra với mặt phía trước và cả mặt phía sau nữa. Tại sao điều này lại rất quan trọng bởi vì hiệu năng của ứng dụng sẽ tăng lên khi bạn không phải vẽ cả 2 mặt mà chỉ thực hiện vẽ mặt phía trước. Đó là ý tưởng tốt sử dụng sự uốn khúc cho tất cả các dự án của bạn. Bạn có thể định nghĩa phía trên của bề mặt bằng cách.
gl.glFrontFace(GL10.GL_CCW); // OpenGL docs
gl.glEnable(GL10.GL_CULL_FACE); // OpenGL docs
gl.glCullFace(GL10.GL_BACK); // OpenGL docs

3, Render:
Thời gian để bạn đưa một cái j đó ra ngoài màn hình, có 2 phương thức để bạn làm điều này, 2 phương thức đó là:
public abstract void glDrawArrays(int mode, int first, int count); // OpenGL docs

public abstract void glDrawElements(int mode, int count, int type, Buffer indices); // OpenGL docs

Một số render cơ bản nhất:
GL_POINTS: Render một điểm ra màn hình.
GL_LINE_STRIP: Render một dãy các phân đoạn đường thẳng nối liền nhau, nhưng không nối điểm đầu và điểm cuối.
GL_LINE_LOOP: Giống như GL_LINE_STRIP nhưng không nối điểm đầu và điểm cuối.
GL_LINES: Render một đường thẳng.
GL_TRIANGLES: Render một tam giác.
GL_TRIANGLE_STRIP: Render một loạt các tam giác theo thứ tự VD: Ta có các đỉnh v0, v1, v2, v3, v4, v5 khi đó các tam giác được render là (v0, v1, v2) sau đó là (v2, v1, v3) (lưu ý thứ tự), tiếp theo là (v2, v3, v4) ...
Gl_triangle_strip
GL_TRIANGLE_FAN: Render một loạt các tam giác giống như GL_TRIANGLE_STRIP nhưng các tam giác được vẽ giống như một hình quạt dựa vào một gốc.
Gl_triangle_strip

Giờ chúng ta sẽ vẽ thử một tam giác:
Bạn vẫn còn project hôm trước chứ, ta sẽ thay đổi một chút để có thể render ra được một tam giác.
Ta chỉ cần sửa lại lớp VortexRenderer lại như sau:

package vn.vndev.android.opengl;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView;

/**
 * 
 * @author TanNM
 * 
 */
public class VortexRenderer implements GLSurfaceView.Renderer {
 private static final String LOG_TAG = VortexRenderer.class.getSimpleName();

 private float red = 0f;
 private float green = 0f;
 private float blue = 0f;

 // a raw buffer to hold indices allowing a reuse of points.
 private ShortBuffer indexBuffer;

 // a raw buffer to hold the vertices
 private FloatBuffer vertexBuffer;

 private short[] indicesArray = { 0, 1, 2 };
 private int nrOfVertices = 3;

 private float angle;

 @Override
 public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  // preparation
  gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  initTriangle();
 }

 @Override
 public void onSurfaceChanged(GL10 gl, int w, int h) {
  gl.glViewport(0, 0, w, h);
 }

 public void setAngle(float angle) {
  this.angle = angle;
 }

 @Override
 public void onDrawFrame(GL10 gl) {
  // define the color we want to be displayed as the "clipping wall"
  gl.glClearColor(red, green, blue, 1.0f);

  // clear the color buffer to show the ClearColor we called above...
  gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

  // set rotation
  gl.glRotatef(angle, 0f, 1f, 0f);

  gl.glColor4f(0.2f, 0.5f, 0.2f, 0.5f);
  gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
  gl.glDrawElements(GL10.GL_TRIANGLES, nrOfVertices,
    GL10.GL_UNSIGNED_SHORT, indexBuffer);
 }

 private void initTriangle() {
  // float has 4 bytes
  ByteBuffer vbb = ByteBuffer.allocateDirect(nrOfVertices * 3 * 4);
  vbb.order(ByteOrder.nativeOrder());
  vertexBuffer = vbb.asFloatBuffer();

  // short has 4 bytes
  ByteBuffer ibb = ByteBuffer.allocateDirect(nrOfVertices * 2);
  ibb.order(ByteOrder.nativeOrder());
  indexBuffer = ibb.asShortBuffer();

  float[] coords = { -0.5f, -0.5f, 0f, // (x1, y1, z1)
    0.5f, -0.5f, 0f, // (x2, y2, z2)
    0f, 0.5f, 0f // (x3, y3, z3)
  };
  vertexBuffer.put(coords);
  indexBuffer.put(indicesArray);
  vertexBuffer.position(0);
  indexBuffer.position(0);
 }

 public void setColor(float r, float g, float b) {
  red = r;
  green = g;
  blue = b;
 }
}

Để hình tam giác của ta quay với tốc độ tùy vào vị chí mà ta click ta set thêm góc giống như
renderer.setAngle((event.getX() + event.getY()) / 20);
trong phương thức
public boolean onTouchEvent(final MotionEvent event)
của lớp VortexView

Bạn có thể download mã nguồn của ứng dụng về chạy thử.

Friday, December 3, 2010

Chỉ dẫn lập trình game 3D trên Android (P4)

Chúc các bạn một ngày tốt lành, hôm qua đi đá bóng về đau chân quá ko làm việc được nên ngồi viết bài tiếp vậy!
Hôm trước ứng bài demo chạy tốt chứ? Hôm nay tôi sẽ giải thích sơ qua một chút về ứng dụng đó.
1, Trước hết là lớp GLSurfaceView:
Bắt đầu được hỗ trợ trên Android từ phiên bản 1.5.
Lớp này hỗ trợ bạn kết nối vào OpenGL từ view bằng cách quản lý một bề mặt và ghép chúng vào hệ thống view của Android. Nó quản lý một EGL display, cho phép OpenGL thực hiện render vào một bề mặt.
Tạo khả năng giúp OpenGL ES làm việc với vòng đời của Activity.
Tạo khả năng lựa chọn định dạng frame buffer pixel một cách thích hợp.
Quản lý các thread rendering riêng biệt cho phép tạo các chuyển động mượt mà :D.
Cung cấp tools debugging một cách đơn giản cho tracing các lời gọi API OpenGL ES và kiểm tra lỗi.

Bạn muốn tiến xa hơn trong OpenGL thì đây là nơi mà bạn cần phải bắt đầu.
Để sử dụng GLSurfaceView bạn chỉ cần gọi phương thức:
 public void  setRenderer(GLSurfaceView.Renderer renderer);
 
có trong GLSurfaceView. Để tùy biến các thuộc tính của GLSurfaceView thì trước khi gọi phương thức setRenderer bạn có thể gọi một số các phương thức khác như:
 setDebugFlags(int);
 setEGLConfigChooser(boolean);
 setEGLConfigChooser(EGLConfigChooser);
 setEGLConfigChooser(int, int, int, int, int, int);
 setGLWrapper(GLWrapper);
 
Mặc định GLSurfaceView sẽ tạo một bề mặt với định dạng mặc định là PixelFormat.RGB_565. Nếu bạn cần một bề mặt trong suốt bạn có thể gọi phương thức getHolder().setFormat(PixelFormat.TRANSLUCENT).
Một GLSurfaceView phải được thông báo khi Activity là paused và resumed. GLSurfaceView clients cần phải gọi phương thức onPause() khi activity pauses và gọi onResume() khi activity resumes. Lời gọi cho phép GLSurfaceView thực hiện pause hay resume các thread rendering, và nó cũng cho phép GLSurfaceView release hay khởi tạo lại các đối tượng OpenGL display.

2, GLSurfaceView.Renderer:
Là một render interface.
Render sẽ được gọi trên một thread riêng biệt vì thế hiệu năng rendering sẽ tách rời UI thread. Nhưng các render cần giao tiếp với các UI thread bởi vì UI thread là nơi nhận được các sự kiện input. Các render có thể giao tiếp bằng bất kỳ kỹ thuật java chuẩn nào cho giao tiếp cross-thread, hoặc đơn giản hơn là sử dụng phương thức queueEvent(Runnable).
Khi bạn implementation render này bạn cần khai báo các phương thức sau:
 // Gọi khi một bề mặt được khởi tạo hay khởi tạo lại
 public void onSurfaceCreated(GL10 gl, EGLConfig config) 

 // Gọi để vẽ frame hiện tại.
 // Phương thức này sẽ chịu trách nhiệm vẽ frame hiện tại.
 public void onDrawFrame(GL10 gl)

 // Gọi khi bề mặt thay đổi kích thước
 public void onSurfaceChanged(GL10 gl, int width, int height)
 

onSurfaceCreated: Đây là nơi tốt để bạn cài đặt một điều gì đó mà bạn không thường xuyên thay đổi trong vòng đời của rendering.
onDrawFrame: Đây là nơi sự kiện vẽ thực sự diễn ra.
onSurfaceChanged: Nếu thiết bị của bạn cho phép chuyển giữa màn hình nằm ngang hay nằm dọc, bạn sẽ có lời gọi tới phương thức này khi sự chuyển đổi đó diễn ra. Bạn có thể thiết lập lại các tỷ lệ mới ở đây

Bạn có thể download mã nguồn của bài trước và bài này tại đây

Thursday, December 2, 2010

Chỉ dẫn lập trình game 3D trên Android (P3)

Hôm nay tôi sẽ chỉ các bạn lập trình OpenGL trong Android, cách sử dụng OpenGL trong cả 2 ngôn ngữ Java và C. Điều này rất quan trọng trong việc tái sử dụng mã nguồn trong Java và C cũng như sử dụng được các tính năng tốt nhất mà mỗi ngôn ngữ cung cấp.
Bất kỳ một nhà phát triển game nào cũng cần phải biết OpenGL là kim chỉ nam cho nhưng nhà phát triển game chuyên nghiệp. Bạn khó có thể tìm thấy một game mạnh mẽ nào mà không sử dụng API của OpenGl, bởi vì nó có khả năng tận dụng và tăng tốc phần cứng hơn hầu hết tất cả các phần mềm renderer khác.
OpenGL có thể là một môn học đáng sợ cho người mới bắt đầu (that's true for me :D). Nhưng bạn cũng không thể thành thạo OpenGL tới mức biết được làm thế nào để nó có thể vẽ các phần tử đó với OpenGL API. Bạn chỉ cần sự ham học hỏi, mong muốn tìm hiểu một công cụ mạnh mẽ để xây dựng các ứng dụng đồ họa như game.
Trong giới hạn của bài này tôi không thể chỉ bạn tất cả về OpenGL mà tôi chỉ đưa ra ví dụ sử dụng chúng trong ứng dụng Android, dựa vào đó và các API của OpenGL bạn có thể tùy biến theo ý của bạn.
Tham khảo thêm về OpenGL tại:
http://www.opengl.org/sdk/docs/man/
http://www.falloutsoftware.com/tutorials/gl/gl0.htm
http://mathworld.wolfram.com/OrthographicProjection.html
http://nehe.gamedev.net/

Về thiết bị thì khỏi bàn, hiện nay Android ngày càng trở nên mạnh mẽ cho việc phát triển các ứng dụng đồ họa.
Để tận dụng tối đa hiệu năng của CPU, Google đã đưa OpenGL Embedded System (OpenGL-ES) vào trong hệ điều hành Android.
OpenGL-ES cung cấp một loạt các API làm cho game có hiệu năng sử lý cao, tăng tốc phần cứng. Đây là các Java API, để xây dựng lại chúng từ C là một công việc rất phức tạp. Tôi sẽ chỉ các bạn cách thức làm việc trên cả Java và C.
Bắt đầu bằng một số khái niệm cơ bản về OpenGL

1, Đỉnh: là một điểm trong không gian 3D trong OpenGl có thể chỉ là 2 tọa độ (x, y) hoặc nhiều tọa độ như (x, y, z, w) ở đó w là tùy chọn và mặc định nó có giá trị là 1.0, tương tự trục z cũng là tùy chọn và giá trị mặc định của nó là 0. Tất các các đối tượng được vẽ bởi các đỉnh hay chính là các điểm, do đó kho nói tới điểm cũng chính là 1 đỉnh.
2, Tam giác: được tạo nên bởi 3 điểm, trong OpenGL chúng ta có thể dùng 3 đỉnh để tạo nên 1 tam giác.
3, Đa giác: được tạo nên bởi nhiều hơn 2 điểm, tam giác cũng là 1 đa giác.

Nào trước hết chúng ta bắt đầu chúng với Java:
Tạo một Android project mới, với activity là Vortex và một số các lớp sau:
package vn.vndev.android.opengl;

import android.app.Activity;
import android.os.Bundle;

/**
 * 
 * @author TanNM
 *
 */
public class Vortex extends Activity {
 private static final String LOG_TAG = Vortex.class.getSimpleName();
 private VortexView vortexView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // Hien thi toan man hinh
  this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN);
  vortexView = new VortexView(this);
  setContentView(vortexView);
 }
}
package vn.vndev.android.opengl;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.view.MotionEvent;

/**
 * 
 * @author TanNM
 *
 */
public class VortexView extends GLSurfaceView {
 private static final String LOG_TAG = VortexView.class.getSimpleName();
 private VortexRenderer renderer;

 /**
  * 
  * @param context
  */
 public VortexView(Context context) {
  super(context);
  renderer = new VortexRenderer();
  setRenderer(renderer);
 }

 public boolean onTouchEvent(final MotionEvent event) {
  queueEvent(new Runnable() {
   public void run() {
    renderer.setColor(event.getX() / getWidth(), event.getY() / getHeight(), 1.0f);
   }
  });
  return true;
 }
}
package vn.vndev.android.opengl;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView;

/**
 * 
 * @author TanNM
 *
 */
public class VortexRenderer implements GLSurfaceView.Renderer {
 private static final String LOG_TAG = VortexRenderer.class.getSimpleName();

 private float red = 0.7f;
 private float green = 0.5f;
 private float blue = 0.8f;

 @Override
 public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
 }

 @Override
 public void onSurfaceChanged(GL10 gl, int w, int h) {
  gl.glViewport(0, 0, w, h);
  float ratio = (float) w / h;
  gl.glMatrixMode(GL10.GL_PROJECTION);
  gl.glLoadIdentity();
  gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
 }

 @Override
 public void onDrawFrame(GL10 gl) {
  gl.glClearColor(red, green, blue, 1.0f);
  gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
 }

 public void setColor(float r, float g, float b) {
  red = r;
  green = g;
  blue = b;
 }
}
Ok giờ bạn hãy chạy thử ứng dụng và click lên các vị trí khác nhau của màn hình. Thấy j nhỉ?

Friday, November 26, 2010

Tối ưu hóa ứng dụng J2ME

Ứng dụng trên J2ME thường bị chậm bởi hạn chế về bộ nhớ, vậy làm sao để chúng ta có thể tối ưu hóa ứng dụng J2ME của mình. Đây là một số chỉ dẫn có ích cho bạn:
1, Khởi tạo và hủy bỏ đối tượng: Khi tạo một đối tượng bằng từ khóa new chúng sẽ chiếm một bộ nhớ của thiết bị do đó chỉ nên tạo đối tượng khi cần thiết, nên sử dụng lại các đối tượng đã có. Không nên tạo đối tượng trong các vòng lặp

for (int i = 0; i < length; i++) {
ClassName p = new ClassName ();
results[i] = p.calculateResult();
}


Chú ý: Khi sử dụng toán tử "+" với các chuỗi String nhỏ khi đó nó sẽ tạo ra các đối tượng String không cần thiết vì thế nếu sử dụng thao tác với chuỗi tôi khuyến cáo các bạn nên dùng StringBuffers hoặc mảng char

2, Trong vòng lặp bạn không nên sử dụng các thuật toán phức tạp, các tính toán trong vòng lặp. Một số cách khai báo vòng lặp tối ưu:


//Một vòng lặp tồi (Vòng lặp a)
for (int i = 0; i < v.size(); i++) {
// Do something
}
//Tốt hơn vòng lặp a (Vòng lặp b)
int size = v.size();
for (int i = 0; i < size; i++) {
// Do something
}
//Tốt hơn vòng lặp b (Vòng lặp c)
for (int i = 0,n = v.size(); i < n; i++) {
// Do something
}
/* Nếu thứ tự trong đối tượng bạn duyệt không quan trọng, bạn hãy duyệt ngược lại như bên dưới để tranh các biến local trong stack. So sánh với 0 luôn hiệu quả nhất trong các ngôn ngữ */
//Tốt hơn vòng lặp c
for( int i = v.size() - 1; i >= 0; i-- ) {
// Do something
}


3, Phân chia ứng dụng của bạn ra: Một MIDP trong thời gian thực thi sẽ load các lớp mà chúng cần, khi đó nếu một lớp lớn sẽ làm tốn bộ nhớ hơn. Hãy chia ra các lớp nhỏ nếu có thể.
Trong câu lệnh import, chỉ rõ lớp mà bạn sử dụng, không nên để như vn.vndev.mzone.util.* mà nên để như vn.vndev.mzone.util.StringUtil
Khai báo biến, khai báo là public nếu có thể bởi vì khi bạn khai báo private bạn sẽ phải truy xuất chúng thông qua phương thức getter và setter khi đó sẽ tốn hiệu năng hơn.

4, Tránh sử dụng thread, khi sử dụng một vài synchronization, hiệu năng của hệ thống sẽ giảm xuống 2/3 lần

5, Sử dụng lại các thành phần giao diện giống như Forms,TextBox... thay vì khởi tạo chúng nếu có thể, điều này làm giảm bộ nhớ sử dụng của ứng dụng.

6, Tránh thường xuyên mở Recordstores

7, Sử dụng loại phù hợp cho biến trong J2ME, như vậy sẽ tránh lãng phí bộ nhớ RAM

8, Sử dụng lại biến: Cố gắng sử dụng lại biến cang nhiều càng tốt, bởi vì tạo nhiều biến làm giảm hiệu năng và tốn dung lượng bộ nhớ. Bằng cách khai báo các biến global và nhớ ko làm ảnh hưởng tới design của lớp.

9, Chia các mảng đa chiều thành các mảng 1 chiều, truy xuất mảng đa chiều luôn làm giảm hiệu năng hệ thống.

10, Tính toán: Nên sử dụng các toán tử dịc bit thay vì dùng các toán tử bình thường khác ví dụ: sử dụng int a = 11<< 1 thay vì dùng int a = 11* 2.
Thay vì nhân chia ta nên sử dụng cộng và trừ càng nhiều càng tốt.

11, Sử dụng lời gọi Native Methods: giống như String.indexOf(), String.lastIndexOf()

12, Sử dụng obfuscater trong ứng dụng của bạn.
Đừng gọi garbage collector trong chương trình của bạn:
System.gc();

Tránh sử dụng synchronization.

13, Cố gắng giữ tính đa hình của đối tượng bằng các interface.

14, Sử dụng Singleton Design Pattern.