Pastikan anda sudah menginstall serta konfigurasi NPM serta Node.js.
Pertama tama, ketik ionic start LoginApp
3. Pilih blank .
4. input y
5. input n
6. Apabila proses instalasi sudah selesai, masuk ke folder anda dengan mengetik cd LoginApp
7. Untuk mengecek apakah sudah berhasil, ketik ionic serve -ctl
8. Sekarang kita akan membuat 2 buah halaman yaitu login dan home dengan megetik ionic generate page login untuk halaman login, serta ionic generate page home untuk halaman home.
9. Kemudian buka folder project LoginApp dengan IDE anda, pada tutorial ini menggunakan Visual Code.
10. Lalu masuk ke src/pages/login/login.html
11. Masukkan code berikut , ubah code aslinya yang ada pada gambar di atas
Pada kesempatan kali ini, kita akan mencoba membuat CRUD(Create, Read, Update, Delete) menggunakan framework codeigniter. Langsung saja kita mulai dengan langkah pertama ini, dengan membuat database dengan nama tutorial_rumah_coding dan sebuah table dengan nama siswa seperti yang terlihat dibawah ini:
Selanjutnya lakukan pengaturan pada file autoload.php yang terdapat didalam folder application/config/ seperti berikut ini :
Setelah helper dan libraries yang kita butuhkan sudah diload, selanjutnya hubungkan database dengan project kita seperti berikut ini :
Tidak lupa juga untuk mengatur base_url yang terdapat didalam file config.php pada folder application/config/ :
Kemudian buat sebuah controllers dengan nama CrudSiswa.php dengan perintah sebagai berikut ini :
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class CrudSiswa extends CI_Controller {
public function __construct(){
parent ::__construct();
//load model
$this->load->model('CrudSiswaModel');
}
public function index()
{
$data = array(
'title' => 'Data Siswa',
'data_siswa' => $this->CrudSiswaModel->get_all(),
);
$this->load->view('datasiswa', $data);
}
public function tambah()
{
$data = array(
'title' => 'Tambah Data Siswa'
);
$this->load->view('tambahsiswa', $data);
}
public function simpan()
{
$data = array(
'id_siswa' => $this->input->post("id_siswa"),
'nama' => $this->input->post("nama"),
'email' => $this->input->post("email"),
'password' => $this->input->post("password"),
'telepon' => $this->input->post("telepon"),
'pelajaran' => $this->input->post("pelajaran")
);
$this->CrudSiswaModel->simpan($data);
$this->session->set_flashdata('notif', '<div class="alert alert-success alert-dismissible"> Success! data siswa berhasil disimpan didatabase.
</div>');
//redirect
redirect('CrudSiswa/');
}
public function edit($id_siswa)
{
$id_siswa = $this->uri->segment(3);
$data = array(
'title' => 'Edit Data Siswa',
'data_siswa' => $this->CrudSiswaModel->edit($id_siswa)
);
$this->load->view('editsiswa', $data);
}
public function update()
{
$id['id_siswa'] = $this->input->post("id_siswa");
$data = array(
'id_siswa' => $this->input->post("id_siswa"),
'nama' => $this->input->post("nama"),
'email' => $this->input->post("email"),
'password' => $this->input->post("password"),
'telepon' => $this->input->post("password"),
'pelajaran' => $this->input->post("pelajaran"),
);
$this->CrudSiswaModel->update($data, $id);
$this->session->set_flashdata('notif', '<div class="alert alert-success alert-dismissible"> Success! data berhasil diupdate didatabase.
</div>');
//redirect
redirect('CrudSiswa');
}
public function hapus($id_siswa)
{
$this->CrudSiswaModel->hapus($id_siswa);
//redirect
redirect('CrudSiswa');
}
}
Selanjutnya buat sebuah Model dengan nama CrudSiswaModel.php dengan perintah seperti berikut ini :
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class CrudSiswaModel extends CI_model{
public function get_all()
{
$query = $this->db->select("*")
->from('siswa')
->order_by('id_siswa', 'DESC')
->get();
return $query->result();
}
public function simpan($data)
{
$query = $this->db->insert("siswa", $data);
if($query){
return true;
}else{
return false;
}
}
public function edit($id_siswa)
{
$query = $this->db->where("id_siswa", $id_siswa)
->get("siswa");
if($query){
return $query->row();
}else{
return false;
}
}
public function update($data, $id_siswa)
{
$query = $this->db->update("siswa", $data, $id_siswa);
if($query){
return true;
}else{
return false;
}
}
public function hapus($id_siswa)
{
$this->db->where('id_siswa', $id_siswa);
$this->db->delete('siswa');
}
}
Langkah Terakhir Adalah membuat halaman/view untuk menampikan data siswa, halaman tambah data siswa dan halaman edit data siswa. Pertama kita membuat halaman data siswa dengan nama file datasiswa.php :
Pada kesempatan kali ini, kita coba membuat restful dengan framework Codeigniter. Untuk persiapan yang kita butuhkan dalam tutorial kali ini adalah sebagai berikut :
Install aplikasi Xampp, yang dapat didownload pada halaman ini
Framework Codeigniter
Database tutorial_rumah_coding dengan table siswa yang sebelumnya telah kita gunakan pada tutorial ini
Instal aplikasi postman, yang dapat didownload pada halaman ini
Instal Composer, yang dapat didownload pada halaman ini
Setelah tools yang kita butuhkan berhasil dijalankan, langkah pertama adalah kita perlu menginstall library untuk Codeigniter agar dapat membuat restful api. kita dapat menemukan library ini pada github atau packagist dengan kata kunci “codeigniter rest”. Adapun cara installnya adalah sebagai berikut :
Jika instalasi sukses, maka akan muncul didalam project Codeigniter kita folder bernama ‘codeigniter-restserver’ dimana didalam folder tersebut ada beberapa file yang perlu kita copy kedalam folder tutorialrumahcoding/application/. Adapun file tersebut adalah sebagai berikut :
copy file idap.php dan rest.php yang terdapat pada tutorialrumahcoding/codeigniter-restserver/application/config kedalam folder tutorialrumahcoding/application/ config
copy file db_helper.php yang terdapat pada tutorialrumahcoding/codeigniter-restserver/application/helpers kedalam folder tutorialrumahcoding/application/ helpers
copy file Format.php dan REST_Controller.php yang terdapat pada tutorialrumahcoding/codeigniter-restserver/application/libraries kedalam folder tutorialrumahcoding/application/ libraries
Selanjutnya Kita Coba Membuat Model dengan nama file SiswaModel.php didalam folder tutorialrumahcoding/application/ Models. Berikut baris Perintahnya :
<?php
class SiswaModel extends CI_Model{
// response jika field ada yang kosong
public function empty_response(){
$response['status']=502;
$response['error']=true;
$response['message']='Field tidak boleh kosong';
return $response;
}
// function untuk insert data ke tabel siswa
public function add_person($nama,$email,$password,$telepon,$pelajaran){
if(empty($nama) || empty($email) || empty($password) || empty($telepon) || empty($pelajaran)){
return $this->empty_response();
}else{
$data = array(
"nama"=>$nama,
"email"=>$email,
"password"=>$password,
"telepon"=>$telepon,
"pelajaran"=>$pelajaran
);
$insert = $this->db->insert("siswa", $data);
if($insert){
$response['status']=200;
$response['error']=false;
$response['message']='Data siswaditambahkan.';
return $response;
}else{
$response['status']=502;
$response['error']=true;
$response['message']='Data siswagagal ditambahkan.';
return $response;
}
}
}
// mengambil semua data siswa
public function all_person(){
$all = $this->db->get("siswa")->result();
$response['status']=200;
$response['error']=false;
$response['data']=$all;
return $response;
}
}
?>
Kemudian buat sebuah Controllers dengan nama Siswa.php didalam folder tutorialrumahcoding/application/ controllers. Berikut baris perintahnya :
<?php
require APPPATH . 'libraries/REST_Controller.php';
class Siswa extends REST_Controller{
// construct
public function __construct(){
parent::__construct();
$this->load->model('SiswaModel');
}
// method index untuk menampilkan semua Data Siswa menggunakan method get
public function index_get(){
$response = $this->SiswaModel->all_person();
$this->response($response);
}
// untuk menambah Data Siswa menaggunakan method post
public function add_post(){
$response = $this->SiswaModel->add_person(
$this->post('nama'),
$this->post('email'),
$this->post('password'),
$this->post('telepon'),
$this->post('pelajaran')
);
$this->response($response);
}
}
?>
Setelah Controllers dan Modelnya kita buat, saatnya kita coba memasukkan data kedalam database dengan method post dan mengambil data dengan method get menggunakan aplikasi postman. Pertama kita coba untuk memasukkan data kedalam database dengan cara berikut :
Saat memasukkan data dengan method POST, maka hasilnya akan terlihat seperti ini :
Kemudian coba mengambil data menggunakan method GET seperti ini :
24. Tambahkan code berikut pada file create.blade.php
25. Aktifkan folder public untuk menyimpan gambar
26. Buka file ProductController.php tambahkan code seperti gambar di bawah
27. Buka file ProductController.php tambahkan code dalam method store( )
public function store(Request $request)
{
//
$rules =[
'name'=>'required',
'price'=>'required|integer',
'imageFile'=>'required|mimes:jpg,png,jpeg,JPG',
'description'=>'required'
];
$pesan=[
'name.required'=>'Nama Barang Tidak Boleh Kosong',
'price.required'=>'Harga Barang Tidak Boleh Kosong',
'imageFile.required'=>'Gambar Tidak Boleh Kosong',
'description.required'=>'Deskripsi Tidak Boleh Kosong'
];
$validator=Validator::make(Input::all(),$rules,$pesan);
//jika data ada yang kosong
if ($validator->fails()) {
//refresh halaman
return Redirect::to('admin/product/create')
->withErrors($validator);
}else{
$image=$request->file('imageFile')->store('productImages','public');
$product=new \App\Product;
$product->name=Input::get('name');
$product->condition=Input::get('condition');
$product->description=Input::get('description');
$product->price=Input::get('price');
$product->image=$image;
$product->save();
Session::flash('message','Product Stored');
return "Berhasil Input Barang";
}
}
28. Sekarang coba input data pada form tambah data, lihat apakah berhasil
29. Buatlah sebuah file index.blade.php dalam folder product
30. Masukkan code di bawah ini ke dalam index.blade.php
public function update(Request $request, $id)
{
//
$rules=[
'name'=>'required',
'price'=>'required|integer',
'description'=>'required',
];
$pesan=[
'name.required'=>'Nama Tidak Boleh Kosong!!',
'price.required'=>'Harga Tidak Boleh Kosong!!',
'description.required'=>'Deskripsi Barang Tidak Boleh Kosong!!',
];
$validator=Validator::make(Input::all(),$rules,$pesan);
if ($validator->fails()) {
return Redirect::to('admin/product/'.$id.'/edit')
->withErrors($validator);
}else{
$image="";
if (!$request->file('imageFile')) {
# code...
$image=Input::get('imagePath');
}else{
$image=$request->file('imageFile')->store('productImages','public');
}
$product=\App\Product::find($id);
$product->name=Input::get('name');
$product->condition=Input::get('condition');
$product->price=Input::get('price');
$product->description=Input::get('description');
$product->image=$image;
$product->save();
Session::flash('message','Data Barang Berhasil Diubah');
return Redirect::to('admin/product');
}
}
44. Sekarang coba anda ubah salah satu data barang
45. Terakhir kita aktifkan fungsi hapus, buka file ProductController.php tambahkan code dalam method delete ( )
46. Coba hapus salah satu data dengan klik simbol tong sampah
Lalu masuk ke file MainActivity.java . Tambahkan 2 fungsi di bawah.
Sekarang kita coba running ulang aplikasi, lalu sentuh Kotak Hijau. Nanti akan tampil form input data. Coba input satu data, lalu sentuh Tombol Simpan.
Buat menu resource seperti cara no 3, namakan dengan context_menu. Kemudian tambahkan 2 item menu seperti gambar di bawah.
Sekarang kita aktifkan context menu untuk memunculkan menu Edit dan Delete. Masuk ke file MainActivity.java . Tambahkan 2 fungsi di bawah.
Daftarkan context menu ke ListView dengan memanggil fungsi registerForContextMenu().
Sekarang coba running kembali , lalu sentuh dan tahan pada data. Nanti akan muncul menu
Tambahkan fungsi hapus pada MainActivity Class, masukkan source code berikut.
public void deletePerson(final int id) {
ApiEndPoint apiEndPoint = ApiClient.getClient().create(ApiEndPoint.class);
Call<StatusResponse> call = apiEndPoint.deleteRequest(id);
call.enqueue(new Callback<StatusResponse>() {
@Override
public void onResponse(Call<StatusResponse> call, Response<StatusResponse> response) {
final StatusResponse StatusResponse = response.body();
if (StatusResponse != null) {
Log.d("Response Data ", "Total Data" + StatusResponse.getStatus());
if (StatusResponse.getStatus()) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "Data Berhasil Dihapus", Toast.LENGTH_SHORT).show();
getAllPerson(generateToken());
}
});
} else {
Toast.makeText(getApplicationContext(), "Data Kosong", Toast.LENGTH_SHORT).show();
}
} else {
Log.d("Login : ", "Data Null");
}
}
@Override
public void onFailure(Call<StatusResponse> call, Throwable t) {
Toast.makeText(getApplicationContext(), "Koneksi Bermasalah", Toast.LENGTH_SHORT).show();
}
});
}
Sekarang kita tambahkan code untuk mengambil data Person Id. Lalu panggil fungsi deletePerson.
Selanjutnya, kita tambahkan code untuk pindah activity, serta mengirim nilai Person Id.
Sekarang coba anda hapus dan ubah data melalui menu. Kalau berhasil, it’s done yea ……
Bulan Ramadhan sebentara lagi datang, apa yang sudah anda persiapkan? Bulan Ramadhan kali ini, Rumah Coding insya Allah akan mengadakan “Workshop Android Spesial Ramadhan”. Terdapat 3 workshop di bulan ramadhan mendatang. Melalui workshop ini, anda akan langsung praktek membuat aplikasi berikut
1. Kamus Arab Indonesia
Hari: Minggu,
Tanggal: 28 Mei 2017
Waktu: 09:00 – 17:00
Biaya: Rp. 100.000
Materi:
– Activity
– Frame Layout
– Google Translator API
– List View
– Card View
– Custom Adapter
– Share Intent
– Realm
2. Jadwal dan Pengingat Shalat
Hari: Kamis,
Tanggal: 1 Juni 2017
Waktu: 09:00 – 17:00
Biaya: Rp. 100.000
Mandelbrot set is a mathematical set of points whose boundary is a distinctive and easily recognizable two-dimensional fractal shape. The Mandelbrot set is defined over the complex number plane. The definition of the Mandelbrot set is simple but the structure of the set is really complex and beautiful.
Mandelbrot Set Overview
Mandelbrot set is defined mathematically as the set of values of c in the complex plane for which the orbit of 0 under iteration of the complex quadratic polynomial zn+1 = zn2 + c remains bounded. That is, a complex number c is part of the Mandelbrot set if, when starting with z0 = 0 and applying the iteration repeatedly, the absolute value of zn remains bounded however large n gets.
Below is the structure of the Mandelbrot set that is generated using our application.
Mandelbrot Set
HTML 5 Canvas Overview
HTML5 is the latest version of the standard HTML. It comes with new cool element, Canvas that allows you to draw directly and manipulate every single pixels in the canvas. A canvas is a rectangular area on an HTML page, and it is specified with the [cci]
We’ll not cover all the definition of cool function in the canvas. There are documentation of those over the web. We only give an attention to several functions that will be used in our tutorial.
Every canvas element has a graphics context that will be used to modify the pixel on the canvas. We’ll use [cci]2d[/cci] context. To get the context, use [cci]getContext[/cci] function of the canvas object.
var canvas = document.getElementById('thecanvas');
var ctx = canvas.getContext('2d');
The above code assumes that we have defined a canvas element which id [cci]thecanvas[/cci].
Our requirement is to get all the pixels data of the canvas and modify the color of the pixels. To get all pixels data, use [cci]getImageData[/cci] function of the context. The function has 4 arguments [cci]x[/cci],[cci]y[/cci],[cci]width[/cci] and [cci]height[/cci]. [cci]x[/cci] and [cci]y[/cci] arguments define the square top left position from which the pixels will be taken. [cci]width[/cci] and [cci]height[/cci] define the dimension of the square.
var imageData = ctx.getImageData(0, 0, 100, 100);
var pixels = imageData.data;
The variable [cci]pixels[/cci] above contains 100×100=10.000 pixels that is save in 1 dimension array. 1 pixels have 4 elements, red,green,blue and alpha component. So [cci]pixels[/cci] variable has 10.000×4 = 40.000 elements. 1 element pixel is an integer from 0 to 255.
We now can modify the pixels data. After the pixels have been modified, we must put the pixels back to canvas in order to our modification takes effect.
ctx.putImageData(imageData, 0, 0);
Drawing Mandelbrot Set on HTML 5 Canvas
Javascript doesn’t provides built in complex number data type. So, we have to define our complex number data type. For simplicity of the tutorial, we will represent any complex number in javascript object with two properties. The [cci]x[/cci] property represents the real part and [cci]y[/cci] property represents the imaginary part.
//define complex data type
var Complex = function(x, y) {
this.x = x; // real part
this.y = y; // imaginary part
};
//define new complex number 1+2i
var complex = new Complex(1,2);
We have now a simple complex number data type for our application. Before we start to code, remember from above explanation. The mandelbrot definition requires to use two operation on complex number. We’ll not define all number operations in complex number, but we’ll create only two operations, multiplication and addition that will be used in generating mandelbrot set.
//define two complex number
var a = 1, b = 2, c = 3, d = 4;
var complex1 = new Complex(a,b);
var complex1 = new Complex(c,d);
//add complex1 and complex1 will result
var addition = new Complex(a+c, b+d);
//multiply complex1 and complex 2 will result
var multiplication = new Complex(a*c - b*d, b*c + a*d);
The Mandelbrot Set Drawing Algorithm
We’ll use different approach from mandelbrot set definition to visualize the set. Rather than finding all complex numbers [cci]c[/cci] which is bounded, our goal is to colorize all of the pixels in the canvas based on number of iterations. This will result great visualization for mandelbrot set.
Step by Step Mandelbrot Set Drawing
Define user interface. Our application will has simple user interface. It’ll contains color scheme selection box, a button and the canvas.
Mandelbrot Generator Simple User Interface
Below is HTML tags that defines our simple user interface.
After the html page is loaded, immediately we call javascript function [cci]setupCanvas[/cci]. This function will checks whether the browser support html5 canvas then get canvas’s drawing context and save it as global variable [cci]ctx[/cci]. We’ll use the context to modify each pixels on the canvas.
Define [cci]setupCanvas[/cci] function.
var setupCanvas = function() {
canvas = document.getElementById('thecanvas');
setupMouseListener();
if (!canvas.getContext) {
alert("I'm sorry, seems your browser not support HTML 5, try another browser.");
return;
}
// get drawing context
ctx = canvas.getContext('2d');
};
Define render function.
In this function we get the selected color scheme in the selection box. Save the canvas size as global variables then define the scaling ratio from canvas coordinats to mandelbrot coordinats.
var render = function() {
if (!canvas.getContext) return;
//get color scheme
var a = document.getElementById('scheme');
colorScheme = parseInt((a.value || a.options[a.selectedIndex].value));
//save canvas size into variable
cw = canvas.width;
ch = canvas.height;
//define scaling ratio from canvas coordinat to mandlebort coordinat
scaleX = (mx[1] - mx[0])/cw;
scaleY = (my[1] - my[0])/ch;
drawMandlebrot();
};
Define the [cci]drawMandelbrot[/cci] function.
In this function, we iterate to each pixels in the canvas and find the iteration for each pixels then color the pixel based on number iterations.
var drawMandlebrot = function() {
if(isDrawing) return;
isDrawing = true;
var imageData = ctx.getImageData(0, 0, cw, ch);
pixels = imageData.data;
for(var x = 0; x < cw; x++) {
for(var y = 0; y < ch; y++) {
iteration = 0;
// scale canvas coordinat to mandlebrot complex coordinat
var x0 = scaleX*x + mx[0], y0 = scaleY*y + my[0];
// define complex number c
var c = new Complex(x0, y0), z = new Complex(0, 0);
while(iteration < maxIteration) { // check if z still inbound if(z.x*z.x + z.y*z.y >= 2*2) {
break;
}
// multiply z and z
z = new Complex(z.x*z.x - z.y*z.y, z.y*z.x + z.x*z.y);
// add z and c
z = new Complex(z.x+c.x, z.y+c.y);
// inrease iteration
iteration++;
}
// colorize current pixel
setPixelColor(x, y, iteration);
}
}
ctx.putImageData(imageData, 0, 0);
isDrawing = false;
};
Define [cci]setPixelColor[/cci]
This function will color the current pixels and get the color from [cci]getColor[/cci] function. [cci]getColor[/cci] function will generate a color based on number of iteration and selected color scheme.
var getColor = function(i) {
i /= maxIteration;
var cr = 0.0;
var cg = 0.0;
var cb = 0.0;
switch(colorScheme) {
case 1:
if (i >= 0.66) cr = i;
else if (i >= 0.33) cg = i;
else cb = i;
break;
case 2:
if (i >= 0.66) cr = i;
else if (i >= 0.33) cb = i;
else cg = i;
break;
case 3:
if (i >= 0.66) cb = i;
else if (i >= 0.33) cg = i;
else cr = i;
break;
case 4:
if (i >= 0.66) cg = i;
else if (i >= 0.33) cr = i;
else cb = i;
break;
case 5:
if (i >= 0.66) cg = i;
else if (i >= 0.33) cb = i;
else cr = i;
break;
case 6:
if (i >= 0.66) cb = i;
else if (i >= 0.33) cr = i;
else cg = i;
break;
};
var r = parseInt(cr * 3 * maxColor);
var g = parseInt(cg * 3 * maxColor);
var b = parseInt(cb * 3 * maxColor);
return [r, g, b];
};
var setPixelColor = function(x, y, i) {
var c = getColor(i);
var off = 4 * (y * cw + x);
pixels[off] = c[0]; //red
pixels[off + 1] = c[1]; //green
pixels[off + 2] = c[2]; //blue
pixels[off + 3] = 255; //alpha
};
Finally, add the zoom capability.
var mouseWheelHandler = function(e) {
// cross-browser wheel delta
var e = window.event || e; // old IE support
// get delta scroll
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
//get mouse position
var mousePos = getMousePos(e);
// scale canvas coordinat to mandlebrot complex coordinat
var x0 = scaleX*mousePos.x + mx[0], y0 = scaleY*mousePos.y + my[0];
//scale the mandelbrot coordinat size
var scale = 1 - delta*zoomScale;
var sizeX = (mx[1]-mx[0])*scale;
var sizeY = (my[1]-my[0])*scale;
// redefine mandelbrot boundaries
mx = [x0-sizeX/2, x0+sizeX/2];
my = [y0-sizeY/2, y0+sizeY/2];
render();
};
var getMousePos = function(evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
};
Async Task is an android helper class that will allows you to run a background processes. If you are a Java programmer, may be you are familiar with thread. If you run a long task in the main thread, the current user interface will be blocked untill the task has finished. This is not a good practice. To avoid the user interface is being blocked, the long task must be perform in another thread.
Async Task Overview
In android, the only thread that can modify the user interface is called UI thread. This is means you can’t modify user interface from another thread. This is a problem, because in another side, we need to run a long task in separate thread and also we need to update the user interface to display the task progress. Actually, android provides a [cci]Handler[/cci] class that allows you to update the user interface from another thread. But we’ll discuss it in the next tutorial.
Rather than create new thread and handler, android has provides a helper class, [cci]AsyncTask[/cci], to do the same thing. The concept is same, [cci]AsyncTask[/cci] is a smart helper that encapsulates the creation of thread and handler.
[cci]AsyncTask[/cci] must be subclassed to be used. There are three methods that need to be overridden, [cci]doInbackground[/cci], [cci]onProgressUpdate[/cci] and [cci]onPostExecute[/cci]. The first method is mandatory to be overriden, the rest are optional.
[cci]doInbackground[/cci] is a method where the execution codes is placed. [cci]doProgressUpdate[/cci] and [cci]onPostExecute[/cci] run in UI thread, so user interface can be modified in both of methods. Put any codes for displaying the task progress on [cci]doProgressUpdate[/cci]. The [cci]doPostExecute[/cci] method will be called once the task has finished.
[cci]AsyncTask[/cci] is a generic class. [cci]AsyncTask[/cci] is subclassed in the form [cci]AsyncTask<Params, Progress, Result>[/cci].
[cci]Params[/cci], the type of the parameters sent to the task upon execution.
[cci]Progress[/cci], the type of the progress units published during the background computation.
[cci]Result[/cci], the type of the result of the background computation.
To give a better understanding, a sample application that use [cci]AsyncTask[/cci] will be given.
Creating Sample Application
We’ll create a sample application to demonstrate the use of [cci]AsyncTask[/cci] class to perform background processes. Our goal is to create a simple application which download a file from server and display the download progress in the progress bar.
Our application have very simple user interface that only contains a progress bar and a button.
AsyncTask Simple Application
If user click Start Button above, the application will start download a file from server and display the progress in progress bar. After the download process has completed, the file is saved into android root folder (/sdcard).
In this demonstration, I will use a file located on my server, http://semurjengkol.com/dl/files/CustomArrayAdapter.rar(445KB), this is an eclipse project from previous tutorial. You can also use this file or change the url as you want.
Now, open your Eclipse IDE and create new Android Application Project, then follow step by step below:
Create new layout file [cci]res/layout/activity_main.xml[/cci]
This file defines the application main layout which contain a progress bar and a button.
Create new java class [cci]src/DownloadListener.java[/cci]
This is a listener that will be used by [cci]AsyncTask[/cci] to communicate with activity to change the user interface.
package com.sj.asynctask;
import java.io.File;
public interface DownloadListener {
public void onDownloadComplete(File filename);
public void onProgressUpdate(int progress);
public void onDownloadFailure(final String msg);
}
Create new java class [cci]src/DownloadTask.java[/cci]
This file extends [cci]AsyncTask[/cci] and will do the download task and call the listener to display the progress result. The [cci]doInBackground[/cci] method retrieves two string parameters:
URL of the file to be downloaded
The destination storage location to save the file
package com.sj.asynctask;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import android.os.AsyncTask;
import android.os.Environment;
public class DownloadTask extends AsyncTask<String, Integer, Boolean> {
/** This is our listener*/
private final DownloadListener listener;
/** Hold message if download failure*/
private String msg;
/** Save Destination */
private File saveTo;
public DownloadTask(DownloadListener listener) {
this.listener = listener;
}
@Override
protected Boolean doInBackground(String... params) {
/** Params should be array of string with length 2.
* 1. url
* 2. filename destination*/
if(params == null || params.length < 2) {
msg = "Incomplete parameters";
return false;
}
String sUrl = params[0];
String filename = params[1];
/** get root directory: /sdcard */
File rootDir = Environment.getExternalStorageDirectory();
/** create destination file*/
saveTo = new File(rootDir, filename);
try {
/** define url*/
URL url = new URL(sUrl);
/** open the connection*/
URLConnection conn = url.openConnection();
conn.connect();
/** get the size of file that will be downloaded. It will be used to measure the progress*/
int fileLength = conn.getContentLength();
/** create input and outpout stream*/
InputStream is = new BufferedInputStream(url.openStream());
OutputStream os = new FileOutputStream(saveTo);
/** create buffer*/
byte buffer[] = new byte[512];
/** hold total of downloaded bytes*/
long totalDownloaded = 0;
int count;
while ((count = is.read(buffer)) != -1) {
totalDownloaded += count;
/**cause call to onProgressUpdate, which is run on UI thread*/
publishProgress((int) (totalDownloaded * 100 / fileLength));
os.write(buffer, 0, count);
}
/** closing stream*/
os.flush();
os.close();
is.close();
return true;
}
catch (MalformedURLException e) {
msg = "Invalid URL";
}
catch (IOException e) {
msg = "No internet connection";
}
return false;
}
@Override
protected void onProgressUpdate(Integer... values) {
if(listener != null) listener.onProgressUpdate(values[0]);
}
@Override
protected void onPostExecute(Boolean result) {
if(!result) {
if(listener != null) listener.onDownloadFailure(msg);
return;
}
if(listener != null) listener.onDownloadComplete(saveTo);
}
}
Create main activity [cci]src/MainActivity.java[/cci]
This is our main activity that will inflate the [cci]res/layout/activity_main.xml[/cci] to build our main user interface. The activity will create and execute [cci]DownloadTask[/cci] object when Start Button is clicked. Our activity also implements the [cci]DownloadListener[/cci] and set itself as a listener to [cci]DownloadTask[/cci] object. The [cci]DownloadTask[/cci] object will call the listener method implementation in the activity when the progress updated, download failure and when download completed.
Adding permission to [cci]AndroidManifest.xml[/cci]
This simple application has two main features:
Connecting to internet to download a file
Save the file into sdcard storage
In order to our application runs well, we must add [cci]uses-permission[/cci] in our [cci]AndroidManifest.xml[/cci] related to above features. Add the following lines into [cci]AndroidManifest.xml[/cci]:
List View is an element that displays a collection of items in single column direction. It has an internal vertical scroll bar that enable user to scroll if it’s height bigger than display height. The type of single item in the list is any of java object.
[cci]ListView[/cci] needs an adapter to works. This adapter behaves as a data resources for the list. The adapter also defines how each items in the list is displayed. The adapter is attached to the list via [cci]setAdapter[/cci] method on the [cci]ListView[/cci] object. There are two commons used adapters:
Array Adapter: An adapter that is designed to work with arrays data resources.
Cursor Adapter: An adapter that is designed to handle database related data.
This tutorial will focuses on array adapter.
Simple Array Adapter
A simple array adapter is an array adapter that is built using array of string as items. The array of string is passed to the constructor of [cci]ArrayAdapter[/cci] object.
List<String> apps = new ArrayList<String>();
apps.add("Twitter");
apps.add("Whatsapp");
apps.add("Facebook");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, apps);
The constructor of array adapter have 3 arguments:
context: this is the application context
layout resource id: the layout resource id for item view
array items: this is array object for items
We will attach the created adapter into the list by using [cci]setAdapter[/cci] method on [cci]ListView[/cci] object.
List Activity
[cci]ListActivity[/cci] is a subclass of [cci]Activity[/cci] that will make our work with [cci]ListView[/cci] easier. [cci]ListActivity[/cci] has internal implementation method that is related to [cci]ListView[/cci]. You must have list view object with id is [cci]android:id/list[/cci] in the layout file to use List Activity.
Now we will create a sample list view application using simple array adapter. Open your Eclipse IDE and create new android project by selecting menu: File -> New -> Android Application Project. Fill out required fields.
Run your project, your list view will be displayed like image below:
Simple Android List View
Customize Array Adapter
By default, array adapter displays a [cci]TextView[/cci] for each items and set the text of it by calling [cci]toString[/cci] method of item object. We can customize the default display of array adapter by overriding [cci]getView[/cci] method.
For a demo, we will modify previous project and use custom array adapter:
Create new java class: [cci]Application.java[/cci].
This class represents a single object of list item.
package com.sj.customlistview;
public class Application {
private String title;
private long totalDl;
private int rating;
private String icon;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public long getTotalDl() {
return totalDl;
}
public void setTotalDl(long totalDl) {
this.totalDl = totalDl;
}
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
}
Create new xml file: [cci]app_custom_list.xml[/cci]
This file defines a view for list item