Senin, 03 November 2014

Asynctask Sederhana



Asyntask Sederhana

            Dibawah ini merupakan contoh program android yang mengimplementasikan AsyncTask dan ProgressBar pada android. User akan memilih sebuah file dari media penyimpanan, kemudian file tersebut akan dikirimkan ke AsyncTask untuk di baca (pembacaan file dilakukan pada background thread). Pada saat file sedang dibaca, AsyncTask akan mengirimkan kemajuan dari pembacaan file ke UI thread dan menampilkannya melalui ProgressBar. Setelah file selesai di baca atau proses pembacaan file di batalkan, secara otomatis progressbar akan menghilang, kemudian hasil dari operasi akan ditampilkan melalui TextView (lama operasi dan status operasi yang terjadi di background). Berikut adalah source code dari file HelloWorldActivity.java:
package com.example.helloworld;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;

import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.example.asyntask.R;

public class HelloWorldActivity extends ActionBarActivity {

       private static final int REQ_CODE = 0;
       private ReadTask tasker;

       @Override
       protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_hello_world);

              if (savedInstanceState == null) {
                     getSupportFragmentManager().beginTransaction()
                                  .add(R.id.container, new PlaceholderFragment()).commit();
              }
       }

       public void cancelButton(View v) {

              // check is there any task that can be aborted
              if (tasker.getStatus() == AsyncTask.Status.RUNNING
                           || tasker.getStatus() == AsyncTask.Status.PENDING) {

                     // abort the task
                     tasker.cancel(true);
              }
       }

       /** AsyncTask class used for reading a file <Params, Progress, Result> */
       private class ReadTask extends AsyncTask<String, Integer, String> {

              // private String data;
              private String time;
              private int progressStatus;
              ProgressBar bar;
              TextView barPercent;
              Button openButton;
              Button cancelButton;
              TextView tv1;
              TextView tv2;

              @Override
              protected void onPreExecute() {
                     super.onPreExecute();

                     // initial the Views
                     bar = (ProgressBar) findViewById(R.id.progressbar);
                     barPercent = (TextView) findViewById(R.id.barPercent);
                     openButton = (Button) findViewById(R.id.openButton);
                     cancelButton = (Button) findViewById(R.id.cancelButton);
                     tv1 = (TextView) findViewById(R.id.textView1);
                     tv1.setText("Elapsed: ");
                     tv2 = (TextView) findViewById(R.id.textView2);
                     tv2.setText("Status: ");

                     // disable openButton
                     openButton.setEnabled(false);

                     // show the Views
                     bar.setVisibility(View.VISIBLE);
                     barPercent.setVisibility(View.VISIBLE);
                     cancelButton.setVisibility(View.VISIBLE);

                     progressStatus = 0;
                     bar.setProgress(progressStatus);
                     barPercent.setText("Reading... 0%");
              }

              @Override
              protected String doInBackground(String... params) {
                     // TODO Auto-generated method stub
                     File file = new File(params[0]);
                     int length = (int) file.length();
                     int i = 0;

                     InputStream in = null;
                     byte[] buffer = new byte[8192];
                     try {
                           in = new BufferedInputStream(new FileInputStream(file));
                           long start = System.currentTimeMillis();
                           while ((i = in.read(buffer)) != -1) {

                                  // temp[j++] = (byte) i;

                                  progressStatus += i;

                                  // update the progressbar
                                  publishProgress((int) ((progressStatus / (float) length) * 100));

                                  // Escape early if cancel() is called
                                  if (isCancelled())
                                         break;

                           }
                           // data = byteToString(temp).toString();
                           time = ((System.currentTimeMillis() - start) + "ms").toString();

                     } catch (FileNotFoundException ex) {
                           ex.printStackTrace();
                           time = ex.getMessage();
                     } catch (IOException ex) {
                            // TODO Auto-generated catch block
                           ex.printStackTrace();
                           time = ex.getMessage();
                     } finally {
                           if (in != null) {
                                  try {
                                         in.close();
                                  } catch (IOException e) {
                                         // TODO Auto-generated catch block
                                         e.printStackTrace();
                                         time = e.getMessage();
                                  }
                           }
                     }
                     return time;
              }

              @Override
              protected void onProgressUpdate(Integer... progress) {
                     super.onProgressUpdate(progress);

                     // bar.incrementProgressBy(progress[0]);

                     bar.setProgress(progress[0]);
                     barPercent.setText("Reading... " + progress[0] + "%");
              }

              @Override
              protected void onCancelled() {
                     super.onCancelled();

                     results("-", "Cancelled");
              }

              @Override
              protected void onPostExecute(String result) {
                     super.onPostExecute(result);

                     results(result, "Finished");
              }

              void results(String e, String s) {

                     // clean up the Tasker
                     tasker = null;

                     // enable the openButton
                     openButton.setEnabled(true);

                     // close the Views
                     bar.setVisibility(View.GONE);
                     barPercent.setVisibility(View.GONE);
                     cancelButton.setVisibility(View.GONE);

                     // update the TextView1 and TextView2
                     tv1.setText("Elapsed: " + e);
                     tv2.setText("Status: " + s);
              }


       }

       boolean gotStatus() {

              if (tasker == null || tasker.getStatus() == AsyncTask.Status.PENDING
                           || tasker.getStatus() == AsyncTask.Status.FINISHED) {

                     // initial the Tasker
                     tasker = new ReadTask();

                     return true;
              }
              if (tasker.getStatus() == AsyncTask.Status.RUNNING) {

                     return false;
              }

              return false;
       }

       /** called when button "Open a File" clicked */
       public void openFile(View v) {

              if (gotStatus()) {

                     Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                     intent.setType("*/*");
                     intent.addCategory(Intent.CATEGORY_OPENABLE);

                     try {
                           startActivityForResult(
                                         Intent.createChooser(intent, "Select a file"), REQ_CODE);
                     } catch (android.content.ActivityNotFoundException ex) {
                           Toast.makeText(getBaseContext(), "You a need a File Manager",
                                         Toast.LENGTH_LONG).show();
                           ex.printStackTrace();
                     }
              } else {
                     Toast.makeText(HelloWorldActivity.this, "Task is still Running",
                                  Toast.LENGTH_LONG).show();
              }
       }

       @Override
       protected void onActivityResult(int reqCode, int resultCode, Intent data) {

              switch (reqCode) {
              case REQ_CODE:
                     if (resultCode == RESULT_OK) {

                           // get Uri data from intent
                           Uri uri = data.getData();

                           String path = null;
                           try {

                                  // convert Uri to file path (String)
                                  path = getPath(getBaseContext(), uri);

                                  // send the task to the AsyncTask
                                  tasker.execute(path);

                           } catch (URISyntaxException e) {
                                  // TODO Auto-generated catch block
                                  e.printStackTrace();
                           }
                     }
              }
       }

       private static String getPath(Context context, Uri uri)
                     throws URISyntaxException {
              if ("content".equalsIgnoreCase(uri.getScheme())) {
                     String[] projection = { "_data" };
                     Cursor cursor = null;

                     try {
                           cursor = context.getContentResolver().query(uri, projection,
                                         null, null, null);
                           int column_index = cursor.getColumnIndexOrThrow("_data");
                           if (cursor.moveToFirst()) {
                                  return cursor.getString(column_index);
                           }
                     } catch (Exception e) {
                           e.printStackTrace();
                     }
              } else if ("file".equalsIgnoreCase(uri.getScheme())) {
                     return uri.getPath();
              }

              return null;
       }

       @Override
       public boolean onCreateOptionsMenu(Menu menu) {

              // Inflate the menu; this adds items to the action bar if it is present.
              getMenuInflater().inflate(R.menu.hello_world, menu);
              return true;
       }

       @Override
       public boolean onOptionsItemSelected(MenuItem item) {

              int id = item.getItemId();
              if (id == R.id.action_settings) {
                     return true;
              }
              return super.onOptionsItemSelected(item);
       }

       public static class PlaceholderFragment extends Fragment {

              public PlaceholderFragment() {
              }

              @Override
              public View onCreateView(LayoutInflater inflater, ViewGroup container,
                           Bundle savedInstanceState) {
                     View rootView = inflater.inflate(R.layout.fragment_main, container,
                                  false);
                     return rootView;
              }
       }
}

Kemudian pada file activity_hello_world.xml ubah source code menjadi seperti berikut:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.helloworld.HelloWorldActivity"
    tools:ignore="MergeRootFrame" />

Kemudian buat file fragment_main.xml, contoh source code adalah sebagai berikut:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.me.asynctaskprogressbarsample.MainActivity$PlaceholderFragment" >

    <Button
        android:id="@+id/openButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:onClick="openFile"
        android:text="Open a File" />

    <LinearLayout
        android:id="@+id/linear"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/openButton"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="Elapsed: " />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="Status: " />
    </LinearLayout>

    <ProgressBar
        android:id="@+id/progressbar"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/linear"
        android:layout_below="@id/linear"
        android:visibility="invisible" />

    <TextView
        android:id="@+id/barPercent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/linear"
        android:layout_below="@id/progressbar"
        android:visibility="invisible" />

    <Button
        android:id="@+id/cancelButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/barPercent"
        android:layout_centerHorizontal="true"
        android:onClick="cancelButton"
        android:text="Cancel"
        android:visibility="invisible" />

</RelativeLayout>







Setelah selesai semuanya maka ini adalah beberapa screenshot dari aplikasi ini:

setelah klik open a file, maka akan muncul document yang akan dipilih