Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Sunday, 15 July 2012

Perbandingan Performa SharedPreferences dan SQLite

Yup bersama saya lagi bermain-main dengan Android! Kali ini saya ingin membahas tentang SharedPreferences dan SQLite sebagai pilihan untuk menyimpan data pada Android.

Pembuat aplikasi Android pasti suatu saat akan menemui suatu permasalahan tentang penyimpanan data. Bagaimana cara menyimpan data? Bagaimana data itu disimpan? Dimana harus disimpan? Jawaban dari pertanyaan itu dapat dijawab dengan membaca tutorial Android disini. Menurut saya tutorial itu sudah cukup memberikan pengantar yang cukup untuk memulai merambah dunia simpan-menyimpan di Android (sehubungan dengan simpan-menyimpan, saya jadi ingat dengan "simpanan" saya. Tapi itu untuk lain cerita).

Apabila si pembuat aplikasi ini sudah mulai advance, ia akan mulai bingung antara "apakah saya harus menggunakan SharedPreferences atau kah saya harus menggunakan SQLite?" dengan asumsi kita tidak memperdulikan penyimpanan di storage (internal maupun eksternal). Karena sudah dipastikan penyimpanan di storage itu lambat (akan disinggung sedikit nanti mengapa penyimpanan di storage itu lambat). Seperti kita ketahui, SharedPreferences hanya dapat menyimpan data dalam bentuk key-value pair sehingga mudah dimodifikasi. Sedangkan SQLite hanya dapat diubah dengan membuat query SQL.
Ini ngomongin apa sih? Saya maunya pake Hadoop saja >:)
Di sebuah post di StackOverflow sudah dibahas tipe penyimpanan mana yang harus anda gunakan pada suatu kondisi tertentu. Inti dari post itu adalah: Gunakan SharedPreferences bila data-nya kecil dan bermacam-macam. Gunakan SQLite bila data-nya besar, terstruktur dan sedikit macam-nya. Contoh data yang ingin anda simpan di SharedPreferences adalah: "opsi apakah user ingin mendapatkan notifikasi", "opsi apakah user hanya ingin mengunduh data dari internet ketika terhubung dengan wireless", "berapa kali notifikasi harus dilakukan tiap hari" dan berbagai macam data yang kecil yang lain. Contoh data yang ingin anda simpan di SQLite adalah: "daftar manga yang di bookmark oleh user", "contact list", "kumpulan teman-teman yang baru saja saya miss-call" dan berbagai macam data yang terstruktur yang lain.

Namun anda yang suka bermain Javascript atau fanatik dengan JSON akan berargumen: "Bitch please! Saya bisa mengubah data saya, misalnya Manga, menjadi sebuah JSON lalu saya simpan ke SharedPreferences. Manga saya nanti punya sebuah key, misal URL darimana Manga tersebut diambil, untuk mendapatkan Manga yang saya mau dari SharedPreferences dengan mudah. Solusi ini mudah dibuat dan sangat mudah dikembangkan! Semua-nya jadi rata ke SharedPreferences! Screw SQL!"
JSON can save the world! JSON can even kill and fight Freddy!
Baik saya sangat setuju bahwa dengan SharedPreferences pasti perlu digunakan (untuk setting, konstanta-konstanta kecil, menyimpan versi terakhir yang digunakan, menyimpan waktu update dari internet terakhir kali, dan lain sebagainya). Sedangkan seperti yang telah disebutkan diatas, SQLite tidak sepenuhnya dibutuhkan dengan alasan struktur yang kita butuhkan dapat dikompres dengan mudah kedalam JSON lalu kita simpan sebagai String biasa. Tapi bagaimana kalau kita tinjau dari segi performa?

Pertama SharedPreference akan makin lambat seiring dengan banyak-nya data yang disimpan dalam SharedPreference tersebut. Lambat disini hanya terjadi saat aplikasi mulai dijalankan. Misal anda menyimpan segala sesuatu di SharedPreference SPMangaMobile. Maka suatu saat apabila terlalu banyak Manga yang anda simpan di SPMangaMobile ini, untuk bisa me-load opsi-opsi trivial seperti "kapan terakhir kali aplikasi ini di-update" akan memakan waktu sangat lama. Samsung Galaxy Mini saya merasakan 5 detik startup hanya untuk memulai aplikasi karena saya menggunakan cara ini.

"Kalau begitu, pisahkan saja SharedPreference yang bersifat struktural, seperti Manga, ke SPManga. Sedangkan untuk yang lain, masukkan ke SPMangaMobile." In a way, solusi ini cukup benar sampai anda punya 1 MegaByte data. Me-load 300kB data saja membutuhkan waktu hingga hampir 1200 ms! Dan ini dilakukan di Android yang tidak sembarangan: Galaxy Tab 8.9" dengan processor Tegra 2 dual core 1 GHz! Bayangkan berapa lama waktu yang dibutuhkan di Galaxy Mini?


Tiap kali pengguna memulai aplikasi, pengguna harus menunggu selama 516 ms untuk  mempersiapkan SharedPreferences. Another 720 ms untuk mendapatkan data yang dibutuhkan.
Selebihnya program menghabiskan rata-rata 720ms untuk mengolah data hingga dapat digunakan.
Wow. Pengguna Android sekarang pasti akan mulai membanting HP-nya apabila HP-nya berhenti me-respon dalam waktu lebih dari 3 detik (ya, pengguna Android se-tidak-sabaran itu). "Nexus gw gak mungkin selambat itu! Yang lambat itu cuma BB!" Baik, coba tunjukkan waktu yang dibutuhkan bila menggunakan SQLite! Segera komandan!
3685 ms adalah waktu yang dibutuhkan untuk mem-backup database ke eksternal storage (karena itu saya bilang menyimpan di storage itu lambat). Hal ini hanya dilakukan sekali saja  setiap kali anda mengubah definisi database (misal menambah kolom pada suatu tabel). Jika anda pintar, database hanya perlu dibuat sekali saja :)
Loh tapi ternyata performa-nya tidak berkembang sama sekali! Penipuan ini namanya!
Ya, bisa anda lihat bahwa performa menggunakan SQLite tidak berbeda jauh dari menggunakan SharedPreference. Lalu apa gunanya donk kita menggunakan SQLite? Tunggu dulu! Mari kita simak lagi.

Berbeda dengan apabila kita menggunakan JSON terstruktur pada SharedPreferences, pada SQLite kita bisa mengambil data-data yang kita perlukan saja (dengan menspesifikasikan query yang tepat). Misalnya untuk kasus ini, saya hanya ingin mengambil judul, url, dan rating dari suatu Manga. Saya tidak peduli dengan deskripsi, genre, maupun data-data yang lain. Tentu hal ini bisa meningkatkan performa! Tapi sebesar apa? Mari kita lihat!
Karena sudah di-backup sebelumnya, kali ini kita hanya melihat waktu yang dihabiskan oleh aplikasi untuk menyiapkan data yang siap ditampilkan.
Yes! Akhirnya peningkatan performa! Kali ini aplikasi dapat me-load data dalam waktu hanya 231ms saja! Tiga kali lebih cepat dibandingkan sebelumnya!

Dari percobaan ini saya kembali ke kesimpulan yang sebelumnya telah dibuat oleh suatu post di  StackOverflow : Gunakan SharedPreferences bila data-nya kecil dan bermacam-macam. Gunakan SQLite bila data-nya besar, terstruktur dan sedikit macam-nya.


Sekian dari saya. Seperti biasa, komentar dan tanggapan sangat diterima :)

Saturday, 30 June 2012

Random Thought June

Juni datang! Waktu musim panas dan liburan telah tiba!

  1. [All Manga Mobile] Akhirnya nge-release All Manga Mobile! Pada dua hari pertama agak kacau. Sistem biling nya Google nge-bug sesaat, akhirnya server nya over-quota. Karena server over-quota, jadi ga bisa diakses dan aplikasinya jadi ga guna. Akhirnya pada hari itu banyak yang ngasih rating jelek :(
App Engine yang quota-nya sedikit dan mahal :(
  1. [All Manga Mobile] Lagi memikirkan bagaimana men-support banyak manga source sekaligus. Saat ini All Manga Mobile sudah men-support 6 manga source dimana secara UI masih enak dilihat. Tapi bayangkan kalau sudah ada 20 manga source!
  2. Meninggalkan banyak proyek di Indo (and a big one on top of that). Semoga yang ditinggalkan kuat untuk mengerjakannya. Amin.
  3. Cukup senang sampai saat ini masih berhasil men-juggling 4 kerjaan sekaligus (Facebook, Bangunindo, All Manga Mobile dan satu proyek pribadi).
  4. Sedih sekali melihat teman-teman pada lulus. Mereka akan hidup di jalan nya masing-masing sekarang dan mulai menjalani kehidupan yang sepi dan membosankan. Good luck my friends. We will need it.
  5. [Android] ActionBar tidak berfungsi untuk ActivityGroup (yang sudah deprecated) pada Ice Cream Sandwich. Padahal di Honeycomb masih berfungsi dengan baik.
  6. [Android] Sesedikit mungkinlah menggunakan AsyncTask. Dan jangan lupa untuk meng-cancel AsyncTask yang tidak digunakan (misalnya setelah Activity berakhir). Karena bila tidak, ketika Activity berakhir dan AsyncTask masih berjalan, AsyncTask ini akan berjalan terus menerus (istilahnya zombie thread). Hal ini mengakibatkan program tidak bisa menjalankan Thread lain (tidak hanya AsyncTask lain) dan bahkan menutup aplikasi tidak membantu ini. So use AsyncTask moderately and with a grain of salt.
  7. [Android] Perlu ditekankan, AsyncTask itu selalu di set sebagai Thread dengan LOW_PRIORITY. Jadi apapun yang dikerjakan di AsyncTask sangatlah lambat. Bila perlu prioritas dalam melakukan suatu pekerjaan, buatlah Thread sendiri.
  8. Random pic:
I don't know what I was thinking that time

Sunday, 4 March 2012

Manga Mobile Coding Series : Membajak mangareader.net part 2

Asyik bisa nulis lagi. Sebelumnya kita telah membahas logika dibalik teknik pembajakan Mangareader. Kali ini saya akan membahas secara teknis bagaimana implementasinya di Android.

Kembali saya ingatkan: untuk bisa mengerti dengan sepenuhnya apa yang dibahas di artikel ini, anda perlu mengenal beberapa hal yang tidak dibahas di artikel ini:
  1. DOM (Document Object Model)
  2. Manga :)
Android dapat mengunduh isi halaman HTML dengan mudah. Tetapi hasil unduhan ini adalah sebuah string panjang. Lalu bagaimana kita bisa mengeksekusi logika "temukan anak pertama dari tag ul"? Ada beberapa cara seperti berikut:
  1. Lakukan manipulasi string. Kita membuat asumsi bahwa ul ini pasti punya anak. Sehingga kita dapat mencari karakter "<" pertama yang mengawali sebuah tag HTML dan menandai karakter tersebut menjadi karakter pertama dari anak yang kita cari. Lalu kita tinggal mencari ">" yang sesuai dan menandai karakter tersebut menjadi karakter terakhir dari anak yang kita cari. Dari sini kita dapat menyalin karakter-karakter diantara karakter yang telah kita tandai tersebut dan jadilah mereka sebagai string anak pertama yang kita cari. Ada permasalahan dari sini? Banyak: sangat rentan bug dan sangat tidak fleksibel.
  2. Gunakan XML Parser.
  3. Gunakan 3rd party library untuk membuat DOM.
Saya akan membahas cara terakhir (yang kebetulan saya gunakan). Dan perlu diketahui, sebenarnya membuat DOM tidak perlu menggunakan 3rd party library karena sepertinya Android sudah memilikinya. Namun saya terlanjur menggunakan 3rd party library dan malas untuk menggantinya (maaf).

Perkenalkan Jsoup (halo Jsoup, saya Gogo), library pembuat DOM yang saya gunakan. Fitur-fitur yang bisa dilakukan oleh library ini silakan dilihat di website nya. Yang penting, si Jsoup ini menyediakan beberapa hal yang berguna untuk saya:
  1. kemampuan untuk membuat DOM
  2. kemampuan untuk memanipulasi dan mencari elemen dalam DOM
  3. kemampuan untuk mencari elemen spesifik berdasarkan tag, class, id, name, dan href atribut lainnya.
  4. kemampuan untuk mencari bapak dan anak dari suatu elemen.
Sebenarnya fungsi 2 hingga 4 adalah fitur yang wajib ada untuk sebuah library yang mengaku bisa membuat DOM, jadi fungsi utama library ini sebenarnya hanya 1.

Jadi tanpa banyak cakap, inilah kodenya:


public ArrayList downloadMangaList() {
    ArrayList mangaList = new ArrayList();
    String url = Utilities.MANGAREADER_URL + "/alphabetical";

    boolean gagal = true;
    int attempt = 0;

    while (gagal && attempt < Utilities.DOWNLOAD_ATTEMPT) {
        try {
            Log.i("Manga", "trying to connect to " + url);
            Document soup = Jsoup.connect(url).get();
            gagal = false;

            // lewat sini means berhasil konek
            Elements links = soup.select("ul[class=series_alpha]");

            for (Element link : links){
                Elements mangaLinks = link.getElementsByTag("a");
                for (Element manga : mangaLinks){
                    mangaList.add(new Manga(manga.text(), Utilities.MANGAREADER_URL + manga.attr("href")));
                }
            }

        } catch (IOException ex){
            Log.i("Manga", "" + ex.getMessage());
            ++attempt;
        }
    }

    return mangaList;
}



Kode diatas adalah contoh bagaimana saya mendapatkan kumpulan manga yang ada di Manga Reader. Yang pertama saya lakukan adalah mengunduh page www.mangareader.net/alphabetical dimana pada page itu, semua manga yang ada di Manga Reader dituliskan. Saya mengunduhnya menggunakan Jsoup.connect(url).get()agar HTML yang diunduh ini sudah terformat dengan baik oleh JSoup. Hal ini saya lakukan berkali-kali in case pengguna menggunakan koneksi yang abal-abal sehingga page HTML-nya jadi tidak terunduh.

Langkah kedua adalah pattern matching. Ya, dengan sedikit pengamatan kita dapat melihat bahwa page HTML yang dibuat oleh Manga Reader ini cukup ber-pola. Tiap manga selalu dibungkus dalam alphabet yang mengawalinya (Naruto berarti N). Dan tiap alphabet itu dibungkus dalam satu elemen HTML yaitu 
<ul> , dan selalu memiliki class=series_alpha. Gambar berikut mungkin bisa lebih menjelaskan.

      HTML dari www.mangareader.net/alphabetical
Dari sini kita tinggal mengambil semua elemen yang memiliki class=series_alpha, lalu mencari semua URL yang ada didalamnya. Cara ini tidak foolproof, tapi cukup untuk mendapatkan apa yang kita butuhkan.

That's it! Semudah itu kita "membajak" Manga Reader. Tinggal melakukan hal yang sama pada page-page yang lain dan kita dapat membuat software untuk pengunduh manga dengan mudah. Cara ini juga dapat diaplikasikan pada manga source lain seperti GoodManga, MangaHere, AnimeA dan lain-lain. Namun beberapa manga source seperti MangaStream dan Batoto sering mengganti pola menampilkan halamannya dan membuat mereka susah di-scrapping.

What do you think? Ada yang mau membantu saya membuat manga downloader dengan membuat pola-pola seperti ini?

Tuesday, 28 February 2012

Random Thought February



Random thought
  1. Mineral water cannot quench my thirst anymore. Only sweet tea can. I wonder if vampires feel the same way about blood.
  2. Mungkin jurus terbaik yang diperlukan programmer dan desainer adalah Kage Bunshin no Jutsu. So many ideas and no time/manpower.
  3. "For engineers, our deadline is the deadline time. For market, the deadline is the opportunity." - Nico
  4. Saya curiga bahwa orang-orang jenius adalah orang dari masa depan yang menggunakan mesin waktu untuk kembali dan memperbaiki masa lalunya yang suram.
  5. [Android] Misalnya mau bikin Button programmatically (ga pake XML). Kalau misalnya kita punya drawable dalam bentuk resource (contoh R.drawable.image), lebih baik langsung button.setBackgroundResource(R.drawable.image). Jangan ubah R.drawable.image jadi obyek Drawable dulu (drawable = context.getResources().getDrawable(R.drawable.image); button.setBackgroundDrawable(drawable)). Hal ini buruk kalau R.drawable.image mengandung animasi (contoh kalau bikin selector pake XML). Nanti animasinya ga jalan.
  6. [Android] Just realized that beside Log.v(verbose), Log.d(debug), Log.i(info), Log.w(warning) and Log.e(error), there's Log.wtf(What a Terrible Failure)
  7. [Game Dev] Tips bikin gerakan Seeking Missile. Pertama cari vektor antara misilnya dengan targetnya. Terus cari vektor satuannya. Habis itu kalikan vektor satuan dengan kecepatan maksimal misil.
  8. [Manga Mobile] Just finished multiple manga source for Manga Mobile. And there're so many bug reports. Emailed on top of that. So sorry everyone >.<
  9. [Manga Mobile] Comment by user: Jan 28, 2012 11:02:34 AM on version 1.952 "fucked up"
  10. Don't go too far ahead, or be ready to be alone there.
  11. When I hate something, I just feel like making the game of it. Setelah kuliah Agama Islam, I feel like making a game about God (like Black and White?). Setelah naik angkot yang ngetem 1 jam, I feel like making a game about Angkot (like Dinner Dash?). And I had countless idea for game about programming.
  12. Keraguan adalah puncak dari keyakinan - Imam Al-Ghazali.
  13. Rioux SVN for free and private SVN :)
  14. Hello World in GWT and App Engine! So excited! Tutorial  in Indonesian coming up :). Ini tutorial Inggris-nya yang lumayan bagus (dibandingkan yang Google punya)
Damn GWT, how am I supposed to learn from ur f****d up sample?


Sunday, 17 April 2011

Manga Mobile Coding Series : Membuat Main Menu

Yup, untuk sebagian besar aplikasi, pasti memerlukan Main Menu untuk melakukan navigasi mula-mula. Bisa dibilang Main Menu adalah bagian terpenting dari sebuah aplikasi. Karena itu, pada kesempatan kali ini kita akan membahas :
  1. Bagaimana memulai activity baru dari activity sebelumnya.
  2. Bagaimana membuat layout Main Menu
  3. Bagaimana membuat event listener. Pada kasus ini event listener pada button.
Melanjutkan dari pembuatan Splash Screen di sini, pertama kita buat dahulu layout Main Menu yang kita kehendaki. Berikut kode XML layout sederhana Main Menu yang saya beri nama main_menu.xml :

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dip"
    android:gravity="center"
    android:id="@+id/main_layout" 
    android:background="@drawable/main_menu">
    <LinearLayout 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/main_linear"    
        android:orientation="vertical"
        android:gravity="center_horizontal"
    >
        <Button 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:id="@+id/read_button"
            android:text="Read"    
            android:background="@drawable/bg_button"
            android:layout_margin="10dip"
            android:textColor="#ffffff"
        />
        <Button 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:id="@+id/favorite_button"
            android:text="My Favorites"    
            android:background="@drawable/bg_button"
            android:layout_margin="10dip"
            android:textColor="#ffffff"
        />
        <Button 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:id="@+id/setting_button"
            android:text="Setting"    
            android:background="@drawable/bg_button"
            android:layout_margin="10dip"
            android:textColor="#ffffff"
        />
    </LinearLayout>
        
</RelativeLayout>

Ada banyak cara membuat .xml baru, salah satunya adalah meng-copy .xml yang sudah ada, lalu me-rename dan mengganti kode didalamnya.

Disini ada beberapa atribut baru yang cukup baru. Pertama adalah android:gravity="center_horizontal". Atribut ini bertujuan untuk menengahkan tombol-tombol yang ada didalam LinearLayout. Sedangkan android:orientation="vertical" berguna untuk menjaga agar tombol yang satu dan yang lain disusun secara vertikal. Setelah itu, didalam LinearLayout kita buat beberapa tombol. Pada kode diatas saya mendefinisikan isi text (android:text), warna text (android:textColor), ID dari tiap button (android:id), background button (android:background) dan jarak antar satu button dengan button lain (android:layout_margin).

Sebagai referensi, saya menggunakan 2 gambar ini untuk background Main Menu dan background button.

main_menu.png

bg_button.png


Lalu kita buat sebuah Activity baru bernama MainMenuAct. Cara membuat Activity sama dengan saat kita membuat SplashScreenAct hanya saja ada beberapa perubahan kode :

package gogo.mobile.mm;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainMenuAct extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_menu);
        
        mRead = (Button)findViewById(R.id.read_button);
        mRead.setOnClickListener(new View.OnClickListener() {
            
            public void onClick(View v) {
                //startActivity(new Intent(MainMenuAct.this, SelectMangaAct.class));
            }
        });
        
    }
    
    private Button mRead;
}

Perhatikan bahwa pada kode diatas kita mendapatkan definisi button Read dan Favorite dari main_menu.xml yang telah kita definisikan sebelumnya (dan ini menjadi penyebab mengapa saya lebih suka memainkan layout lewat kode daripada menggunakan IDE). Pada kode diatas, kita juga telah membuat sebuah event listener untuk button Read yang nanti akan kita isi untuk melakukan navigasi.

Lalu kita harus membenarkan SplashScreenAct kita. Cukup ubah kode ini :

SplashScreenAct.this.finish();

menjadi :

SplashScreenAct.this.finish();
startActivity(new Intent(SplashScreenAct.this.getApplicationContext(), MainMenuAct.class));

Sampai tahap ini, kita telah berhasil membuat MainMenuAct yang akan dijalankan setelah Splash Screen selesai. Namun kode ini masih belum bisa berjalan dengan sempurna. Kita harus memberitahu Android bahwa MainMenuAct adalah bagian dari activity kita. Tambahkan pada AndroidManifest.xml

<activity android:name=".MainMenuAct" />

dimanapun dalam tag <application> setara dengan tag <activity> milik SplashScreenAct.

Jalankan aplikasi. Bila lancar, maka akan muncul seperti berikut :

Splash Screen

Dan 5 detik kemudian, muncullah MainMenuAct.

Sekarang mari kita buat Main Menu ini bisa melakukan navigasi. Buatlah sebuah Activity kosong bernama SelectMangaAct.

package gogo.mobile.mm;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class SelectMangaAct extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

Lalu uncomment kode


//startActivity(new Intent(MainMenuAct.this, SelectMangaAct.class)


pada MainMenuAct. Tambahkan juga


<activity android:name=".SelectMangaAct" />


pada AndroidManifest.xml. Kira-kira isi tag <application> pada AndroidManifest.xml saat ini adalah :

<application android:icon="@drawable/icon" android:theme="@android:style/Theme.NoTitleBar">
    <activity android:name=".SplashScreenAct" android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".MainMenuAct"/>
<activity android:name=".SelectMangaAct" />
</application>

Jalankan aplikasi, dan bila sukses bin lancar muncullah seperti berikut :
Splash Screen

5 detik kemudian muncul MainMenuAct. Pencet button Read

Yap, kita berhasil melakukan navigasi ke Activity lain.

Sekian kombo pembahasan Splash Screen dan Main Menu. Nantikan pembahasan selanjutnya yang (semoga) lebih seru. Kritik dan saran tentunya masih saya terima.

Saturday, 16 April 2011

Manga Mobile Coding Series : Membuat Splash Screen

Yup, akhirnya punya cukup waktu luang untuk menuliskan artikel ini. Pada artikel ini saya akan memaparkan beberapa hal tentang bagaimana cara membuat Splash Screen.

Bagi anda mau memulai membuat project dan melakukan setting emulator, anda bisa melakukannya disini.
Pada project kali ini, saya menggunakan konfigurasi berikut

  1. Project Name = MangaMobile
  2. Build Target Android 2.1 yang memiliki API version 7
  3. Application Name = MangaMobile
  4. Package Name = gogo.mobile.mm
  5. Tidak membuat Activity (checkbox Create Activity tidak dicentang)
  6. Min SDK Version = 7
Kurang lebih akan muncul tampilan seperti berikut di Project Explorer anda (bila anda tidak bisa menemukan Project Explorer, klik Window > Show View > Project Explorer) :


Pada tahap ini, anda telah berhasil membuat sebuah project yang tidak bisa dijalankan (karena tidak ada Activity yang bisa dijalankan). Sekarang buka src, dan pada package gogo.mobile.mm, klik kanan > New > Class. Akan muncul tampilan seperti berikut

Yang paling penting untuk dilakukan adalah mengisi nama kelas di Name dan mengosongkan Superclass. Lalu langsung saja klik Finish. Kelas yang kita buat ini tidak akan langsung menjadi sebuah Splash Screen.

Sekarang kita memerlukan gambar untuk Splash Screen. Saya sarankan resolusi gambar tersebut adalah 320x480 seperti ini :
Simpan gambar ini di folder res > drawable-mdpi > splash.png (nama file gambarnya terserah, tapi pastikan hanya terdiri dari huruf kecil dan garis bawah). Kembali ke Eclipse, klik kanan pada project anda (pada kasus ini : MangaMobile) lalu pilih Refresh. Bila gambar anda berhasil dimasukkan, file tersebut akan muncul di folder res > drawable-mdpi pada project dan muncul juga di gen > gogo.mobile.mm > R.java > R > drawable > splash sebagai sebuah pointer ke resource gambar splash.png.

Setelah memiliki gambar untuk splash dan Android Project telah mendeteksi gambar kita, kita perlu membuat layout. Lihat pada Project Explorer, folder res > layout > main.xml. Akan muncul tampilan seperti layar HP. Saya tidak terlalu suka berkutat ditampilan ini karena tidak terlalu fleksibel. Pada bagian bawah, klik main.xml. Akan muncul tampilan XML. Ganti isi XML menjadi seperti berikut

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dip"
    android:gravity="center"
    android:id="@+id/main_layout" 
    android:background="@drawable/splash">    
</RelativeLayout>

Pada baris pertama <?xml version="1.0" encoding="utf-8"?> digunakan untuk mendefinisikan tipe XML yang digunakan. Pada Splash Screen kita menggunakan layout RelativeLayout (layout akan dibahas di post lain). Layout ini akan memenuhi seluruh layar (karena android:layout_width  dan android:layout_height bernilai fill_parent yang artinya ia akan memenuhi seluruh parent-nya dimana parent-nya adalah layar HP itu sendiri). Yang paling penting disini adalah properti ID dan Background. Disini ID nya saya set dengan main_layout sementara Background nya saya isi dengan splash (sesuai dengan nama file yang kita masukkan di res > drawable-mdpi).

Terakhir, kita tinggal memasukkan kode yang diperlukan di SplashScreenAct.java. Tambahkan kode sedemikian menjadi seperti berikut :

package gogo.mobile.mm;

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

public class SplashScreenAct extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Thread timer = new Thread() {
            @Override
            public void run() {
                long startTime = System.currentTimeMillis();
                // lakukan sesuatu pada saat memulai game
                
                long now = System.currentTimeMillis();
                if (now - startTime < 5000){
                    try {
                        sleep(5000 - (now - startTime));
                    } catch (InterruptedException iEx){
                        
                    }
                }
                
                SplashScreenAct.this.finish();
                //kita belum akan membuat activity baru disini setelah splash screen selesai
                //startActivity(new Intent(SplashScreenAct.this.getApplicationContext(), MainMenuActivity.class));
            }
        };
        
        timer.start();
    }
}

Hal yang perlu diperhatikan adalah, kelas ini sekarang meng extend Activity. Saya sarankan untuk melakukan segala sesuatu dengan Ctrl + Space. Sebagai contoh tulis Activi lalu pencet Ctrl + Space, lalu pilih Activity pada intellisense. Hal ini akan membuat Eclipse secara otomatis mengimport segala hal yang diperlukan untuk membuat Activity.

Pada Activity, kita harus selalu mengimplementasikan onCreate(Bundle savedInstanceState)(cara paling mudah adalah dengan menulis onCreate, lalu pencet Ctrl + Space, lalu pilih onCreate yang sesuai pada intellisense). Jangan lupa untuk menambahkan super.onCreate(savedInstanceState) karena tanpa sebaris kode tersebut Activity tidak akan bisa di-start. Yap, pada tahap ini kita sudah membuat sebuah Activity yang bisa dijalankan. Tapi bila kita mencoba menjalankan project ini, tentu akan terdapat error.

Lalu untuk membuat Activity ini menggunakan layout yang telah kita buat, kita harus menambahkan setContentView(R.layout.main) dimana main disini adalah nama layout yang kita buat (main.xml).

Berikutnya kita membuat Thread yang akan melakukan sesuatu selama 5000 millisecond. Dan setelah 5000 millisecond, Thread ini akan menutup SplashScreenAct dan akan membuat Activity baru. Namun pada tutorial ini pembuatan Activity baru tidak akan dibahas. Yap, Splash Screen sudah selesai dibuat.

Apakah program ini akan berjalan? Belum! Kita perlu memberitahukan Android bahwa aplikasi kita memiliki Activity bernama SplashScreenAct dan aplikasi kita dimulai dari sana. Pada Project Explorer klik pada AndroidManifest.xml. Dan lagi-lagi pencet AndroidManifest.xml pada bagian bawah jendela. Pada tag <application>, edit kodenya sehingga menjadi seperti berikut

<application android:icon="@drawable/icon" android:theme="@android:style/Theme.NoTitleBar">
    <activity android:name=".SplashScreenAct" android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        </activity>    
</application>

Hal ini membuat Android mengetahui bahwa aplikasi kita dimulai dari SplashScreenAct yang bisa distart dari launcher (icon yang kita klik untuk memulai aplikasi).

Yap sekarang Splash Screen kita telah selesai. Silakan dicoba :

memulai emulator

ketika kita buka menu utama Android, kita dapat melihat aplikasi kita

Yes, that's our Splash Screen

Bila anda mengikuti tutorial ini hingga seri kedepan, maka tampilan ini akan muncul

Sunday, 3 April 2011

Manga Mobile Coding Series : Membuat Widget

Maap kalau seri nya mungkin agak ngacak. Tapi kebetulan saya lagi penasaran mau membuat Widget untuk Manga Mobile atas saran dari teman saya (tag : dieend).

Jadi anggap saja kita sudah mempunya Android Project di Eclipse dan sudah men-develop-nya sedemikian rupa sehingga sudah bisa digunakan (detail pembuatan project di Eclipse dan development-nya akan saya tulis dikemudian hari). Lalu kita ingin membuat sebuah widget, misalnya untuk kasus aplikasi Manga Mobile saya, saya ingin memberikan update manga terbaru. Pada contoh ini, saya hanya akan membuat sebuah tombol di widget saya, yang bila dipencet, akan langsung membuka aplikasi Manga Mobile.

Untuk membuat widget, kita memerluka 3 hal :

  1. AppWidgetProviderInfo : yaitu widget itu sendiri. Disini kita akan mendefinisikan layout widget, frekuensi melakukan update dan provider yang akan mengupdate widget.
  2. AppWidgetProvider : yaitu class yang meng-update isi widget.
  3. Layout dari widget itu sendiri.

Pertama, mari kita definisikan AppWidgetProviderInfo dalam bentuk xml. Saya menyimpan file ini di /res/xml/widget.xml

<?xml version="1.0" encoding="utf-8"?>

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="294dp"
    android:minHeight="72dp"
    android:updatePeriodMillis="1000"
    android:initialLayout="@layout/widget_layout"
    >
</appwidget-provider>

Penjelasan singkat : kita membuat widget menggunakan XML. Widget ini ukurannya paling kecil 294 x 72 dp (Density-Independent-Pixel). Widget ini akan mengupdate dirinya sendiri (dengan memanggil suatu method di provider yang akan kita definisikan nanti) setiap 1000 milliseconds. Tampilan widget ini juga akan dikonfigurasi oleh @layout/widget_layout (yang juga akan kita definisikan setelah ini).

Lalu kita membutuhkan WidgetProvider, yaitu class yang akan meng-update isi dari widget ini. Saya menamai kode dibawah ini = MangaMobileWidget.java

package gogo.mobile.mm;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;

public class MangaMobileWidget extends AppWidgetProvider {
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        final int widgetSize = appWidgetIds.length;
        
        for (int i = 0; i < widgetSize; ++i){
            Intent intent = new Intent(context, SplashScreenActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

            // Get remote layout
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
            views.setOnClickPendingIntent(R.id.widget_button, pendingIntent);

            // update widget
            appWidgetManager.updateAppWidget(appWidgetIds[i], views);
        }
    }
}

Method pada kode diatas akan dipanggil setiap beberapa millisecond (pada kasus ini 1000 milliseconds). Disini saya membuat Intent yang akan memanggil SplashScreenActivity yang sudah saya buat di aplikasi saya. Intent ini dikirim apabila suatu button dipencet. Button yang dimaksud sudah saya definisikan di @layout/widget_layout.

Lalu sekarang saatnya kita mendefinisikan layout dari widget itu sendiri. Layout ini saya simpan di /res/layout/widget_layout.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="200dp"
    android:layout_height="160dp"
    android:padding="10dip"
    android:gravity="center"
    android:id="@+id/widget_layout" 
    android:background="@drawable/bg_button">
     <Button 
         android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/widget_button"
        android:text="Widget Button Test"
     />
 </LinearLayout>

Saya tidak akan membahas dengan detail tentang pembuatan layout disini. Disini intinya saya membuat sebuah  LinearLayout yang memiliki sebuah button didalamnya. Button ini memiliki ID (R.id.widget_button), sehingga bisa diakses oleh WidgetProvider yang telah saya buat.

Lalu, belum selesai sampai sini, kita harus mendefinisikan widget kita ke AndroidManifest.xml. Kode berikut saya letakkan antara tag  dan 

<receiver android:name=".MangaMobileWidget" >
    <intent-filter>
    <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget" />
</receiver>


Disini kita mendefinisikan widget, dan mengatakan bahwa widget tersebut dikontrol oleh MangaMobileWidget sebagai WidgetProvider. Resource disini adalah AppWidgetInfo yang telah kita definisikan diatas.

Lalu jalankan emulator :


Home-nya emulator


Klik Menu dulu baru klik Add.



Klik Widgets



Ups, saya melihat icon saya


Yup itu dia widget nya. Coba di klik ah


Yep, Manga Mobile is ready.

Sekian dari saya, semoga bermanfaat. Masukan sangat diterima untuk seri koding selanjutnya

Saturday, 19 March 2011

Cara melakukan pass by reference integer di Java

Sekadar sharing saja. Mungkin anda sudah tahu bahwa di Java kita tidak bisa melakukan pass by reference terhadap tipe data integer. Bahkan dengan menggunakan class Integer sekalipun, kita memiliki keterbatasan karena class Integer itu immutable (tidak bisa diubah-ubah nilainya).

Ini merupakan cara bodoh yang cukup efektif untuk melakukan pass by reference integer di Java. Saya akan menggunakan contoh bagaimana cara menukar dua buah bilangan menggunakan fungsi swap.


public static void main(String args[]){
  int[] bil = new int[2];
  bil[0] = 10;
  bil[1] = -7;

  System.out.println("Before = " + bil[0] + " " + bil[1]);

  doSwap(bil);

  System.out.println("After = " + bil[0] + " " + bil[1]);
}

dan method doSwap kita adalah :


public static void doSwap(int[] bil){
  int temp = bil[0];
  bil[0] = bil[1];
  bil[1] = temp;
}

Jadi yang kita lakukan adalah membuat sebuah array of integer (yang tentunya bisa di pass by reference) lalu mem-pass kan array tersebut ke method doSwap.

Semoga beguna.

Wednesday, 16 March 2011

Memulai Android Development Di Windows / Di Linux / Di Mac OS - part 2

Untuk part-2 ini saya mau sharing tentang :
  1. Bagaimana cara mendownload Android SDK dan melink SDK tersebut dengan Eclipse yang sudah sudah kita konfigurasi sebelumnya.
  2. Bagaimana membuat emulator menggunakan AVD (Android Virtual Device).
  3. Bagaimana mengoneksikan HP Android anda sehingga bisa digunakan untuk debugging.
Untuk mendownload Android SDK, langsung saja pergi ke download site nya :
Untuk Windows :
Download .exe yang recommended saja. Setelah di download, eksekusi .exe nya. Ketika program meminta posisi hasil instalasi nantinya, letakkan di tempat yang mudah diingat (karena tempat ini akan kita gunakan lagi). Setelah program selesai menginstall, jalankan SDK Manager ketika diminta.

Untuk Mac OS dan Linux :
Download file kompresi yang disediakan. Ekstrak di tempat yang mudah diingat (karena tempat ini akan digunakan lagi). Masuk ke direktori Android, lalu jalankan SDK Manager.

Pada proses ini, kita harus terkoneksi dengan internet. Saat SDK Manager dibuka, ia akan mengupdate database nya. Setelah update selesai, pilih Cancel. Klik pada Available Packages dan klik pada panah kecil di sebelah Android Repository.




Setelah itu, klik pada API yang diperlukan (dari 1.6 sampai 3.0, saya sarankan untuk mendownload 2.1 karena 2.1 adalah firmware yang paling umum dimiliki HP-HP Android saat ini). Uncheck dokumentasi karena bila di check dapat menyebabkan download tidak berjalan alias stuck. Klik Install SelectedAccept setelah itu anda tinggal menunggu download selesai.

Yup selamat, kita berhasil menginstall Android SDK dengan sukses. Sekarang saatnya menghubungkannya dengan Eclipse. Jalankan Eclipse dan pilih Window > Preferences. Klik bagian Android.
Di bagian SDK Location, klik Browse dan arahkan ke tempat anda mengekstrak Android SDK. Pada komputer saya, saya mengarahkannya ke D:\Program Files\Android\android-sdk seperti gambar diatas. Klik Apply dan lihat apakah Eclipse berhasil mendeteksi SDK anda. Bila Eclipse berhasil mendeteksi Android SDK anda, maka anda dapat melihat versi-versi API yang telah anda Install. Klik OK dan anda dapat mulai mengembangkan aplikasi Android dari Eclipse anda. Lagi-lagi, applause untuk anda, cendol untuk saya.

Namun sebelum mulai membuat sesuatu, alangkah baiknya bila anda menyiapkan emulator untuk debugging. Langkah-langkahnya cukup mudah. Buka Eclipse anda, dan klik pada Window > Android SDK and AVD Manager. Klik pada Virtual devices, lalu klik New...


Masukkan nama virtual device dan target API (lagi-lagi saya sarankan untuk membuat 2.1). Biarkan opsi yang lain kecuali anda ingin melakukan konfigurasi khusus terhadap emulator seperti mengganti resolusi layar, membuat dan mengatur ukuran SD Card atau menambahkan sensor gerak. Akhiri dengan klik Create AVD.


Ya! Anda telah berhasil membuat virtual device yang dapat digunakan sebagai emulator Android di komputer anda. Mungkin beberapa diantara anda bertanya-tanya :
Mengapa nama virtual device nya Eclair? Saya mau namanya Lontong
Oh, itu tentu terserah anda. Anda bisa menamai virtual device anda sesuai keinginan anda. Bahkan anda bisa juga mengajaknya ngobrol, jalan-jalan ke mall, nonton di bioskop atau memeluknya sambil tidur.
Bagaimana bila saya ingin menggunakan HP Android yang sudah saya miliki sebagai emulator?
Tentu saja bisa, langkah yang perlu dilakukan adalah menginstall driver USB Android anda dan mengaktifkan fitur USB Debugging pada HP anda.
Bagaimana mengaktifkan fitur USB Debugging?
Nyalakan HP anda, buka Settings > Applications > Developments. Pastikan opsi USB debugging tercentang.

Untuk memastikan apakah SDK, ADT dan virtual device atau HP anda siap digunakan untuk membuat aplikasi Android, mari kita coba untuk membuat sebuah project sederhana. Buka Eclipse dan klik File > New > Android Project. 


Pastikan untuk memilih Build Target dan memasukkan Project Name, Application Name, Package name dan Min SDK Version. Sesuaikan Min SDK Version dengan Build Target (pada kasus diatas Build Target menggunakan API 7, maka Min SDK Version nya pun juga 7). Package name boleh apapun (saya sarankan nama-perusahaan-anda.nama-divisi-anda.nama-aplikasi-anda). Klik Finish bila sudah selesai.

Setelah selesai membuat project, klik Run As... (tanda panah warna ijo) atau Ctrl + F11. Run sebagai Android Application. Bila semua berjalan lancar, maka anda akan melihat tampilan seperti berikut.



Selamat, anda telah berhasil membuat sebuah aplikasi Android. Sampai sini saja seri Memulai Android Development. Kritik dan saran sangat diterima untuk perbaikan kedepannya. Terima kasih.

Saturday, 12 March 2011

Memulai Android Development Di Windows / Di Linux / Di Mac OS - part 1

Tentunya kita sudah tahu bahwa Android makin lama makin mendunia. Sebagai manusia yang tidak ingin ketinggalan jaman, beberapa diantara kita pasti ingin mulai ikut andil dalam dunia perkembangan Android. Saya akan menuliskan sedikit demi sedikit bagaimana cara ikut andil di dunia tersebut. Perlu ditekankan bahwa saya belum pro dalam dunia pengembangan aplikasi Android, sehingga kritik dan saran sangat diterima.

Pertama, download lah JDK dulu. Akan muncul gambar seperti ini :

Klik "Download JDK" dan lanjutkan dengan memilih OS yang sesuai dengan OS anda. Setelah selesai download, langsung klik saja "OK", "Next", "I agree" atau apapun yang membuat langkah-langkah instalasi berlanjut. Selamat, anda telah berhasil meng-install JDK (applause untuk anda, cendol untuk saya).

Setelah instalasi JDK selesai, download lah Eclipse Galileo. Akan muncul gambar seperti berikut :


Kenapa Elipse?
Karena Eclipse IDE adalah satu-satunya (saat tulisan ini dibuat) IDE yang diberi plugin official oleh Android.
Kenapa Galileo?
Karena Eclipse Galileo adalah versi Eclipse yang paling baru yang masih beres (lagi-lagi saat tulisan ini dibuat). Versi Eclipse yang lebih baru (Helios) akan lagging (nge-hang kalau saya jalankan di netbook saya) ketika kita menjalankan intellisense (autocomplete-nya IDE) yang cukup berat.
Kenapa ada ijo-ijo di gambar?
Karena saya mau cendol! Bukan, bukan itu....
Karena saya menyarankan anda mendownload Eclipse untuk Java Developers (karena aplikasi di Android ditulis dalam bahasa pemrograman Java, well... most of it).

Lalu pilih OS yang sesuai dengan OS anda. Setelah selesai download, ekstraklah Eclipse ke folder yang anda inginkan. Hasil ekstraksi ini adalah Eclipse Galileo itu sendiri. Ya, tidak perlu instalasi. Kalau tidak percaya coba saja double-click eclipse pada folder utama eclipse. Starting-up Eclipse akan muncul ke layar monitor anda bila anda melakukan instalasi JDK dengan benar dan Eclipse terunduh dengan sempurna.

OK, sekarang jalankan Eclipse bila anda belum menjalankannya. Pilih menu Help > Install New Software... Akan muncul jendela seperti berikut
Masukkan https://dl-ssl.google.com/android/eclipse/ ke textbox Work With, lalu klik ke manapun. Akan muncul tulisan Pending yang akan berubah menjadi tulisan Developer Tools pada gambar diatas. Ingat, proses ini harus dilakukan sambil terkoneksi dengan internet. Pilih Next, OK dan apapun yang membuat langkah-langkah instalasi berlanjut. Tunggu beberapa saat hingga instalasi ADT selesai.

Sebagai catatan, Eclipse yang telah diinstal dengan ADT dapat di copy kemanapun anda suka (yeaah, Eclipse adalah IDE yang sangat portable). Sehingga bisa saja anda melakukan proses download Eclipse dan ADT ini di warnet (asalkan warnet itu punya JRE / JDK untuk menjalankan Eclipse). Lalu Eclipse yang sudah dimasukin ADT ini anda bawa ke rumah untuk anda gunakan selanjutnya.

Lalu apakah proses instalasi sudah selesai sampai sini? Tentu saja belum, nantikan seri Memulai Android Development - part 2.