MultiThreading: AsyncTask Multiple parameters – return multiple value

MultiThreading là gì

MultiThreading được sử dụng để xử lý các tác vụ chạy song song với nhau và giúp quá trình tương tác của người dùng với ứng dụng không bị gián đoạn. Khi một ứng dụng được start lên sẽ có một Thread được gọi là Main Thread hay UI Thread được chạy. Từ Thread này chúng ta có thể tạo ra những Thread khác để làm những tác vụ chiếm nhiều thời gian. Nếu chúng ta cố tình xử lý những tác vụ này trên UI Thread mà không tạo ra Thread khác có thể dẫn tới làm đơ UI và crash ứng dụng.

Những trường hợp nên sử dụng MultiThreading.

  •  Thao tác với hệ thống mạng (network).
  •  Đọc, ghi file…

Sử dụng AsyncTask trong Android

Class AsyncTask có các phương thức chính như sau:

onPreExecute

Là phương thức được chạy đầu tiên khi task được bắt đầu. Phương thức này làm việc trên UI Thread.

doInBackground

Là phương thức chạy background thực hiện tác vụ nào đó. Phương thức này chạy trên Background Thread vì thế chúng ta không được update giá trị lên UI trong phương thức này.

onPostExecute

Là phương thức được gọi ngay sau khi phương thức doInBackground kết thúc. Đối số của phương thức này chính là kết quả return từ phương thức doInBackground. Phương thức này làm việc trên UI Thread.

Ba đối số mà khi chúng ta tạo class extends từ AsyncTask là:

AsyncTask<Params, Progress, Result>

Param

Là kiểu của đối số được truyền vào phương thức doInBackground.

Progress

Là kiểu biến dùng để update giá trị trong quá tình doInBackground chạy. Giá trị này được truyền vào phương thức onProgressUpdate.

Result

Là kiểu trả về của phương thức doInBackground và là kiểu của đối số của phương thức onPostExcute.

———————————

Ở Bài viết này mình sẽ  sử dụng AsyncTask với nhiều giá trị truyến vào và trả về kết quả nhiều giá trị:

1.Đầu tiên tạo một class để lưu trữ các giá trị truyền vào như sau:

private  class MyParam {
        Bitmap bm;
        int requestCode;

        public MyParam(Bitmap bm, int requestCode) {
            this.bm = bm;
            this.requestCode = requestCode;
        }
    }

Asynctask nhận vào 2 giá trị là bm kiểu BitmapRequestCode kiểu Int.

2. Tạo một Class dùng để nhận kết quả trả về như sau:

  private class Result
    {
        Uri uri;
        int requestCode;
    }

AsyncTask này sẽ trả về 2 kết quả là 1 Uri và  1 requestCode.

3. Tạo Class AsynTask gọi hàm SaveImage và giá trị trả về là Uri kèm theo một requestCode để xử lý.

 private class SaveImageAsyncTask extends AsyncTask<MyParam, Void, Result> {

        @Override
        protected Result doInBackground(MyParam... myParams) {
            //Lấy các Param đã truyền vào.
            Bitmap bm = myParams[0].bm;
            int requestCode = myParams[0].requestCode;
            Result result = new Result();
            result.uri = presenter.saveImageCrop(bm);
            result.requestCode = requestCode;
            return result;
        }

        @Override
        protected void onPostExecute(Result result) {
            super.onPostExecute(result);
            //Kết quả trả về được xử lý tại đây.
            listUriImage.put(result.requestCode,result.uri);
        }
    }

4. Thực thi AsyncTask như sau:

Tạo mới đối tượng MyParam  và tiến hành execute AsyncTask.

 MyParam myParam = new MyParam(bm,requestCode);
 SaveImageAsyncTask  saveImageAsyncTask = new SaveImageAsyncTask();
 saveImageAsyncTask.execute(myParam);

Note: Hàm Save Image cho bạn nào cần:

//Lưu image tạm thời
    public Uri saveImageCrop(Bitmap bm){
        OutputStream fOut = null;
        Uri outputFileUri = null;
        try {
            File root = new File(Environment.getExternalStorageDirectory()
                    + File.separator + "androidcoban" + File.separator);
            root.mkdirs();
            Random random = new Random();
            String imageNameForSDCard = "image_" + String.valueOf(random.nextInt(100)) + System.currentTimeMillis() + ".jpg";
            File sdImageMainDirectory = new File(root, imageNameForSDCard);
            outputFileUri = Uri.fromFile(sdImageMainDirectory);
            fOut = new FileOutputStream(sdImageMainDirectory);
        } catch (Exception e) {
          //  Toast.makeText(activity, "Error occured. Please try again later.",
            //        Toast.LENGTH_SHORT).show();
        }
        try {
            bm.compress(Bitmap.CompressFormat.PNG, 80, fOut);
            fOut.flush();
            fOut.close();
        } catch (Exception e) {
        }
        return outputFileUri;
    }

Lý thuyết được tham khảo bên eitguide.com .
Code được thực hiện bởi Blog androidcoban.com

Nguyễn Linh

Chia sẻ để cùng tiến bộ...

Bình luận đã bị khoá.