14 Май 2010

Русификация Nook’а.

Я начал заниматься русификацией Nook’а.
Пруфлинк:
2010-05-14-041839
2010-05-14-041859

28 Май 2009

Небольшое обновление старкрафта

В данный раз внешних изменений почти нет.

  • Пока что выключена карта, поскольку съедает много памяти
  • Отрисовка GRP-изображений была переделана - теперь есть два рендера: первый рисует, на лету преобразуя индексы цветов в массив цветов, а затем уже рисует, второй же сразу все кеширует в битмапы. Скорость отрисовки во втором случае больше в разы, но в первом случае памяти в два раза меньше потребляется
  • Сделан полный рефакторинг кода. Добавлено наследование. Отказ от него из-за маленькой скорости - было глупостью, ибо она усложняла сильно код и не позволяла писать сопровождаемый код.
  • Все полностью перенесено на SDK 1.5
  • Добавлено управление на экране

Что дальше? необходимо по-прежнему улучшать код графической части - необходима разработка хорошего алгоритма для кеширования графики, поскольку производительность андроида оставляет желать лучшего.

1

2

3

4

18 Март 2009

DroidGear roms

You could find this on CoolRom.com.

Now DroidGear supprots only Sega Game Gear and Sega Master System roms.

17 Март 2009

Забавный SoundPool…

В общем сегодня я решил немного заняться звуком в своем старкрафте и начал писать код с использованием SoundPool.
Что же мне удалось определить:

  • На форуме anddev.org прочитал, что нормально работает только с Wav 16-бит и с OGG… Так и вышло.
  • Неудобно при использовании большого числа звуков ( у меня их 1144 шутки), поскольку он подгружает все звуки в память… что делать теперь не знаю…
В общем ситуация оочень странная - нету официального API, как следствие нету нормальной документации… очень странный ход со стороны гугла, ведь игры очень прибыльная вещь…

13 Март 2009

JNI для андроида


Необходимые материалы

Для лучшего понимания рекомендую прочитать мой предыдущий пост про Hello World на Си для анроода.

Если вы используете не линукс, то вам нужна папка include из линуксового JDK, поскольку из-за незначительных различий виндовая не подходит(

Описание нативного метода в java-классе и получение хидера для Си

Нативный код в Java описывается с помощью ключевого слова native. В своем коде я заведу такую функцию:

public static native int hello(int val1, String val2);

Теперь необходимо собрать проект(я не нашел в эклипсе кнопки “Build”, поэтому я просто запускал проект), а затем перейти в папку /bin и выполнить там комманду:

javah %ClassName%

где %ClassName% - полное название класса, в котором мы написали этот метод. В моем случае - это hotheart.JNITest.JNITestActivity в результате мы получили заголовочный файл

 

К сожалению, мы не сможем воспользоваться вторым параметром и в нативном коде мы не сможем ничего о нем узнать. Поскольку в заголовочных файлах не описаны методы для работы с объектами. В частности String перейдет в jstring, который на самом деле jobject, который является просто пустой структурой. Но, возможно, это дело может исправить использование заголовочных файлов из самого андроида.

Изучение заголовочного файла и реализация метода

Теперь взглянем на сгенерированный заголовочный файл. Вот что получилось в моем случае:
(файл myjni.h)

/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class hotheart_JNITest_JNITestActivity */

#ifndef _Included_hotheart_JNITest_JNITestActivity
#define _Included_hotheart_JNITest_JNITestActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     hotheart_JNITest_JNITestActivity
 * Method:    hello
 * Signature: (ILjava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_hotheart_JNITest_JNITestActivity_hello
 (JNIEnv *, jclass, jint, jstring);

#ifdef __cplusplus
}
#endif
#endif

Рассмотрим комментарий перед описанием метода. Мы должны запомнить что здесь написано - мы будем это использовать в последствии.
В поле Class мы получили название метода, в Metod - название метода, Signature - Описание параметров и выходных значений метода.

Теперь реализуем этот метод. Я в своей реализации буду просто возвращать первый аргумент:
(файл myjni.c)

#include
#include "myjni.h"

#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_hotheart_JNITest_JNITestActivity_hello
 (JNIEnv *a, jclass b, jint c, jstring d)
{
 return c;
}

#ifdef __cplusplus
}
#endif

Но! этого не достаточно для функционирования JNI. Необходимо при инициализации JNI регистрировать методы в джава-машине.

Делается это так:

static JNINativeMethod sMethods[] = {
 /* name, signature, funcPtr */

 {"hello", "(ILjava/lang/String;)I", (void*)Java_hotheart_JNITest_JNITestActivity_hello},
};

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
 JNIEnv* env = NULL;
 jint result = -1;

 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
 return result;
 }

 jniRegisterNativeMethods(env, "hotheart/JNITest/JNITestActivity", sMethods, 1);
 return JNI_VERSION_1_4;
}

Этот код приписываем в конец файла myjni.c
Массив sMethods представляет из себя список всех регистрируемых функций, а в методе JNI_OnLoad мы регистрируем сами функции.

 

Компиляция и загрузка библиотеки

Что бы теперь скомпилировать наш проект нужно немного видоизменить код для компиляции в случае с HelloWorld’ом - при компиляции нужно добавить параметры -i с путями к заголовкам (не забываем про пробелы), которые вы скачали, когда начали читать статью, а при линковке добавить ключ -shared.

В результате в моем случае получаем:

arm-none-linux-gnueabi-gcc -ID:\Android\AndroidJNI\jdk_include\ -ID:\Android\AndroidJNI\jdk_include\linux -fpic -c myjni.c -o D:\CompileTemp\myjni.o
arm-none-linux-gnueabi-ld -TD:\GCC\arm-none-linux-gnueabi\lib\ldscripts\armelf_linux_eabi.xsc -shared -o D:\CompileTemp\myjni.so D:\CompileTemp\myjni.o

Теперь с нативным кодом покончено и мы можем загрузить библиотеку в андроид.
Я положил в папку /data/data/hotheart.JNITest/, поскольку в эту папку мое приложение имеет гарантированный полный доступ. Теперь остался последний штрих - добавление кода для загрузки библиотеки в память:

System.load("/data/data/hotheart.JNITest/myjni.so");

В итоге мой java-код стал таким:

package hotheart.JNITest;

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

public class JNITestActivity extends Activity {
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main);
 TextView tv =  (TextView)findViewById(R.layout.hello);
 System.load("/data/data/hotheart.JNITest/myjni.so");
 tv.setText("Result =" + hello(10, "test"));
 }

 public static native int hello(int val1, String val2);
}

Все! теперь мы можем запустить наше приложение:

Hello World на Си для андроида

Что требуется для компиляции

  • Компилятор GCC для ARM. Далее буду описывать работу под виндами
  • Модифицированный скрипт, необходимый для адаптации компилятора для компилирования под андроид - armelf_linux_eabi.xsc

Отмазка

Я плохо разбираюсь в GCC и многого не понимаю еще и этот мануал - выдержка из слежующих блогов:

Компиляция HelloWorld’а со статичной линковкой

После установки компилятора мы можем сразу скомпилировать свой HelloWorld с таким кодом файла main.c:
#include <stdio.h>;
int main()
{
printf("Hello Kitty!");
    return 0;
}
Выполнив такой код в папке с этим файлом:
arm-none-linux-gnueabi-gcc -static main.c -o main
В результате мы получили бинарник теперь его необходимо загрузить на G1 или эмулятор, прописать права на выполнение и запустить:
adb push  main /data/myjni
adb shell
#cd /data
#chmod 777 myjni
#./myjni
В результате получим надпись “Hello Kitty!” на экране) Если не верите, то вот пруф - скриншот с экрана G1, но у меня myjni немного не тот бинарник. Результат подобных действий у меня в native:
Но есть огромный минус - статическая линковка. и таким образом мы подходим к следующему пункту.

Динамическая компиляция

В андроиде таблица импортов/экспортов немного не такая как сделана в этом компиляторе и поэтому необходимо вмешиваться в работу компилятора.
Первое, что нам нужно сделать - это скачать файл armelf_linux_eabi.xsc и заменить им такой же файл в дистрибе компилятора - %CompilerPath%\arm-none-linux-gnueabi\lib\ldscripts\
Затем нам нужно сделать так, что бы в пути к компилятору не было пробелов. Это необходимо, поскольку как-то некорректно работает этот GCC с парамертрами, которые содержат пробелы(
Я решил дело просто - сделал символьную ссылку на папку компилятора и назвал её D:\GCC
Теперь непосредственно компилируем и линкуем:
arm-none-linux-gnueabi-gcc -fpic -c myjni.c -o D:\CompileTemp\myjni.o
arm-none-linux-gnueabi-ld -TD:\GCC\arm-none-linux-gnueabi\lib\ldscripts\armelf_linux_eabi.xsc -shared -o D:\CompileTemp\myjni.so D:\CompileTemp\myjni.o 
Тут еще проблема была - выходной файл из компилятора без указания абсолютного пути писался непонятно куда… пришлось вручную писать во временную папку(
Теперь все с динамическим кодом и в результате мы получили полноценный HelloWorld

28 Январь 2009

Парсинг XML в Google Android

Введение

Более подробно можете почитать о Document Object Model(DOM) в википедии. Лучше в английской.

В крадце опишу.

Есть некий документ, который представим в виде дерева. Пусть будет HTML-код:

<paragraph align="left">
The <it>Italicized</it> portion.
</paragraph>

В результате он будет преобразован к вот такому дереву:

Как видно(это верно и для Android Java) текст внутри тега помещается в отдельный узел(лист) дерева.
Это нужно не забывать, когда будем работать с этим деревом!

» Читать полностью …

Android и NetBeans

1) Скачайте и установите NetBeans

Тут ведется на основе NetBeans 6.5 All (система Windows 7 7000 build)
NetBeans

2) Скачайте и установите Android SDK

Тут ведется на основе Android SDK 1.0 R2
Android SDK

3) Установка плагина

а) Идем в Tools->Plugins


» Читать полностью …