Sejarah Angka Nol (Part 2)

Artikel ini adalah lanjutan dari Sejarah Angka Nol (Part 1).
“Sebelum bapak menjawab pertanyaan mu, Tom, bapak akan lanjutkan dulu sejarah tentang Brahmagupta dan angka nolnya! Ok?” tanya Pak Zero pada siswa-siswinya, khususnya Tom yang sudah bertanya.
“Yaaaaaaaaa……….. bapak, enggak asyik, ah!!!!” spontan Jerry berteriak, karena sejak tadi sudah tak sabar menahan rasa ingin tahunya. Kontan, seisi kelas melirik padanya. Jerry hanya bisa cengar-cengir disaksikan kawan-kawannya.
“Konon, walau angka nol dilambangkan berupa titik, Brahmagupta sudah secara sistematis mengenal sifat-sifat operasi bilangan dengan angka nol, khususnya operasi penjumlahan, pengurangan, dan perkalian.” kata Pak Zero melanjutkan kisah sejarah angka nolnya.
Pak Zero sengaja diam sebentar, menunggu reaksi murid-muridnya, apakah mereka menyimak dengan baik atau hanya terbengong-bengong saja. Pak Zero berharap ada siswa atau siswinya yang menanyakan tentang operasi pembagian dengan nol. Tapi, harapannya tidak terwujud. Para siswanya tetap diam, menantikan kelanjutan kisah sang angka nol.
Pak Zero tidak kehilangan akal. Untuk menggali sifat kritis para siswanya, dia memancing dengan pertanyaan.
“Ok, di antara kalian, coba siapa yang paling mengerti tentang angka nol dan sifat operasi-operasi padanya?”


Sejenak seisi kelas diam.
Tiba-tiba, Jerry kembali membuat ulah. “Pak, setahu saya, sejak SD dulu, si Udin tuh yang paling akrab dengan nol!”
“Maksud mu bagaimana Jerr?” tanya Pak Zero dengan tampak sabar, karena sebetulnya menahan rasa kesal.
“Maksudnya, setahu saya, si Udin sering sekali dapat nol dalam pelajaran matematika, Pak!!!
“Ha ha ha ha ha….” tanpa dikomando, hampir seisi kelas, kecuali Udin, tertawa mendengarnya. Untungnya, Udin tidak mudah sakit hati sebab sudah tahu sifat Jerry yang memang suka meledek dan bercanda sejak SD dulu. Jadi, Udin senyam-senyum saja, santai, sambil menunggu kesempatan membalasnya.:)
“Sudah-sudah! Jangan suka ngeledek! Yuk, kita lanjutkan ceritanya!” Pak Zero menengahi keadaan.
***
“Pak, apakah maksud dari sifat operasi penjumlahan, pengurangan, dan perkalian dengan nol itu?” tanya Rahma, siswi yang duduk paling depan, tepat di depan meja Pak Zero. Pak Zero yang semula akan melanjutkan kisah angka nol, mengurungkan sementara.
“Menurut mu bagaimana?” Pak Zero balik bertanya. Rahma tersenyum, berpikir, lalu mencoba mengungkapkan pendapatnya.
“Yang saya tahu sih, kalau bilangan ditambah atau dikurangi dengan nol, ya hasilnya bilangan itu sendiri!” jawab Rahma dengan penuh percaya diri.
“Bisa memberi contohnya?” lagi-lagi Pak Zero bertanya pada muridnya itu.
“Pak, saya bisa memberi contoh!” jawab Udin tanpa diminta. Sementara Rahma yang semula akan memberi contoh, tidak jadi mengungkapkan pendapatnya.
‘Misalnya begini, Pak. 4 + 0 = 4, 4 – 0 = 4, dan ini berlaku bagi bilangan lainnya, termasuk nol itu sendiri!” lanjut Udin memberi penjelasan.
Pak Zero: “Ok, bagus Din! Selanjutnya, bagaimana tentang perkalian dengan nol?”
“Itu sih, gampang, Pak. Kalau kita mempunyai sebuah bilangan, lalu dikali dengan nol, maka hasilnya, pasti nol! Contohnya, 4 x 0 = 0, 10 x 0 = 0, dan seterusnya!” jawab Dirman, mendahului Jerry yang sedari tadi ingin berpendapat.
Pak Zero: “Bagus Dirman!”
Sementara itu, sejak tadi Tom berpikir tentang pembagian angka nol. Dia mengalami kesulitan yang tak terpikirkan sebelumnya.
“Pak, kalau pembagian dengan nol bagaimana? Dari tadi, saya memikirkan, misalnya 4 : 0, lalu 0 : 4, tapi saya kesulitan menemukan jawabannya, Pak! kata Tom berpendapat, tepat sebelum Pak Zero menanyakan hal itu kepada siswa-siswi lainnya.
Pak Zero: “Ayo, siapa yang bisa jawab pertanyaan Tom?”
Kali ini, kelas terdiam sediam-diamnya. Tampak seluruh siswa berpikir, mencoba mencari tahu jawab pertanyaan Tom. Bahkan, Jerry yang biasanya berulah, kini memainkan pensilnya di atas kertas, mengutak-atik pembagian dengan nol.
Sementara itu, Pak Zero sabar menunggu reaksi siswa-siswinya sambil menandai daftar hadir dengan tanda ceklist, yang sedari tadi lupa dilakukan saat mengecek kehadiran siswa-siswinya.
Sepuluh menit waktu berlalu, belum juga ada reaksi dari Tom dan teman-temannya.
Pak Zero: “Ok, sudah 10 menit bapak menunggu. Tapi, belum ada jawaban dari kalian! Karena itu, pertanyaan Tom bapak jadikan PR buat kalian!”
“Yaaaaaaaaa, bapak!” serempak, kelas bergema, menandakan kekecewaan.
Pak Zero sengaja melakukan hal itu, agar siswa-siswinya sendiri yang menemukan jawaban atas rasa keingintahuan mereka. Sebuah proses pembelajaran yang konstruktif. Ini sesuai teori pembelajaran yang pernah dipelajari Pak Zero, di Jurusan Pendidikan Matematika, Universitas Pendidikan Indonesia (dahulu bernama IKIP Bandung), yakni teori konstruktivisme dalam pembelajaran.
Pak Zero: “Ok, ok, kalian jangan kecewa! Kalau kalian merasa sulit, itu biasa, tidak masalah. Bahkan Brahmagupta sendiri, sang matematikawan India itu, sungguh mengalami kesulitan tentang operasi pembagian dengan nol. Hingga akhir hayatnya, dia tak mampu menemukan jawab masalah ini! Karena itu, bila kalian dapat memecahkan masalah pembagian dengan nol, berarti kalian hebat!”
Demikian kata Pak Zero, menyemangati siswa-siswinya, agar tidak kecewa.
“Kalau begitu, apakah sampai saat ini masalah pembagian dengan nol belum terpecahkan, Pak?” kembali Tom bertanya.
Pak Zero: “Tentu sudah, Tom! Karena itu, pertanyaanmu bapak jadikan PR. Tugas kamu dan kawan-kawan adalah mencari tahu jawabnya. Entah di perpustakaan, atau di mana saja!”
“Pak, yang berhasil memecahkan masalah pembagian dengan nol, siapa Pak? Apakah orang biasa atau matematikawan juga?” tanya Rahma, yang juga penasaran ingin tahu.
Pak Zero: “Tentang masalah pembagian dengan nol, baru terpecahkan sekitar 10 abad setelah masa Brahmagupta. Adalah Newton dan Leibniz yang membahas masalah itu dan berhasil memecahkannya.” Demikian kata Pak Zero, sambil menuliskan kedua tokoh yang baru saja disebutnya di papan tulis: NEWTON & LEIBNIZ, abad 17.
“Pak, NEWTON itu siapa?” tanya Udin, yang terdengar lucu sebab menyebut Newton sesuai apa yang tertulis, bukan seperti cara baca yang dicontohkan Pak Zero (yaitu “nyu ton”). :D
“Udah dong Din, jangan bertanya-tanya hal lain dulu. Sejak tadi kan, kita ingin tahu sifat pembagian dengan nol. Lalu, sebelumnya kita juga belum tahu, siapa matematikawan yang pertama kali menggunakan lambang nol seperti yang kita gunakan sekarang!” sewot Jerry, yang rupanya makin penasaran karena makin banyak hal yang belum terceritakan oleh Pak Zero.
Pak Zero: “Ok, ok, akan bapak ceritakan lanjutan kisahnya. Ayo, dengarkan bapak baik-baik!”
Baru saja kelas mulai tenang dan para siswa siap-siap mendengar lanjutan kisah angka nol dari Pak Zero, tiba-tiba lonceng berbunyi dua kali, menandakan waktu pelajaran matematika hari itu telah habis.
‘Baiklah anak-anak sekalian, berhubung waktu habis, dongeng angka nolnya bapak lanjutkan pertemuan berikutnya ya….”
***
Catatan: Mudah-mudahan artikel ini bermanfaat bagi kita semua. Amiin. Selamat menantikan kisah selanjutnya! :D Dan, selamat menunaikan berbagai ibadah di bulan Ramadhan yang mulia ini.

Games Coming to Android Market in Korea



[This post is by Eric Chu, Android Developer Ecosystem. —Dirk Dougherty]



In the 24 months since the first Android device became available locally, Korea has quickly become one of the top countries in Android device activations. In parallel, we’ve also seen tremendous growth in app downloads from Android Market. Korea is now the second-largest consumer of apps worldwide. Today we are adding to this momentum by bringing games to Android Market in Korea.



Starting right away, Android users in Korea can explore the many thousands of popular game titles available in Android Market and download them onto their devices. For paid games, purchasing is fast and convenient through direct carrier billing, which lets users in Korea easily charge their purchases to their monthly mobile operator bills.



If you are a game developer, now is the time to localize your game resources, app descriptions, and marketing assets to take advantage of this new opportunity. When you are ready, please visit the Android Market developer console to target your app for distribution in South Korea and set prices in Korean Won (KRW). If you don’t want to distribute to Korea right away, you can also exclude it.



With the huge popularity of games on Android and the convenience of direct carrier billing in Korea, we expect to see a jump in game purchases and downloads in the weeks ahead. For game developers worldwide, it’s “game on” in Korea!

Making Android Games that Play Nice

[This post is by Ian Ni-Lewis, a Developer Advocate who devotes most of his time to making Android games more awesome. — Tim Bray]



Making a game on Android is easy. Making a great game for a mobile, multitasking, often multi-core, multi-purpose system like Android is trickier. Even the best developers frequently make mistakes in the way they interact with the Android system and with other applications
 — mistakes that don’t affect the quality of gameplay, but which affect the quality of the user’s experience in other ways.

A truly great Android game knows how to play nice: how to fit seamlessly into the system of apps, services, and UI features that run on Android devices. In this multi-part series of posts, Android Developer Relations engineers who specialize in games explain what it takes to make your game play nice.

I: The Audio Lifecycle (or, why is there music coming from my pants?)

One of the most awesome things about Android is that it can do so much stuff in the background. But when apps aren’t careful about their background behaviors, it can get annoying. Take my own personal pet peeve: game audio that doesn’t know when to quit.

The problem

I’m on the bus to work, passing the time with a great Android game. I’m completely entranced by whatever combination of birds, ropes, and ninjas is popular this week. Suddenly I panic: I’ve almost missed my stop! I leap up, quickly locking my phone as I shove it into a pocket.

I arrive breathless at my first meeting of the day. The boss, perhaps sensing my vulnerability, asks me a tough question. Not tough enough to stump me, though — I’ve got the answer to that right here on my Android phone! I whip out my phone and press the unlock button... and the room dissolves in laughter as a certain well-known game ditty blares out from the device.

The initial embarrassment is bad enough, but what’s this? I can’t even mute the thing! The phone is showing the lock screen and the volume buttons are inactive. My stress level is climbing and it takes me three tries to successfully type in my unlock code. Finally I get the thing unlocked, jam my finger on the home button and breathe a sigh of relief as the music stops. But the damage is done — my boss is glowering and for the rest of the week my co-workers make video game noises whenever they pass my desk.

What went wrong?

It’s a common mistake: the developer of the game assumed that if the game received an onResume() message, it was safe to resume audio. The problem is that onResume() doesn’t necessarily mean your app is visible — only that it’s active. In the case of a locked phone, onResume() is sent as soon as the screen turns on, even though the phone’s display is on the lock screen and the volume buttons aren’t enabled.

Fixing this is trickier than it sounds. Some games wait for onWindowFocusChanged() instead of onResume(), which works pretty well on Gingerbread. But on Honeycomb and higher, onWindowFocusChanged() is sent when certain foreground windows — like, ironically, the volume control display window — take focus. The result is that when the user changes the volume, all of the sound is muted. Not the developer’s original intent!

Waiting for onResume() and onFocusChanged() seems like a possible fix, and it works pretty well in a large number of cases. But even this approach has its Achilles’ heel. If the device falls asleep on its own, or if the user locks the phone and then immediately unlocks it, your app may not receive any focus changed messages at all.

What to do about it

Here’s the easy two-step way to avoid user embarrassment:

  1. Pause the game (and all sound effects) whenever you receive an onPause() message. When gameplay is interrupted — whether because the phone is locked, or the user received a call, or for some other reason — the game should be paused.


  2. After the game is paused, require user input to continue. The biggest mistake most game developers make is to automatically restart gameplay and audio as soon as the user returns to the game. This isn’t just a question of solving the “music over lock screen” issue. Users like to come back to a paused game. It’s no fun to switch back to a game, only to realize you’re about to die because gameplay has resumed before you expected it.


Some game designers don’t like the idea of pausing the background music when the game is paused. If you absolutely must resume music as soon as your game regains focus, then you should do the following:

  1. Pause playback when you receive onPause().


  2. When you receive onResume():

    1. If you have previously received an onFocusChanged(false) message, wait for an onFocusChanged(true) message to arrive before resuming playback.


    2. If you have not previously received an onFocusChanged(false) message, then resume audio immediately.



  3. Test thoroughly!


Fixing audio embarrassments is almost always a quick and easy process. Take the time to do it right, and your users will thank you.

Sejarah Angka Nol (Part 1)

Waktu itu adalah hari Senin. Hari pertama Tom dan kawan-kawan masuk sekolah. Hari pertama belajar di SMP Pembangunan, satu-satunya SMP di pinggiran suatu kecamatan di ujung barat pulau Jawa.
Menurut jadwal yang sudah ditetapkan, dan sudah dicatat oleh Tom saat masa orientasi siswa (MOS), pelajaran pertama hari Senin adalah matematika. Satu pelajaran yang disukainya sejak SD dulu.
***
Lonceng sekolah berbunyi empat kali. Menandakan jam masuk sekolah dan pelajaran pertama akan segera dimulai. Para siswa segera masuk kelas, duduk dengan rapi, menunggu guru matematika mereka.
Saat menunggu, Tom membayangkan guru matematika yang akan masuk adalah seorang yang guru yang sudah tua dan ditakuti siswa-siswinya. Tom pernah mendengar dari kakak-kakak kelasnya bahwa guru-guru matematika di SMP Pembangunan terkenal sangat galak, ditakuti, dan tidak disukai siswa-siswinya.
Tiba-tiba lamunan Tom terpecah karena mendengar ucapan salam dari sang guru matematika. Ternyata, yang dibayangkan Tom salah. Guru matematikanya ternyata masih muda, dan sepertinya adalah guru baru di SMP Pembangunan. Setelah berdo’a dan lain sebagainya, tiba giliran sang guru mengenalkan diri sebelum memulai pelajaran.
“Anak-anak sekalian, sebelum kita mulai pelajaran, bapak akan perkenalkan diri bapak dulu, lalu bapak pun ingin mengenal satu-persatu kalian! Nama bapak adalah Al Zero. Orang-orang biasa memanggil Zero, tapi ada juga yang memanggil Al. Kalau ada yang mau kalian tanyakan, bapak persilakan!”
Demikian Pak Zero memperkenalkan diri.
Sambil menunggu pertanyaan, Pak Zero berusaha mengenali siswa-siswinya, dengan memanggil satu persatu nama mereka dari daftar hadir yang beliau bawa.
Kelas masih diam, siswa-siswi Pak Zero rupanya masih enggan bertanya. Baru saja Pak Zero akan bicara, tiba-tiba muncul pertanyaan.
“Pak, kenapa nama bapak Al Zero? Apa artinya?”


Ya, itulah pertanyaan singkat yang diajukan Udin, kawan sebangku Tom. Pak Zero tidak langsung menjawab, sedikit tersenyum dan sepertinya berpikir untuk menjawabnya.
“Ok, terima kasih, pertanyaan yang bagus, Din! Mm…kalian, selain Udin, mau tahu juga?
Serentak, semua siswa Pak Zero mengatakan, “Mauuuuuuuu…”. Mulai saat itu, terjadilah proses pembelajaran matematika melalui tanya jawab seperti berikut ini.
Pak Zero: “Mmm…Zero adalah satu kata yang berasal dari bahasa Inggris. Mm… kalian sudah pernah belajar bahasa Inggris, kan?”
Tak ada siswa yang mengaku, kelas kembali terdiam. Semua siswa diam. Terdiamnya mereka karena memang tak ada satu pun di antara mereka yang pernah belajar bahasa Inggris. Sungguh berbeda nasib mereka dengan siswa-siswa yang ada di kota yang sejak SD sudah pernah belajar bahasa Inggris, baik melalui kursus atau dari sekolah.
Pak Zero baru sadar bahwa yang dihadapinya adalah siswa-siswi SMP, yang sewaktu SD belum pernah mempelajari bahasa asing, termasuk bahasa Inggris.
Pak Zero: “Ok, jadi, zero itu artinya nol! Ya, nol!
“Lalu, kenapa bapak dinamai Zero alias Nol?” tanya Dirman dengan rasa ingin tahu yang tinggi!
Pak Zero: “Orang tua bapak seorang pedagang yang cukup gemar membaca, khususnya tentang sejarah matematika. Saat ada dalam kandungan, orang tua bapak ingin sekali menamai anaknya dengan nama yang berasal dari istilah matematika.”
Para siswa menyimak dengan baik apa yang diceritakan Pak Zero.
Pak Zero: “Dari sekian banyak istilah matematika yang diketahui orang tua bapak, hampir semuanya tidak cocok untuk dijadikan nama. Mereka terus berpikir dan mencari, hingga, entah dengan sebab apa, orang tua bapak menamai bapak dengan Al Zero. Katanya sih, terinspirasi dari nama penyanyi terkenal, tapi nama itu erat kaitannya pula dengan sejarah matematika, khususnya tentang angka nol!”
“Kalau begitu, bapak tahu dong sejarah angka nol?” tanya Tom, tiba-tiba berani mengungkapkan rasa ingin tahunya.
“Iya, Pak, ceritakan tentang angka nol pada kami!” pinta Jerry, seorang siswa yang duduk di pojok kanan belakang kelas.
Pak Zero: “Ok, akan bapak ceritakan! Sekalian ini anggap saja sebagai pembuka topik yang akan kita pelajari nanti. Cerita ini cocok dengan pelajaran yang akan kita pelajari, yaitu tentang bilangan bulat!
“Horee… pelajaran matematikanya lewat dongeng!” kata Udin dalam hati. Udin pantas bergembira, sebab sejak SD dia memang kurang menyukai matematika, seringnya takut belajar satu pelajaran ini.
Pak Zero pun memulai ceritanya, tentang nol. Ya, tentang satu kata yang nyantel di namanya. Beginilah ceritanya.
“Konon, dibandingkan angka-angka yang lain, nol merupakan angka yang relative baru ditemukan! Menurut para ahli sejarah matematika, gagasan tentang nol pertama kali ditemukan di catatan Brahmagupta pada abad 7 Masehi.”
Udin: “Pak, Brahmagupta itu siapa?”
Pak Zero: “Brahmagupta adalah salah seorang matematikawan yang berasal dari negeri India. Ya negerinya tuan Takur, yang terkenal dalam film-film India itu!”
“Ha ha ha…” hampir semua siswa tertawa mendengar cerita Pak Zero, karena menyebut satu tokoh terkenal (bengis) dalam film India.
“Konon, di catatan Brahmagupta, angka nol dilambangkan tidak seperti sekarang. Lambangnya waktu itu baru berupa titik. Bukan bundaran seperti sekarang!”
“Berarti, bukan Brahmagupta dong yang menemukan angka nol? Lalu siapa, Pak, yang pertama kali menggunakan lambang 0 seperti sekarang?” tanya Tom dengan sangat kritis. Pertanyaan yang tak terduga, mengagetkan Pak Zero.
Apa tanggapan Pak Zero terhadap pertanyaan, Tom? Tunggu artikel selanjutnya. Sabar ya… :)

Rahasia Rumus Cepat Matematika

Dulu, ketika saya masih baru menjadi mahasiswa baru tingkat pertama, saya berkenalan dengan salah seorang mahasiswa baru lainnya yang di kemudian hari menjadi teman baik saya. Ketika awal perkenalan, kami pun ngobrol kesana-kemari. Tanya sana-tanya sini. Jawab sana, jawab sini. Hingga ia pun akhirnya bercerita bahwaa nilai tes Matematika Dasar-nya, yaitu salah satu mata pelajaran yang diujikan di UMPTN*, adalah 100 alias benar semua.
Mendengar ceritanya tersebut, saya pun terkagum-kagum dibuatnya. Dalam pikiran saya, saya berkesimpulan “Wah ia pasti orang yang sangat pandai”. Rasa kagum saya mendorong rasa ingin tahu saya tentang pengetahuannya dalam matematika. Akhirnya, dalam masa awal perkenalan itu, saya ajak ia ngobrol tentang matematika yang sudah pernah kami pelajari ketika semasa SD sampai SMA dulu.
Dari obrolan tersebut, saya jadi tahu, ternyata ia benar-benar luas pengetahuan tentang matematika yang sudah dipelajarinya. Hingga akhirnya, mungkin untuk menunjukkan kepiawaiannya, ia mengajak saya adu cepat mengerjakan soal matematika.
Mendapat tantangan itu, sebenernya saya ngeper juga. Karena saya merasa tak sepandai dirinya. Namun, karena ini namanya juga bukan lomba dan bukan apa-apa, saya sih mau saja waktu itu. Soal-soal pun dipilih secara acak dari buku kumpulan soal-soal latihan tes UMPTN* dan EBTANAS** beberapa tahun sebelumnya yang masih rajin ia bawa ke mana-mana. Kemudian, adu cepat menyelesaikan soal matematika pun dimulai.
Bagaimana hasilnya? Siapa yang tercepat?


Ternyata benar, dalam beberapa menit saja, teman saya itu berhasil menyelesaikan semua soal yang sudah dipilih tadi (karena yang dipilih cuma 3 soal sih). Dan ia keluar sebagai yang tercepat, menjadi pemenang. Sedangkan saya, satu soal pun belum mampu saya selesaikan. Waktu itu, saya terlalu berkutat dengan soal nomor pertama yang lumayan sukar untuk ukuran saya waktu itu. Walau sudah dengan segenap kemampuan saya berusaha menyelesaikannya, tapi ternyata, sampai waktu habis belum ketemu juga. Saya pun mengakui kelebihan dan kehebatannya.
Dengan sedikit malu-malu, saya bertanya padanya tentang soal yang belum bisa saya selesaikan tersebut. Sambil saya tanyakan pula kenapa ia begitu cepat bisa menyelesaikan soal-soal tersebut. Soal yang waktu itu belum bisa saya selesaikan adalah seperti berikut ini.

Soal: Bila a + 1/a = 5, maka nilai dari a3 + 1/a3 =…

Dengan cepat teman saya itu pun menyelesaikan soal tersebut seperti berikut ini:

a3 + 1/a3 = (a + 1/a)3 – 3a.1/a(a + 1/a) = 53 – 3(5) = 125 – 15 = 110.

Melihat cara penyelesaiannya, saya hanya bisa melongo waktu itu. “Cuma satu baris? Padahal saya mencoba menyelesaikannya berbaris-baris, dan belum ketemu juga”, itu yang ada di pikiran saya. Kemudian, saya pun bertanya ke teman saya itu, kenapa cara pengerjaannya seperti itu?
Dengan senang hati, ia pun menjelaskan ke saya. Ia katakan bahwa, soal semacam tersebut dapat dengan mudah diselesaikan dengan rumus “cepat” berikut ini.

a3 + b3 = (a + b)3 – 3ab(a + b) ………………………………..(1)

Dengan mengganti b dengan 1/a, katanya, maka soal tadi dapat diselesaikan dengan cepat seperti yang sudah dikerjakannya tadi.
Saya yang tak terbiasa menggunakan rumus “cepat” ketika di SMA dulu, penasaran ingin tahu alasan kenapa rumus “cepat” tersebut bisa dipakai. Tapi sayang, teman saya itu tak memberi tahu saya. Malahan ia menambah lagi rumus cepat yang sudah ia ketahuinya, yaitu:

a3 – b3 = (a – b)3 + 3ab(a – b)……………………………….(2)

Akhirnya, ngobrol-ngobrol pun beres. Ia bergegas pulang menuju kost-kost-annya. Saya pun begitu, pulang dengan rasa penasaran yang mengganjal.
Di kost-kost-an, dengan penuh rasa penasaran ingin tahu, saya pun mengutak-atik rumus “cepat” yang telah ia gunakan tersebut. Setelah beberapa waktu lamanya, akhirnya, terpecahkan juga rahasia rumus “cepat” yang dipakai teman saya tersebut. Saya berhasil menelusuri asal-muasal rumus “cepat” tersebut, berhasil menguak rahasianya. (Duh rasanya begitu senang sekali, tak bisa saya ekspresikan dengan kata-kata).
Hasil penelusuran saya tersebut, setelah saya rapikan, seperti berikut ini.

(a + b)3 = (a + b)2(a + b)
= (a2 + 2ab + b2)( a + b)
= a3 + a2b + 2a2b + 2ab2 + b2a + b3
= a3 + b3 + 3a2b + 3ab2
= a3 + b3 + 3ab (a + b)
Jadi, (a + b)3 = a3 + b3 + 3ab (a + b).

Sehingga, a3 + b3 = (a + b)3 – 3ab (a + b). Rumus “cepat” (1) dapat saya buktikan kebenarannya. Kemudian, dengan cara serupa, saya pun berhasil menelusuri asal-muasal rumus “cepat” (2).

Walaupun apa yang telah saya lakukan tersebut sederhana, tapi bagi ukuran saya waktu itu adalah sesuatu yang menggembirakan hati, menyenangkan pikiran, dan memuaskan dahaga keingin-tahuan saya.
Sejak saat itu, bila ada rumus-rumus “cepat” yang saya temui di buku-buku bimbingan tes, saya pun terpacu untuk menelusuri asal-muasalnya. Dengan cara seperti itu, saya seringkali berhasil memecahkan rahasia rumus-rumus “cepat” yang selama ini beredar luas di kalangan siswa yang mengikuti bimbingan test.
Baiklah, segitu dulu saja ceritanya ya…, lain kali insya Allah saya akan membahas baik-buruknya penggunaan rumus “cepat” (Ada satu cerita yang sangat menggelikan tentang hal ini. Mau tahu? Silakan tunggu di postingan mendatang…). Sampai di sini dulu ya…, mudah-mudahan bermanfaat.
Sebagai bahan latihan untuk Anda, cobalah telusuri asal-muasal rumus-rumus “cepat” berikut ini.
  1. Persamaan garis yang melalui titik (0, a) dan (b, 0) adalah ax + by = ab.
  2. Perhatikan gambar berikut. Panjang PQ dapat ditentukan dengan mudah, yaitu:
    PQ = (AP. DC + DP. AB)/(AD)


    Sumber : mathematicse.wordpress.com 

Materi Matematika Khusus Kelas 6 SD

Updated NDK for Android 4.0

Today we are releasing an updated version of the Android NDK, now in revision 7. The updated NDK lets developers who are using native code get started with the new native APIs available in Android 4.0.

Android NDK r7 includes a number of build system improvements and bug fixes, but most importantly it gives you access to two new sets of APIs:

Low-level streaming multimedia: A new API based on Khronos OpenMAX AL 1.0.1 provides a direct, efficient path for low-level streaming multimedia. The new path is ideal for applications that need to maintain complete control over media data before passing it to the platform for presentation. For example, media applications can now retrieve data from any source, apply proprietary encryption/decryption, and then send the data to the platform for display.

Audio decoding into PCM: Extensions to the existing native audio API based on Khronos OpenSL ES let native apps decode compressed audio assets to PCM format.

For detailed information about how to use these new APIs, please see the documentation included with the Android NDK r7 package. To read about the build system improvements and bug fixes included in this release, check out the release notes.

New Layout Widgets: Space and GridLayout

[This post is by Philip Milne, who is part of the Android framework team. — Tim Bray]

Ice Cream Sandwich (ICS) sports two new widgets that have been designed to support the richer user interfaces made possible by larger displays: Space and GridLayout.

The most commonly used class for layout in Android is LinearLayout, which allows its children to be aligned in the usual ways: along either the horizontal or vertical axes. It’s often possible to take a complicated layout and break it down into a set of nested linear layouts and, provided this nesting doesn’t get too deep, this is still a good choice for many simple layouts.

A number of posts and articles (e.g. Android Layout Tricks #1, Flattening The Stack) have highlighted drawbacks of nested layouts; which fall into three basic categories:

  • Inability to control alignment along both axes simultaneously


  • Performance problems in hierarchies that are too deep


  • Unsuitability for design tools that support free-form editing


A simple example of the first problem is the following form:

As the font and the text of the “Email address” label change, we want the label to remain aligned with the baseline of the component to its right, and aligned with the right edge of the label below it. It’s not possible to do this with nested LinearLayouts because the label needs to be aligned with other components both horizontally and vertically.

These problems aren’t new to Android, or UI toolkits in general, but we’ve used them to drive our work in enriching platform support for flatter hierarchies.

GridLayout

To provide better support for layouts like these we have added a new layout to the Android framework: GridLayout, which can be used to solve the above problems by dividing the container’s real estate into rows and columns:

Now the “Email address” label can belong both to a row that is baseline-aligned, and a column that is right-aligned.

GridLayout uses a grid of infinitely-thin lines to separate its drawing area into: rows, columns, and cells. It supports both row and column spanning, which together allow a widget to occupy a rectangular range of cells that are next to each other. We’ll use the words row, column, and cell in the text below as shorthand for row group, column group and cell group respectively, where groups have one or more contiguous elements.

Similarities with LinearLayout

Wherever possible, GridLayout uses the same conventions as LinearLayout for all its XML API — so it should be easy to start using GridLayout if you’ve already used LinearLayout. In fact, the APIs are so similar that changing a tag name from LinearLayout to GridLayout in an XML file that uses LinearLayout will often produce a similar UI without requiring any other changes. When it doesn’t, you’ll still generally end up with a good starting point for a two-dimensional layout.

Getting Started

Two examples in the samples area of the Android 4.0 SDK show typical use of the programmatic and XML APIs respectively:

[Both examples produce the same UI.]

Here’s a slightly simpler version of the above XML layout.

<?xml version="1.0" encoding="utf-8"?>
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"
android:layout_height="match_parent"

android:useDefaultMargins="true"
android:alignmentMode="alignBounds"
android:columnOrderPreserved="false"

android:columnCount="4"
>

<TextView
android:text="Email setup"
android:textSize="32dip"

android:layout_columnSpan="4"
android:layout_gravity="center_horizontal"
/>

<TextView
android:text="You can configure email in just a few steps:"
android:textSize="16dip"

android:layout_columnSpan="4"
android:layout_gravity="left"
/>

<TextView
android:text="Email address:"

android:layout_gravity="right"
/>

<EditText
android:ems="10"
/>

<TextView
android:text="Password:"

android:layout_column="0"
android:layout_gravity="right"
/>

<EditText
android:ems="8"
/>

<Space
android:layout_row="4"
android:layout_column="0"
android:layout_columnSpan="3"
android:layout_gravity="fill"
/>

<Button
android:text="Next"

android:layout_row="5"
android:layout_column="3"
/>
</GridLayout>

The first difference you’ll notice in these examples is the absence of the WRAP_CONTENT and MATCH_PARENT constants that normally adorn Android layout resources. You don’t normally need to use these with GridLayout, for reasons that are described in the API doc for GridLayout.LayoutParams.

Row and Column Indices

The second thing you may notice in the XML resources is that widgets don’t always explicitly define which cells they are to be placed in. Each widget’s layout parameters have row and column indices that together define where the widget should be placed but when either or both of these values are not specified, GridLayout supplies default values rather than throwing an exception.

Automatic Index Allocation

As children are added to a GridLayout, it maintains a cursor position and a “high-water mark” that it uses to place widgets in cells that don’t yet have anything in them.

When GridLayout’s orientation property is horizontal and a columnCount has been set (to 8 in this example) the high-water mark (shown above in red) is maintained as a separate height value for each column. When indices need to be created, GridLayout first determines the size of the cell group (by looking at the rowSpan and columnSpan parameters of the new widget) and then, starting at the cursor, goes through the available locations from: left to right, top to bottom, so as to find the row and column indices of the first location that’s free.

When GridLayout’s orientation is vertical, all of the same principles apply, except that the roles of the horizontal and vertical axes are exchanged.

If you want multiple views to be placed in the same cell, you have to define the indices explicitly, as the default allocation procedure above is designed to place widgets in separate cells.

Sizes, Margins and Alignment/Gravity

In GridLayout, specifying sizes and margins is done just as with a LinearLayout. Alignment/gravity also works just like gravity in LinearLayout and uses the same constants: left, top, right, bottom, center_horizontal, center_vertical, center, fill_horizontal, fill_vertical and fill.

Flexibility

Unlike most grids in other toolkits, GridLayout does not associate data with rows or columns. Instead, everything to do with alignment and flexibility is associated with the components themselves. GridLayout departs from the norm here to provide a more general system that allows subtle relationships between ancestors in deeply nested layouts to be accommodated in a single layout configuration.

The flexibility of columns is inferred from the gravity of the components inside the column. If every component defines a gravity, the column is taken as flexible, otherwise the column is considered inflexible. Full details are in GridLayout’s API docs.

Emulating Features from other Layouts

GridLayout does not incorporate all of the features of every layout in the Android platform but it has a rich enough feature set that idiomatic use of other layouts can normally be emulated from inside a single GridLayout.

Although LinearLayout can be considered a special case of a GridLayout, for the degenerate case when a set of views are aligned in a single row or column, LinearLayout is the better choice when this is all that is required as it clarifies the purpose of the container and may have some (relatively small) performance advantages.

TableLayout configurations are normally straightforward to accommodate, as GridLayout supports both row and column spanning. TableRows can be removed, as they are not required by GridLayout. For the same UI, a GridLayout will generally be faster and take less memory than than a TableLayout.

Simple RelativeLayout configurations can be written as grids simply by grouping the views that are related to each other into rows and columns. Unlike conventional grids, GridLayout uses a constraints solver to do the heavy lifting of the layout operation. By using GridLayout’s rowOrderPreserved and columnOrderPreserved properties it’s possible to free GridLayout from the confines of traditional grid systems and support the majority of RelativeLayout configurations — even ones that require grid lines to pass over each other as children change size.

Simple FrameLayout configurations can be accommodated within the cells of a GridLayout because a single cell can contain multiple views. To switch between two views, place them both in the same cell and use the visibility constant GONE to switch from one to the other from code. As with the LinearLayout case above, if all you need is the functionality described above, FrameLayout is the better choice and may have some small performance advantages.

One key feature that GridLayout lacks is the ability to distribute excess space between rows or columns in specified proportions — a feature that LinearLayout provides by supporting the principle of weight. This omission and possible ways around it are discussed in GridLayout’s API docs.

The Phases of the Layout Operation

It’s useful to distinguish the allocation phase for cell indices discussed above from the layout operation itself. Normally the phase that allocates indices happens once, if at all, when a UI is initialized. The index-allocation phase only applies when indices have been left unspecified, and is responsible for ensuring that all views have a defined set of cells in which they are to be placed at layout time.

The layout operation happens after this and is recalculated each time a view changes size. GridLayout measures the size of each child during the layout operation so it can calcuate the heights and widths of the rows and columns in the grid. The layout phase completes by using gravity to place each of the components in its cell.

Although index allocation normally only happens once, GridLayout is technically a dynamic layout, meaning that if you change its orientation property or add or remove children after components have been laid out, GridLayout will repeat the above procedure to reallocate indices in a way that is right for the new configuration.

From a performance standpoint, it is worth knowing that the GridLayout implementation has been optimized for the common case, when initialization happens once and layout happens frequently. As a result, the initialization step sets up internal data structures so that the layout operation can complete quickly and without allocating memory. Put another way, changes either to GridLayout’s orientation or the number of children it has are much more expensive than an ordinary layout operation.

Conclusion

GridLayout’s feature set incorporates much of the functionality of the Android framework’s existing general-purpose layouts: LinearLayout, FrameLayout, TableLayout and RelativeLayout. As such, it provides a way to replace many deeply nested view hierarchies with a single highly optimized layout implementation.

If you are starting a UI from scratch and are not familiar with Android layouts, use a GridLayout — it supports most of the features of the other layouts and has a simpler and more general API than either TableLayout or RelativeLayout.

We anticipate that the combination of FrameLayout, LinearLayout and GridLayout together will provide a feature set that’s rich enough to allow most layout problems to be solved without writing layout code by hand. It’s worth spending some time deciding which of these layouts is right for the top of your tree; a good choice will minimize the need for intermediate containers and result in a user interface that is faster and uses less memory.

More Android Developer Labs in Asia

A couple of months ago, we kicked off a series of Android Developer Labs in Asia, North America and Europe. To wrap up the 2011 series, we now have opened registration for 2 more locations in Asia.

  • Taipei — December 2, 2011

  • Hong Kong — December 6, 2011

Remember, this ADL series isn’t another set of introduction-to-Android sessions, nor any other kind of general overview. It's specifically aimed at optimizing Android apps for tablets, in particular creating high-quality tablet apps with an emphasis on polish and user experience.

Registration is a two-step process. Anyone can register, but we can only accommodate a relatively small number of attendees from among the registrants, based on whether they already have an Android app with the potential to be a top-tier tablet app in terms of quality, fit, and finish. The goal is to bring your app to the ADL, and leave equipped to make it into one that makes Android tablet users smile.

JNI Local Reference Changes in ICS

[This post is by Elliott Hughes, a Software Engineer on the Dalvik team. — Tim Bray]

If you don’t write native code that uses JNI, you can stop reading now. If you do write native code that uses JNI, you really need to read this.

What’s changing, and why?

Every developer wants a good garbage collector. The best garbage collectors move objects around. This lets them offer very cheap allocation and bulk deallocation, avoids heap fragmentation, and may improve locality. Moving objects around is a problem if you’ve handed out pointers to them to native code. JNI uses types such as jobject to solve this problem: rather than handing out direct pointers, you’re given an opaque handle that can be traded in for a pointer when necessary. By using handles, when the garbage collector moves an object, it just has to update the handle table to point to the object’s new location. This means that native code won’t be left holding dangling pointers every time the garbage collector runs.

In previous releases of Android, we didn’t use indirect handles; we used direct pointers. This didn’t seem like a problem as long as we didn’t have a garbage collector that moves objects, but it let you write buggy code that still seemed to work. In Ice Cream Sandwich, even though we haven't yet implemented such a garbage collector, we've moved to indirect references so you can start detecting bugs in your native code.

Ice Cream Sandwich features a JNI bug compatibility mode so that as long as your AndroidManifest.xml’s targetSdkVersion is less than Ice Cream Sandwich, your code is exempt. But as soon as you update your targetSdkVersion, your code needs to be correct.

CheckJNI has been updated to detect and report these errors, and in Ice Cream Sandwich, CheckJNI is on by default if debuggable="true" in your manifest.

A quick primer on JNI references

In JNI, there are several kinds of reference. The two most important kinds are local references and global references. Any given jobject can be either local or global. (There are weak globals too, but they have a separate type, jweak, and aren’t interesting here.)

The global/local distinction affects both lifetime and scope. A global is usable from any thread, using that thread’s JNIEnv*, and is valid until an explicit call to DeleteGlobalRef(). A local is only usable from the thread it was originally handed to, and is valid until either an explicit call to DeleteLocalRef() or, more commonly, until you return from your native method. When a native method returns, all local references are automatically deleted.

In the old system, where local references were direct pointers, local references were never really invalidated. That meant you could use a local reference indefinitely, even if you’d explicitly called DeleteLocalRef() on it, or implicitly deleted it with PopLocalFrame()!

Although any given JNIEnv* is only valid for use on one thread, because Android never had any per-thread state in a JNIEnv*, it used to be possible to get away with using a JNIEnv* on the wrong thread. Now there’s a per-thread local reference table, it’s vital that you only use a JNIEnv* on the right thread.

Those are the bugs that ICS will detect. I’ll go through a few common cases to illustrate these problems, how to spot them, and how to fix them. It’s important that you do fix them, because it’s likely that future Android releases will utilize moving collectors. It will not be possible to offer a bug-compatibility mode indefinitely.

Common JNI reference bugs

Bug: Forgetting to call NewGlobalRef() when stashing a jobject in a native peer

If you have a native peer (a long-lived native object corresponding to a Java object, usually created when the Java object is created and destroyed when the Java object’s finalizer runs), you must not stash a jobject in that native object, because it won’t be valid next time you try to use it. (Similar is true of JNIEnv*s. They might be valid if the next native call happens on the same thread, but they won’t be valid otherwise.)

 class MyPeer {
public:
MyPeer(jstring s) {
str_ = s; // Error: stashing a reference without ensuring it’s global.
}
jstring str_;
};

static jlong MyClass_newPeer(JNIEnv* env, jclass) {
jstring local_ref = env->NewStringUTF("hello, world!");
MyPeer* peer = new MyPeer(local_ref);
return static_cast<jlong>(reinterpret_cast<uintptr_t>(peer));
// Error: local_ref is no longer valid when we return, but we've stored it in 'peer'.
}

static void MyClass_printString(JNIEnv* env, jclass, jlong peerAddress) {
MyPeer* peer = reinterpret_cast<MyPeer*>(static_cast<uintptr_t>(peerAddress));
// Error: peer->str_ is invalid!
ScopedUtfChars s(env, peer->str_);
std::cout << s.c_str() << std::endl;
}

The fix for this is to only store JNI global references. Because there’s never any automatic cleanup of JNI global references, it’s critically important that you clean them up yourself. This is made slightly awkward by the fact that your destructor won’t have a JNIEnv*. The easiest fix is usually to have an explicit ‘destroy‘ function for your native peer, called from the Java peer’s finalizer:

 class MyPeer {
public:
MyPeer(JNIEnv* env, jstring s) {
this->s = env->NewGlobalRef(s);
}
~MyPeer() {
assert(s == NULL);
}
void destroy(JNIEnv* env) {
env->DeleteGlobalRef(s);
s = NULL;
}
jstring s;
};

You should always have matching calls to NewGlobalRef()/DeleteGlobalRef(). CheckJNI will catch global reference leaks, but the limit is quite high (2000 by default), so watch out.

If you do have this class of error in your code, the crash will look something like this:

    JNI ERROR (app bug): accessed stale local reference 0x5900021 (index 8 in a table of size 8)
JNI WARNING: jstring is an invalid local reference (0x5900021)
in LMyClass;.printString:(J)V (GetStringUTFChars)
"main" prio=5 tid=1 RUNNABLE
| group="main" sCount=0 dsCount=0 obj=0xf5e96410 self=0x8215888
| sysTid=11044 nice=0 sched=0/0 cgrp=[n/a] handle=-152574256
| schedstat=( 156038824 600810 47 ) utm=14 stm=2 core=0
at MyClass.printString(Native Method)
at MyClass.main(MyClass.java:13)

If you’re using another thread’s JNIEnv*, the crash will look something like this:

 JNI WARNING: threadid=8 using env from threadid=1
in LMyClass;.printString:(J)V (GetStringUTFChars)
"Thread-10" prio=5 tid=8 NATIVE
| group="main" sCount=0 dsCount=0 obj=0xf5f77d60 self=0x9f8f248
| sysTid=22299 nice=0 sched=0/0 cgrp=[n/a] handle=-256476304
| schedstat=( 153358572 709218 48 ) utm=12 stm=4 core=8
at MyClass.printString(Native Method)
at MyClass$1.run(MyClass.java:15)

Bug: Mistakenly assuming FindClass() returns global references

FindClass() returns local references. Many people assume otherwise. In a system without class unloading (like Android), you can treat jfieldID and jmethodID as if they were global. (They’re not actually references, but in a system with class unloading there are similar lifetime issues.) But jclass is a reference, and FindClass() returns local references. A common bug pattern is “static jclass”. Unless you’re manually turning your local references into global references, your code is broken. Here’s what correct code should look like:

 static jclass gMyClass;
static jclass gSomeClass;

static void MyClass_nativeInit(JNIEnv* env, jclass myClass) {
// ‘myClass’ (and any other non-primitive arguments) are only local references.
gMyClass = env->NewGlobalRef(myClass);

// FindClass only returns local references.
jclass someClass = env->FindClass("SomeClass");
if (someClass == NULL) {
return; // FindClass already threw an exception such as NoClassDefFoundError.
}
gSomeClass = env->NewGlobalRef(someClass);
}

If you do have this class of error in your code, the crash will look something like this:

    JNI ERROR (app bug): attempt to use stale local reference 0x4200001d (should be 0x4210001d)
JNI WARNING: 0x4200001d is not a valid JNI reference
in LMyClass;.useStashedClass:()V (IsSameObject)

Bug: Calling DeleteLocalRef() and continuing to use the deleted reference

It shouldn’t need to be said that it’s illegal to continue to use a reference after calling DeleteLocalRef() on it, but because it used to work, so you may have made this mistake and not realized. The usual pattern seems to be where native code has a long-running loop, and developers try to clean up every single local reference as they go to avoid hitting the local reference limit, but they accidentally also delete the reference they want to use as a return value!

The fix is trivial: don’t call DeleteLocalRef() on a reference you’re going to use (where “use” includes “return”).

Bug: Calling PopLocalFrame() and continuing to use a popped reference

This is a more subtle variant of the previous bug. The PushLocalFrame() and PopLocalFrame() calls let you bulk-delete local references. When you call PopLocalFrame(), you pass in the one reference from the frame that you’d like to keep (typically for use as a return value), or NULL. In the past, you’d get away with incorrect code like the following:

 static jobjectArray MyClass_returnArray(JNIEnv* env, jclass) {
env->PushLocalFrame(256);
jobjectArray array = env->NewObjectArray(128, gMyClass, NULL);
for (int i = 0; i < 128; ++i) {
env->SetObjectArrayElement(array, i, newMyClass(i));
}
env->PopLocalFrame(NULL); // Error: should pass 'array'.
return array; // Error: array is no longer valid.
}

The fix is generally to pass the reference to PopLocalFrame(). Note in the above example that you don’t need to keep references to the individual array elements; as long as the GC knows about the array itself, it’ll take care of the elements (and any objects they point to in turn) itself.

If you do have this class of error in your code, the crash will look something like this:

  JNI ERROR (app bug): accessed stale local reference 0x2d00025 (index 9 in a table of size 8)
JNI WARNING: invalid reference returned from native code
in LMyClass;.returnArray:()[Ljava/lang/Object;

Wrapping up

Yes, we asking for a bit more attention to detail in your JNI coding, which is extra work. But we think that you’ll come out ahead on the deal as we roll in better and more sophisticated memory management code.

Android 4.0 Graphics and Animations

[This post is by Romain Guy and Chet Haase, Android engineers who have been known to collaborate on the subject of graphics, UIs, and animation. You can read more from them on their blogs at curious-creature.org and graphics-geek.blogspot.com. — Tim Bray]

Earlier this year, Android 3.0 launched with a new 2D rendering pipeline designed to support hardware acceleration on tablets. With this new pipeline, all drawing operations performed by the UI toolkit are carried out using the GPU.

You’ll be happy to hear that Android 4.0, Ice Cream Sandwich, brings an improved version of the hardware-accelerated 2D rendering pipeline to phones, starting with Galaxy Nexus.

Enabling hardware acceleration

In Android 4.0 (API level 14), hardware acceleration, for the first time, is on by default for all applications. For applications at lower API levels, you can turn it on by adding android:hardwareAccelerated="true" to the <application> tag in your AndroidManifest.xml.

To learn more about the hardware accelerated 2D rendering pipeline visit the official Android developer guide. This guide explains how to control hardware acceleration at various levels, offers several performance tips and tricks and describes in details the new drawing model.

I also encourage you to watch the Android Hardware Accelerated Rendering talk that we gave at Google I/O 2011.

Introducing TextureView

Applications that need to display OpenGL or video content rely today on a special type of UI element called SurfaceView. This widget works by creating a new window placed behind your application’s window. It then punches a hole through your application’s window to reveal the new window. While this approach is very efficient, since the content of the new window can be refreshed without redrawing the application’s window, it suffers from several important limitations.

Because a SurfaceView’s content does not live in the application’s window, it cannot be transformed (moved, scaled, rotated) efficiently. This makes it difficult to use a SurfaceView inside a ListView or a ScrollView. SurfaceView also cannot interact properly with some features of the UI toolkit such as fading edges or View.setAlpha().

To solve these problems, Android 4.0 introduces a new widget called TextureView that relies on the hardware accelerated 2D rendering pipeline and SurfaceTexture. TextureView offers the same capabilities as SurfaceView but, unlike SurfaceView, behaves as a regular view. You can for instance use a TextureView to display an OpenGL scene or a video stream. The TextureView itself can be animated, scrolled, etc.

The following piece of code creates a TextureView to display the video preview from the default camera. The TextureView itself is rotated 45 degrees and semi-transparent.

public class TextureViewActivity extends Activity implements TextureView.SurfaceTextureListener {
private Camera mCamera;
private TextureView mTextureView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

mTextureView = new TextureView(this);
mTextureView.setSurfaceTextureListener(this);

setContentView(mTextureView);
}

@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mCamera = Camera.open();

Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
mTextureView.setLayoutParams(new FrameLayout.LayoutParams(
previewSize.width, previewSize.height, Gravity.CENTER));

try {
mCamera.setPreviewTexture(surface);
} catch (IOException t) {
}

mCamera.startPreview();

mTextureView.setAlpha(0.5f);
mTextureView.setRotation(45.0f);
}

@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// Ignored, the Camera does all the work for us
}

@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
mCamera.stopPreview();
mCamera.release();
return true;
}

@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
// Called whenever a new frame is available and displayed in the TextureView
}
}

A TextureView can just as easily be used to embed an OpenGL scene in your application. As of Android 4.0, eglCreateWindowSurface() can be used to render into a SurfaceTexture object.

Animation

There were minor improvements in Android 4.0 to some of the new animation facilities that were added in the 3.x releases.

First, if you're new to the new android.animation package and classes added in 3.0 and 3.1, you might want to read Animation in Honeycomb and Introducing ViewPropertyAnimator. These articles discuss the new APIs added in 3.0 that make animation in Android easier, more powerful, and more flexible. The Android 4.0 improvements discussed below are small additions to these core facilities.

Properties

One of the constraints of the Java programming language is the lack of “properties”. There is no way to refer generically to a field or a setter/getter of an object. As long as you know what kind of object you have, this is not a problem, because you then know the set of fields and methods that you can call. But if someone passes you some subclass of Object and you'd like to get or set some value “foo” on it, you're out of luck. You can use reflection or JNI to get access to the foo field/methods, but there is no way to refer directly to a field or a method unless you know the instance type of the object that has that field/method on it.

This is a constraint that the new animation system works within. Its whole job, you might say, is to get and set values on generic objects that it's been told about. If someone wants to animate the alpha property on a View, they tell the system the target object and the name of that field (“alpha”), and the animation system uses JNI to figure out which method(s) act on a field of that name. Basically, it looks for setAlpha() and, sometimes, getAlpha() methods. Then when an animation frame occurs, it calculates the new value and passes it into the setter method that it found.

This seems like a lot of work for what it does, but there's really no way around it. Unless the animation system were specific to View objects, there's no way that it could know that the target object has appropriate setter/getter methods. And even if it did, there's still no way for callers that construct the animations to tell the animator about the property named “alpha”; there are no function handles like there are in other languages, and there's no way to reference a public field either. (I'm ignoring Reflection here, which has Method and Field objects, because this approach requires much more overhead and processing than the simple function/field references of other languages).

If only there were a way to refer to these properties and to get/set them on generic objects...

Now there is. There is a new Property object in the android.util package that does exactly this. This class offers a set() and a get() method. So if someone hands you a Property object, you can safely call the set() and get() methods without knowing anything about the target object and it will do the job. Moreover, it will do it much more efficiently than the current JNI or reflection approaches because it can, depending on the implementation of it, set a field or call a method on the target object directly. For example, the new ALPHA property on View calls setAlpha() on the View object.

The Property class is a generic utility that can be used anywhere, not just in animations. But it's animations that benefit enormously from it, in their ability to handle properties in a type-safe and efficient manner.

For example prior to Android 4.0, you might construct a fade-out animation on some object myView like this:

ObjectAnimator anim = ObjectAnimator.ofFloat(myView, "alpha", 0);

In Android 4.0, you can use the new ALPHA object on View to construct a Property-based animator instead:

ObjectAnimator anim = ObjectAnimator.ofFloat(myView, View.ALPHA, 0);

ViewPropertyAnimator Additions

There were minor API additions to the ViewPropertyAnimator class (introduced in Android 3.1) which make this class more flexible and powerful:

  • cancel(): You can now cancel() a running ViewPropertyAnimator.


  • setStartDelay(): You can now set a startDelay on the ViewPropertyAnimator, just like the startDelay of the other Animator classes.


  • start(): ViewPropertyAnimators start automatically, but they do so on the next animation frame handled. This allows them to collect several requests and bundle them together, which is much more efficient and makes it easier to synchronize multiple animations together. However, if you just want to run a single animation, or want to make sure it starts immediately, at the time of construction, you can call start() to avoid that intervening delay.


LayoutTransition

LayoutTransition (introduced in Android 3.0) continues to provide functionality that makes some kinds of animations easier, specifically when adding, removing, hiding, and showing views. For example, either this snippet in a layout file:

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:id="@+id/container">

Or this code added at runtime:

 container.setLayoutTransition(new LayoutTransition());

will result in a container that animates the visibility of its children views. So when a view is added to the container, the other children will animate out of the way and then the new one will fade in. Similarly, removing a child from the container will fade it out and then animate the other children around to their final places and sizes.

You can customize the animations and timing behavior of a LayoutTransition object, but the code above allows a very easy way to get reasonable default animation behavior.

One of the constraints in the pre-4.0 version of the class was that it did not account for changes in the bounds of the parent hierarchy. So, for example, if a LinearLayout with horizontal orientation has a layout_width of wrap_content and you want to run a transition that removes an item from that layout, then you might notice the parent snapping to the end size and clipping its children instead of animating all of them into their new positions. The new approach (enabled by default, but disabled by a call to setAnimateParentHierarchy(false)) also animates the layout bounds and scrolling values of the parent layout and its parents, all the way up the view hierarchy. This allows LayoutTransition to account for all layout-related changes due to that view being added or removed from its transitioning container.

Conclusion

The Android 3.0 release saw huge improvements in the visual capabilities of the platform, as we started enabling hardware acceleration and providing new, more flexible animation capabilities. Android 4.0 continues this trend as we continue to work hard on improving the performance, features, and usability of the Android APIs. We’re not done yet, but the enhancements in this release should help you create more exciting Android experiences and applications.