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.

Thursday, November 18, 2010

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

Bài hôm nay tôi sẽ hướng dẫn các bạn biên dịch native code trong ứng dụng Android.
JNI là viết tắt của Java Native Interface. Sử dụng JNI chúng ta có thể gọi các hàm được viết trong những ngôn ngữ khác từ Java.
Trước hết bạn tạo một Android project tạo một activity MainActivity:

package com.vndev.jni.activities;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import jni.Natives;

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

public class MainActivity extends Activity {
    private static final String LIB = "libch02.so";
    private static final String LIB_PATH = "/data/data/com.vndev.jni.activities/files/" + LIB;

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        try {

            // Install lib

            System.out.println("Installing LIB: " + LIB);

            // Copy lib from assests folder to files folder:

            // /data/data/PKG_NAME/files

            writeToStream(getAssets().open(LIB), openFileOutput(LIB, 0));

            // Load Lib

            System.load(LIB_PATH);

            // Run it

            String[] argv = { "MyLib", "arg1", "arg2" };

            Natives.LibMain(argv);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }



    /**

     * Write to a stream

     * 

     * @param in

     * @param out

     * @throws IOException

     */

    public static void writeToStream(InputStream in, OutputStream out)

            throws IOException {

        byte[] bytes = new byte[2048];

        for (int c = in.read(bytes); c != -1; c = in.read(bytes)) {

            out.write(bytes, 0, c);

        }

        in.close();

        out.close();

    }

}

Trong activity này ta sẽ load thư viện từ C vào bằng cách gọi:

System.load(LIB_PATH);


Activity này gọi một phương thức trong lớp Natives:
Natives.LibMain(argv);


Phương thức này được khai báo:
public static native int LibMain(String[] argv);


Phương thức này có từ khóa native, nó sẽ gọi phương thức LibMain trong thư viên được load ở trên.
Toàn bộ nội dung class Natives sẽ như sau:
package jni;

public class Natives {
    /**
     * Native Main Doom Loop
     * @param argv
     * @return
     */
    public static native int LibMain(String[] argv);
    
    /**
     * This fires on messages from the C layer
     * @param text
     */
    @SuppressWarnings("unused")
    private static void OnMessage(String text, int level) {
        System.out.println("OnMessage text:" + text + " level=" + level);
    }
}

Để tạo file header cho lớp này ta sử dụng javah trong java như sau
Javah -jni Natives


Khi đó ta có file header như sau
/* DO NOT EDIT THIS FILE - it is machine generated */

#include 

/* Header for class jni_Natives */



#ifndef _Included_jni_Natives

#define _Included_jni_Natives

#ifdef __cplusplus

extern "C" {

#endif

/*

 * Class:     jni_Natives

 * Method:    LibMain

 * Signature: ([Ljava/lang/String;)I

 */

JNIEXPORT jint JNICALL Java_jni_Natives_LibMain

  (JNIEnv *, jclass, jobjectArray);



//implements method call by java native



#ifdef __cplusplus

}

#endif

#endif



Giờ bạn cần tạo một file C khác dựa vào khai báo trên cài đặt phương thức này trong C và biên dịch chúng, chạy để thấy kết quả.

Download source

Thursday, November 11, 2010

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

Trước khi bạn bắt đầu, hãy chuẩn bị cho mình một số kỹ năng cần thiết để bắt đầu:
Về ngôn ngữ lập trình, không chỉ Java mà bạn cần biết cả ngôn ngữ lập trình C.
Bởi vì Java cho bạn cách thức lập trình hướng đối tượng và nó chạy trên Android, nhưng chỉ có C mới có sức mạnh mà một lập trình viên games cần tới.
Một số kỹ năng cứng bạn cần biết trong Android là:
    Activities, view, layout....
    Services.
    Content providers.
    Broadcast receivers.
Một số kỹ năng khác là: Hiểu biết cơ bản về Linux và shell scripting:
    Bạn cần biết một số câu lệnh cơ bản như: liệt kê các file, cài đặt một thành phần, một ứng dụng...

Yêu cầu về phần mềm:
    Hệ điều hành Ubuntu.
    Eclipse.
    Android SDK.
    Java JDK.
(Còn tiếp)

11 Lời Khuyên Của Bill Gates


1) Cuộc sống vốn không công bằng, chúng ta phải tìm cách thích ứng với nó.
2) Thế giới này không quan tâm đến cái tự ái trong bạn, mà chỉ mong bạn lập được thành tích trước khi bản thân bạn tự cảm thấy hài lòng (Nói tóm lại mặt dày là ngon).
3) Sau khi tốt nghiệp, bạn không thể có ngay mức lương 40.000$/năm, không thể trở thành chủ tịch một công ty, sở hữu một chiếc xe hơi có lắp điện thoại cho đến khi bạn tự mình kiếm được những thứ ấy. Hãy bắt tay vào làm đi, thay vì ngồi đó mà mơ mộng.
4) Nếu cho rằng thầy giáo của bạn nghiêm khắc, hãy đợi đến khi đi làm bạn sẽ biết. Thầy giáo cũng đến lúc hết nhiệm kì công tác, nhưng ông chủ thì mãi mãi là ông chủ của bạn.
5) Món "bánh nướng kẹp thịt" rẻ tiền không hề làm giảm đi giá trị của bạn. Ông bà ta có định nghĩa khác về "bánh nướng kẹp thịt", họ gọi là thời cơ. Gặp những người khi sa cơ lỡ vận, đừng trở nên bất đắc chí mà hãy sử dụng nghịch cảnh như là một động lực để vươn lên.
6) Nếu bạn lâm vào cảnh khó khăn, đừng mải dằn vặt về những lỗi lầm đã qua mà hãy rút ra bài học từ đó. Hãy cố gắng đứng vững và đi lên từ những thất bại của mình
7) Trước khi sinh ra bạn, cha mẹ bạn không như hiện tại đâu. Họ trở nên như thế là vì bao năm nay họ phải kiếm tiền nuôi bạn, giặt quần áo cho bạn. Nếu muốn diệt "ký sinh trùng" đeo bám suốt đời ba mẹ bạn, trước tiên hãy diệt trừ con rệp trong tủ áo của bạn.
8) Nhà trường có thể không còn phân biệt học sinh giỏi hay kém nhưng cuộc sống thì có đấy. Một số trường đã từ bỏ điểm kém, chỉ cần bạn muốn tìm lời giải chính xác, nhà trường sẽ cho bạn vô số cơ hội. Nhưng cuộc sống thì không phải vậy. Bạn phải không ngừng nỗ lực vươn lên để tự khẳng định mình.
9) Cuộc sống không phân chia học kỳ, bạn sẽ không có kỳ nghỉ hè, cũng ít có ông chủ nào giúp bạn phát hiện chính mình. Bạn phải tự mình phát hiện những điều ấy.
10) Truyền hình không phản ánh cuộc sống chân thực. Trong cuộc sống hiện thực, người ta phải rời khỏi tiệm cà phê để đi làm việc chứ không phải ngồi đấy xem TV.
11) Bạn hãy cư xử tế nhị với kẻ là bạn cho là nhạt nhẽo, vô vị, vì có thể một ngày nào đó bạn có thể phải làm việc với một người vô vị như thế

Tải cuốn sách này