07/09/2018, 16:53

Chủ để AsyncTask Cơ bản

AsyncTask là một lớp trừu tượng được cung cấp bởi Android, giúp chúng ta sử dụng các thread UI đúng. Lớp này cho phép chúng tôi thực hiện các hoạt động dài / nền và hiển thị kết quả của nó trên thread UI mà không cần phải thao tác đề. Android thực hiện mô hình chủ đề duy nhất và bất cứ khi nào ...

AsyncTask là một lớp trừu tượng được cung cấp bởi Android, giúp chúng ta sử dụng các thread UI đúng. Lớp này cho phép chúng tôi thực hiện các hoạt động dài / nền và hiển thị kết quả của nó trên thread UI mà không cần phải thao tác đề.

Android thực hiện mô hình chủ đề duy nhất và bất cứ khi nào một ứng dụng Android được tung ra, một thread được tạo ra. Giả sử chúng ta đang làm mạng lưới hoạt động trên một nút bấm trong ứng dụng của chúng tôi. Mở nút bấm một yêu cầu sẽ được thực hiện cho các máy chủ và phản ứng sẽ được chờ đợi. Do mô hình chủ đề duy nhất của Android, cho đến khi thời gian đáp ứng được chờ đợi màn hình của chúng tôi là không đáp ứng. Vì vậy, chúng ta nên tránh thực hiện các hoạt động dài chạy trên thread UI. Điều này bao gồm tập tin và truy cập mạng.

Để khắc phục điều này chúng ta có thể tạo chủ đề mới và thực hiện các phương pháp chạy để thực hiện cuộc gọi mạng này, do đó, giao diện người dùng vẫn đáp ứng.

Nhưng kể từ khi Android theo mô hình chủ đề duy nhất và Android UI bộ công cụ không phải là thread an toàn, vì vậy nếu có một nhu cầu để thực hiện một số thay đổi về giao diện người dùng dựa trên các kết quả của các hoạt động biểu diễn, sau đó cách tiếp cận này có thể dẫn đến một số vấn đề.

Vì vậy, các khuôn khổ Android đã đưa ra một mô hình rất tốt được bao bọc vào AsyncTask.

Lưu ý: AsyncTask lý tưởng nên được sử dụng cho các hoạt động mà phải mất vài giây. Một số nhiệm vụ giữ cho thread chạy trong thời gian dài như vậy trong trường hợp đó nó được khuyến khích để sử dụng gói java.util.concurrent như Executor, ThreadPoolExecutor và FutureTask.

doInBackground: Mã thực hiện hoạt động dài chạy đi trong phương pháp này. Khi phương thức onClick được thực thi trên nhấp nút, nó gọi phương thức mà chấp nhận các thông số thực hiện và tự động gọi phương thức doInBackground với các thông số thông qua.

onPostExecute: Phương thức này được gọi là phương thức sau doInBackground hoàn thành xử lý. Kết quả từ doInBackground được truyền cho phương thức này.

onPreExecute: Phương thức này được gọi là trước khi phương thức doInBackground được gọi.

onProgressUpdate: Phương thức này được gọi bằng cách gọi publishProgress bất cứ lúc nào từ doInBackground gọi phương thức này.

Các nhiệm vụ có thể được hủy bỏ bằng cách gọi hủy bỏ (boolean) phương thức.
Điều này sẽ gây ra các cuộc gọi tiếp theo để isCancelled () để trở về đúng.

Sau khi gọi phương pháp này, onCancelled (Object) phương thức được gọi là thay vì onPostExecute () sau khi doInBackground () trả về.

Trong ứng dụng mẫu này, tôi chỉ cần thực hiện quá trình ngủ trong một khoảng thời gian thay vì làm mạng lưới hoạt động. (Chỉ cần để giải thích các khái niệm về AsyncTask. Đây không phải là một ứng dụng thời gian thực).

Trong người sử dụng giao diện người dùng chủ đề vào một giá trị (thời gian tính bằng giây milli) sẽ được thông qua để AsyncTaskRunner.

AsyncTaskRunner là một lớp học riêng mà kéo dài AsyncTask.

package com.example.asynctaskdemo;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {
 private Button button;
 private EditText time;
 private TextView finalResult;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  time = (EditText) findViewById(R.id.et_time);
  button = (Button) findViewById(R.id.btn_do_it);
  finalResult = (TextView) findViewById(R.id.tv_result);
  button.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    AsyncTaskRunner runner = new AsyncTaskRunner();
    String sleepTime = time.getText().toString();
    runner.execute(sleepTime);
   }
  });
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.activity_main, menu);
  return true;
 }

 private class AsyncTaskRunner extends AsyncTask<String, String, String> {

  private String resp;

  @Override
  protected String doInBackground(String... params) {
   publishProgress("Sleeping..."); // Calls onProgressUpdate()
   try {
    // Do your long operations here and return the result
    int time = Integer.parseInt(params[0]);
    // Sleeping for given time period
    Thread.sleep(time);
    resp = "Slept for " + time + " milliseconds";
   } catch (InterruptedException e) {
    e.printStackTrace();
    resp = e.getMessage();
   } catch (Exception e) {
    e.printStackTrace();
    resp = e.getMessage();
   }
   return resp;
  }

  /*
   * (non-Javadoc)
   *
   * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
   */
  @Override
  protected void onPostExecute(String result) {
   // execution of result of Long time consuming operation
   finalResult.setText(result);
  }

  /*
   * (non-Javadoc)
   *
   * @see android.os.AsyncTask#onPreExecute()
   */
  @Override
  protected void onPreExecute() {
   // Things to be done before execution of long running operation. For
   // example showing ProgessDialog
  }

  /*
   * (non-Javadoc)
   *
   * @see android.os.AsyncTask#onProgressUpdate(Progress[])
   */
  @Override
  protected void onProgressUpdate(String... text) {
   finalResult.setText(text[0]);
   // Things to be done while execution of long running operation is in
   // progress. For example updating ProgessDialog
  }
 }
}

Khi sử dụng asysntask mà luồng thread của app bị tác động bên ngoài tác động ví dụ như context , fragment ... bị thoát hoặc chết hoặc có thể UI nhảy sang một luồng dữ liệu khác cách cancel hoăc huỷ asystask đó đi chúng ta có thể thực hiện bằng phương pháp như sau .

private WeakReference<Fragment> weakReferenceFragment;
private WeakReference<Context> weakReferenceContext;

private boolean isCancelAsyntask(){
    if(weakReferenceFragment.get() == null||weakReferenceContext.get() ==null||isCancelled()){
    return false;
    }
    return true;
}

@Override
  protected String doInBackground(String... params) {
   if(!isCancelAsyntask()){
         return "" ;
   }
   // to do...
   return resp;
  }

  @Override
  protected void onPostExecute(String result) {
   // execution of result of Long time consuming operation
     if(!isCancelAsyntask()||TextUtils.isEmpty(result)){
         return ;
     }
     // to do...
  }

Bài viết về những phần cơ bản về AsyncTask mình mong được sự đánh giá của các bạn .

0