Ví dụ về AsyncTask Android


680

Tôi đã đọc về AsyncTask, và tôi đã thử chương trình đơn giản dưới đây. Nhưng nó dường như không hoạt động. Làm thế nào tôi có thể làm cho nó hoạt động?

public class AsyncTaskActivity extends Activity {

    Button btn;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener((OnClickListener) this);
    }

    public void onClick(View view){
        new LongOperation().execute("");
    }

    private class LongOperation extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... params) {
            for(int i=0;i<5;i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed");
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
        }

        @Override
        protected void onPreExecute() {
        }

        @Override
        protected void onProgressUpdate(Void... values) {
        }
    }
}

Tôi chỉ cố gắng thay đổi nhãn sau 5 giây trong quá trình chạy nền.

Đây là tệp chính của tôi :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical" >
    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:indeterminate="false"
        android:max="10"
        android:padding="10dip">
    </ProgressBar>
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Progress" >
    </Button>
    <TextView android:id="@+id/output"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Replace"/>
</LinearLayout>

1
ngoài ra, bạn có thể hiển thị tiến trình bằng cách gọi PublishproTHER () từ phương thức doInBackground ().
osum

3
đây là ví dụ asynctask Ví dụ AsyncTask
Samir Mangroliya

đây là một ví dụ AsyncTask tải hình ảnh quá: android-ios-tutorials.com/182/...
Houcine

AsyncTask - Mẫu thiết kế: stackoverflow.com/questions/5058661/
Kẻ

3
ví dụ đơn giản ... Bạn phải đọc liên kết
c49

Câu trả lời:


702

Ok, bạn đang cố gắng truy cập GUI thông qua một luồng khác. Điều này, trong chính, không phải là thực hành tốt.

AsyncTask thực thi mọi thứ doInBackground()bên trong một luồng khác, không có quyền truy cập vào GUI nơi chế độ xem của bạn.

preExecute()postExecute()cung cấp cho bạn quyền truy cập vào GUI trước và sau khi quá trình tải nặng xảy ra trong luồng mới này và thậm chí bạn có thể chuyển kết quả của thao tác dài postExecute()để sau đó hiển thị bất kỳ kết quả xử lý nào.

Xem những dòng này nơi bạn sẽ cập nhật TextView sau này:

TextView txt = findViewById(R.id.output);
txt.setText("Executed");

Đặt chúng vào onPostExecute().

Sau đó, bạn sẽ thấy văn bản TextView của mình được cập nhật sau khi doInBackgroundhoàn thành.

Tôi nhận thấy rằng trình nghe onClick của bạn không kiểm tra xem Chế độ xem nào đã được chọn. Tôi thấy cách dễ nhất để làm điều này là thông qua các câu lệnh chuyển đổi. Tôi có một lớp hoàn chỉnh được chỉnh sửa dưới đây với tất cả các đề xuất để tiết kiệm sự nhầm lẫn.

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.System;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;

public class AsyncTaskActivity extends Activity implements OnClickListener {

    Button btn;
    AsyncTask<?, ?, ?> runningTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = findViewById(R.id.button1);

        // Because we implement OnClickListener, we only
        // have to pass "this" (much easier)
        btn.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        // Detect the view that was "clicked"
        switch (view.getId()) {
        case R.id.button1:
            if (runningTask != null)
                runningTask.cancel(true);
            runningTask = new LongOperation();
            runningTask.execute();
            break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Cancel running task(s) to avoid memory leaks
        if (runningTask != null)
            runningTask.cancel(true);
    }

    private final class LongOperation extends AsyncTask<Void, Void, String> {

        @Override
        protected String doInBackground(Void... params) {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // We were cancelled; stop sleeping!
                }
            }
            return "Executed";
        }

        @Override
        protected void onPostExecute(String result) {
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed"); // txt.setText(result);
            // You might want to change "executed" for the returned string
            // passed into onPostExecute(), but that is up to you
        }
    }
}

2
Tôi không thể làm điều này <code> btn.setOnClickListener (cái này); </ code> Eclipse đưa ra lỗi ----- "Phương thức setOnClickListener (View.OnClickListener) trong loại Chế độ xem không áp dụng cho các đối số (AsyncTaskActivity)"
Fox

Tôi khuyên bạn nên thay đổi cài đặt của văn bản để không tĩnh mà lấy đối số từ onPostExecute(String result)phương thức. Nó sẽ làm cho các độc giả tương lai rõ ràng hơn rằng đối số được xác định bằng giá trị trả về của doInBackground(String... params).
Eric

@Eric Tobias - Đó là những điều chính xác được thực hiện trong phần bình luận. Tôi đã theo dõi và trả lời câu hỏi của người dùng trong ví dụ đầy đủ của tôi.
Graham Smith

1
Là một phụ lục và nhà tạo hạt giống google (và đến từ một người hiện đang tìm hiểu công cụ này, đó là cách tôi đã tìm thấy) được thực thi trong luồng UI chính.
RichieHH

1
Điều này chắc chắn sẽ gây rối nếu hoạt động của bạn bị xoay vòng hoặc phá hủy vì bất kỳ lý do gì ...
Sam

792

Câu trả lời đầy đủ của tôi là ở đây , nhưng đây là một hình ảnh giải thích để bổ sung cho các câu trả lời khác trên trang này. Đối với tôi, hiểu được tất cả các biến đang diễn ra ở đâu là phần khó hiểu nhất lúc ban đầu.

nhập mô tả hình ảnh ở đây


3
paramslà một mảng. (Trong ví dụ trên, đó là một Stringmảng.) Điều này cho phép bạn truyền vào nhiều tham số cùng loại. Sau đó, bạn có thể truy cập những thông số với params[0], params[1], params[2], vv Trong ví dụ này, chỉ có một đơn Stringtrong paramsmảng. Nếu bạn cần truyền vào nhiều tham số thuộc các loại khác nhau (ví dụ: a Stringvà an int), hãy xem câu hỏi này .
Suragch

73

Tôi chắc chắn rằng nó đang thực thi đúng, nhưng bạn đang cố gắng thay đổi các thành phần UI trong luồng nền và điều đó sẽ không xảy ra.

Sửa lại cuộc gọi của bạn và AsyncTask như sau:

Lớp học gọi

Lưu ý: Cá nhân tôi khuyên onPostExecute()bạn nên sử dụng bất cứ nơi nào bạn thực hiện luồng AsyncTask của mình và không phải trong lớp mở rộng chính AsyncTask. Tôi nghĩ rằng nó làm cho mã dễ đọc hơn, đặc biệt nếu bạn cần AsyncTask ở nhiều nơi xử lý các kết quả hơi khác nhau.

new LongThread() {
    @Override public void onPostExecute(String result) {
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText(result);
    }
}.execute("");

Lớp LongThread (mở rộng AsyncTask):

@Override
protected String doInBackground(String... params) {
    for (int i = 0; i < 5; i++) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    return "Executed";
}      

7
Cảm ơn bạn đã cung cấp một ví dụ tách riêng AsyncTask khỏi Hoạt động
sthomps

1
vâng, cuối cùng cũng có người tách rời nhiệm vụ và hoạt động. cảm ơn bạn. Và ghi đè onPostExecutetrong các hoạt động là tuyệt vời.
MCY

58

Khái niệm và mã ở đây

Tôi đã tạo một ví dụ đơn giản để sử dụng AsyncTask của Android. Nó bắt đầu với onPreExecute(), doInBackground(), publishProgress()và cuối cùngonProgressUpdate() .

Trong trường hợp này, doInBackground () hoạt động như một luồng nền, trong khi các hoạt động khác trong Giao diện người dùng. Bạn không thể truy cập phần tử UI trong doInBackground (). Trình tự giống như tôi đã đề cập.

Tuy nhiên, nếu bạn cần cập nhật bất kỳ tiện ích nào từ đó doInBackground, bạn có thể gọi publishProgresstừ doInBackgroundđó onProgressUpdateđể cập nhật tiện ích UI.

class TestAsync extends AsyncTask<Void, Integer, String> {
    String TAG = getClass().getSimpleName();

    protected void onPreExecute() {
        super.onPreExecute();
        Log.d(TAG + " PreExceute","On pre Exceute......");
    }

    protected String doInBackground(Void...arg0) {
        Log.d(TAG + " DoINBackGround", "On doInBackground...");

        for (int i=0; i<10; i++){
            Integer in = new Integer(i);
            publishProgress(i);
        }
        return "You are at PostExecute";
    }

    protected void onProgressUpdate(Integer...a) {
        super.onProgressUpdate(a);
        Log.d(TAG + " onProgressUpdate", "You are in progress update ... " + a[0]);
    }

    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        Log.d(TAG + " onPostExecute", "" + result);
    }
}

Gọi nó như thế này trong hoạt động của bạn:

new TestAsync().execute();

Nhà phát triển tham khảo tại đây


3
các lớp bắt đầu bằng chữ in hoa thường trong Java, đó là một ký hiệu thường được theo sau
Vamsi Pavan Mahesh

20

Di chuyển hai dòng này:

TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");

ra khỏi doInBackgroundphương thức AsyncTask của bạn và đưa chúng vào onPostExecutephương thức. Bạn AsyncTasksẽ trông giống như thế này:

private class LongOperation extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        try {
            Thread.sleep(5000); // no need for a loop
        } catch (InterruptedException e) {
            Log.e("LongOperation", "Interrupted", e);
            return "Interrupted";
        }
        return "Executed";
    }      

    @Override
    protected void onPostExecute(String result) {               
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText(result);
    }
}

Xin chào, tôi đang chạy tác vụ async trên dịch vụ, tôi muốn trả về một số giá trị cho luồng ui chính.
Dipen

@Dipen - Kiểm tra cuộc thảo luận này . Có hai vấn đề: báo cáo kết quả từ một AsyncTask, mà câu trả lời của tôi giải quyết; và gửi một giá trị từ một dịch vụ đến luồng ui, mà các địa chỉ thảo luận khác. Những vấn đề này là độc lập.
Ted Hopp

14

Bối cảnh / Lý thuyết

AsyncTask cho phép bạn chạy một tác vụ trên một luồng nền, trong khi xuất bản kết quả lên luồng UI.

Người dùng phải luôn có thể tương tác với ứng dụng, vì vậy điều quan trọngtránh chặn luồng chính (UI) với các tác vụ như tải xuống nội dung từ web.

Đây là lý do tại sao chúng tôi sử dụng một AsyncTask.

Nó cung cấp một giao diện đơn giản bằng cách gói hàng đợi và xử lý tin nhắn luồng UI cho phép bạn gửi và xử lý các đối tượng và tin nhắn có thể chạy được từ các luồng khác .

Thực hiện

AsyncTask là một lớp chung. (Nó có các loại tham số hóa trong hàm tạo của nó.)

Nó sử dụng ba loại chung này:

Params - loại tham số được gửi đến tác vụ khi thực hiện.

Progress - loại đơn vị tiến độ được công bố trong quá trình tính toán nền.

Result - loại kết quả của tính toán nền.

Không phải tất cả các loại luôn được sử dụng bởi một tác vụ không đồng bộ. Để đánh dấu một loại là không sử dụng, chỉ cần sử dụng loại Void:

private class MyTask extends AsyncTask<Void, Void, Void> { ... }

Ba tham số này tương ứng với ba chức năng chính mà bạn có thể ghi đè AsyncTask:

  • doInBackground(Params...)
  • onProgressUpdate(Progress...)
  • onPostExecute(Result)

Để thực thi AsyncTask

  • Gọi execute()với các tham số sẽ được gửi đến nhiệm vụ nền.

Chuyện gì xảy ra

  1. Trên chủ đề chính / UI , onPreExecute()được gọi.

    • Để khởi tạo một cái gì đó trong chủ đề này. (Ví dụ: hiển thị thanh tiến trình trên giao diện người dùng.)
  2. Trên một chủ đề nền , doInBackground(Params...)được gọi.

    • ( Paramsđã được thông qua execute.)
    • Trường hợp nhiệm vụ dài hạn nên xảy ra.
    • Phải ghi đè ít nhất doInBackground()để sử dụng AsyncTask.

    • Gọi publishProgress(Progress...)để cập nhật giao diện người dùng với màn hình hiển thị tiến trình (ví dụ: hoạt hình UI hoặc văn bản nhật ký được in) trong khi tính toán nền vẫn đang thực thi.

      • Nguyên nhân onProgressUpdate()được gọi.
  3. Trên chủ đề nền một kết quả được trả về từ doInBackground().

    • (Điều này kích hoạt bước tiếp theo.)
  4. Trên luồng chính / UI , onPostExecute()được gọi với kết quả trả về.

Ví dụ

Trong cả hai ví dụ, "nhiệm vụ chặn" là tải xuống từ web.

  • Ví dụ A tải xuống một hình ảnh và hiển thị nó trong ImageView, trong khi
  • Ví dụ B tải xuống một số tệp .

Ví dụ A

Các doInBackground()phương pháp tải các hình ảnh và lưu trữ nó trong một đối tượng kiểu bitmap. CáconPostExecute() phương pháp lấy bitmap và đặt nó trong ImageView.

class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bitImage;

    public DownloadImageTask(ImageView bitImage) {
        this.bitImage = bitImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mBmp = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mBmp = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mBmp;
    }

    protected void onPostExecute(Bitmap result) {
        bitImage.setImageBitmap(result);
    }
}

Ví dụ B

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

Thực hiện ví dụ B

new DownloadFilesTask().execute(url1, url2, url3);

Rất đẹp .. Nhưng tôi cứ bị lỗi về xung đột kiểu trả về - cố gắng sử dụng kiểu trả về không tương thích. Tôi đã thử tất cả các loại trả về, cùng một lỗi.
john ktejik

Xin chào @johnktejik, bạn có thể muốn tìm kiếm vấn đề cụ thể đó. Có lẽ đây là những gì đang xảy ra với bạn: loại trả về-không tương thích với asynctask
TT--

1
Thông minh! Xem xét đi vào chỉnh sửa ?
Peter Mortensen

12

Khi một tác vụ không đồng bộ được thực thi, tác vụ sẽ trải qua bốn bước:

  1. onPreExecute ()
  2. doInBackground (Params ...)
  3. onProTHERUpdate (Tiến trình ...)
  4. onPostExecute (Kết quả)

Dưới đây là một ví dụ demo:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {

    protected Long doInBackground(URL... urls) {
        int count = urls.length;
        long totalSize = 0;
        for (int i = 0; i < count; i++) {
            totalSize += Downloader.downloadFile(urls[i]);
            publishProgress((int) ((i / (float) count) * 100));

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

    protected void onProgressUpdate(Integer... progress) {
        setProgressPercent(progress[0]);
    }

    protected void onPostExecute(Long result) {
        showDialog("Downloaded " + result + " bytes");
    }
 }

Và một khi bạn đã tạo, một tác vụ được thực hiện rất đơn giản:

new DownloadFilesTask().execute(url1, url2, url3);

thực hiện mong đợi một paremeter là Runnable. Nó không chấp nhận chuỗi. Loại url của bạn là gì? chuỗi hay không

10

Ví dụ ngắn nhất để chỉ làm một cái gì đó không đồng bộ:

class MyAsyncTask extends android.os.AsyncTask {
    @Override
    protected Object doInBackground(Object[] objects) {
        // Do something asynchronously
        return null;
    }
}

Để chạy nó:

(new MyAsyncTask()).execute();

10

Làm cách nào để ghi nhớ các tham số được sử dụng trong AsyncTask?

Đừng

Nếu bạn chưa quen với AsyncTask thì việc nhầm lẫn khi viết AsyncTask là điều rất phổ biến. Thủ phạm chính là các tham số được sử dụng trong AsyncTask, nghĩa là , AsyncTask<A, B, C>. Dựa trên A, B, C (đối số) chữ ký của các phương thức khác nhau, điều này làm cho mọi thứ trở nên khó hiểu hơn.

Giữ cho nó đơn giản!

Điều quan trọng là không ghi nhớ . Nếu bạn có thể hình dung những gì nhiệm vụ của bạn thực sự cần làm thì viết AsyncTask với chữ ký chính xác ở lần thử đầu tiên sẽ là một miếng bánh. Chỉ cần tìm ra những gì bạn Input, ProgressOutput là, và bạn sẽ tốt để đi.

Vậy AsyncTask là gì?

AsyncTask là một tác vụ nền chạy trong luồng nền. Nó cần một Input, thực hiện Progressvà đưa ra một Output.

Tức là , AsyncTask<Input, Progress, Output>.

Ví dụ:

Nhập mô tả hình ảnh ở đây

Mối quan hệ với các phương pháp là gì?

Giữa AsyncTaskdoInBackground()

Nhập mô tả hình ảnh ở đây

doInBackground()onPostExecute(),onProTHERUpdate () `cũng có liên quan

Nhập mô tả hình ảnh ở đây

Làm thế nào để viết nó trong mã?

DownloadTask extends AsyncTask<String, Integer, String>{

    // Always same signature
    @Override
    public void onPreExecute()
    {}

    @Override
    public String doInbackGround(String... parameters)
    {
        // Download code
        int downloadPerc = // Calculate that
        publish(downloadPerc);

        return "Download Success";
    }

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

    @Override
    public void onProgressUpdate(Integer... parameters)
    {
        // Show in spinner, and access UI elements
    }

}

Làm thế nào bạn sẽ chạy nhiệm vụ này?

new DownLoadTask().execute("Paradise.mp3");

6

Khi bạn ở trong luồng công nhân, bạn không thể thao tác trực tiếp các thành phần UI trên Android.

Khi bạn đang sử dụng AsyncTask, vui lòng hiểu các phương thức gọi lại.

Ví dụ:

public class MyAyncTask extends AsyncTask<Void, Void, Void>{

    @Override
    protected void onPreExecute() {
        // Here you can show progress bar or something on the similar lines.
        // Since you are in a UI thread here.
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        // After completing execution of given task, control will return here.
        // Hence if you want to populate UI elements with fetched data, do it here.
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        // You can track you progress update here
    }

    @Override
    protected Void doInBackground(Void... params) {
        // Here you are in the worker thread and you are not allowed to access UI thread from here.
        // Here you can perform network operations or any heavy operations you want.
        return null;
    }
}

FYI: Để truy cập luồng UI từ luồng worker, bạn sử dụng phương thức runOnUiThread () hoặc phương thức post trên khung nhìn của bạn.

Ví dụ:

runOnUiThread(new Runnable() {
    textView.setText("something.");
});

or
    yourview.post(new Runnable() {
    yourview.setText("something");
});

Điều này sẽ giúp bạn biết những điều tốt hơn. Do đó, trong trường hợp của bạn, bạn cần đặt textview của mình trong phương thức onPostExecute ().


5

Tôi sẽ khuyên bạn nên làm cho cuộc sống của bạn dễ dàng hơn bằng cách sử dụng thư viện này cho các tác phẩm nền:

https://github.com/Arasthel/AsyncJobL Library

Thật đơn giản ...

AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {

    @Override
    public void doOnBackground() {
        startRecording();
    }
});

3

Nhiệm vụ Async mẫu với yêu cầu POST:

List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("key1", "value1"));
params.add(new BasicNameValuePair("key1", "value2"));
new WEBSERVICEREQUESTOR(URL, params).execute();

class WEBSERVICEREQUESTOR extends AsyncTask<String, Integer, String>
{
    String URL;
    List<NameValuePair> parameters;

    private ProgressDialog pDialog;

    public WEBSERVICEREQUESTOR(String url, List<NameValuePair> params)
    {
        this.URL = url;
        this.parameters = params;
    }

    @Override
    protected void onPreExecute()
    {
        pDialog = new ProgressDialog(LoginActivity.this);
        pDialog.setMessage("Processing Request...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... params)
    {
        try
        {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpEntity httpEntity = null;
            HttpResponse httpResponse = null;

            HttpPost httpPost = new HttpPost(URL);

            if (parameters != null)
            {
                httpPost.setEntity(new UrlEncodedFormEntity(parameters));
            }
            httpResponse = httpClient.execute(httpPost);

            httpEntity = httpResponse.getEntity();
            return EntityUtils.toString(httpEntity);

        }  catch (Exception e)
        {

        }
        return "";
    }

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

        try
        {

        }
        catch (Exception e)
        {

        }
        super.onPostExecute(result);
    }
}


1

Bạn cần khai báo nút onclicklistener. Sau khi nhấp vào, nó gọi lớp AsyncTask DownloadJson.

Quá trình sẽ được hiển thị dưới đây:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btn = (Button) findViewById(R.id.button1);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new DownloadJson().execute();
            }
        });
    }

    // DownloadJSON AsyncTask
    private class DownloadJson extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... params) {
            newlist = new ArrayList<HashMap<String, String>>();
            json = jsonParser.makeHttpRequest(json, "POST");
            try {
                newarray = new JSONArray(json);
                    for (int i = 0; i < countdisplay; i++) {
                        HashMap<String, String> eachnew = new HashMap<String, String>();
                        newobject = newarray.getJSONObject(i);
                        eachnew.put("id", newobject.getString("ID"));
                        eachnew.put("name", newobject.getString("Name"));
                        newlist.add(eachnew);
                    }
                }
            } catch (JSONException e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void args) {
            newlisttemp.addAll(newlist);
            NewAdapterpager newadapterpager = new NewAdapterpager(ProcesssActivitypager.this, newlisttemp);
            newpager.setAdapter(newadapterpager);
        }
    }

1
private class AsyncTaskDemo extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // Showing progress dialog
        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Loading...");
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    @Override
    protected Void doInBackground(Void... arg0) {

        // Do code here

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        // Dismiss the progress dialog
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }

    @Override
    protected void onCancelled() {

        super.onCancelled();
        progressDialog.dismiss();
        Toast toast = Toast.makeText(
                          getActivity(),
                          "An error is occurred due to some problem",
                          Toast.LENGTH_LONG);
        toast.setGravity(Gravity.TOP, 25, 400);
        toast.show();
    }

}


0

Ví dụ mẫu AsyncTask với tiến trình

import android.animation.ObjectAnimator;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class AsyncTaskActivity extends AppCompatActivity implements View.OnClickListener {

    Button btn;
    ProgressBar progressBar;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(this);
        progressBar = (ProgressBar)findViewById(R.id.pbar);
    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button1:
                new LongOperation().execute("");
                break;
        }
    }

    private class LongOperation extends AsyncTask<String, Integer, String> {

        @Override
        protected String doInBackground(String... params) {
            Log.d("AsyncTask", "doInBackground");
            for (int i = 0; i < 5; i++) {
                try {
                    Log.d("AsyncTask", "task "+(i + 1));
                    publishProgress(i + 1);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.interrupted();
                }
            }
            return "Completed";
        }

        @Override
        protected void onPostExecute(String result) {
            Log.d("AsyncTask", "onPostExecute");
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText(result);
            progressBar.setProgress(0);
        }

        @Override
        protected void onPreExecute() {
            Log.d("AsyncTask", "onPreExecute");
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("onPreExecute");
            progressBar.setMax(500);
            progressBar.setProgress(0);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            Log.d("AsyncTask", "onProgressUpdate "+values[0]);
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("onProgressUpdate "+values[0]);

            ObjectAnimator animation = ObjectAnimator.ofInt(progressBar, "progress", 100 * values[0]);
            animation.setDuration(1000);
            animation.setInterpolator(new LinearInterpolator());
            animation.start();
        }
    }
}

0

Nhiệm vụ ASync;

public class MainActivity extends AppCompatActivity {

    private String ApiUrl = "your_api";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyTask myTask = new MyTask();
        try {
            String result=myTask.execute(ApiUrl).get();
            Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
           e.printStackTrace();
        }
    }

    public class MyTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... strings) {

            String result = "";
            HttpURLConnection httpURLConnection = null;
            URL url;

            try {
                url = new URL(strings[0]);
                httpURLConnection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = httpURLConnection.getInputStream();
                InputStreamReader reader = new InputStreamReader(inputStream);
                result = getData(reader);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return result;
        }

        public String getData(InputStreamReader reader) throws IOException {

            String result = "";
            int data = reader.read();
            while (data!=-1) {
                char now = (char) data;
                result += data;
                data = reader.read();
            }
            return result;
        }
    }

}

Tại sao lớp học MyTaskbên trong lớp học MainActivity? Đó có phải là thông lệ không?
Peter Mortensen

0

Trong khi làm việc với AsyncTask, cần phải tạo một lớp kế và trong đó để đăng ký thực hiện các phương thức cần thiết cho chúng ta. Trong bài học này chúng ta sẽ xem xét ba phương pháp:

doInBackground - sẽ được thực thi trong một luồng mới và ở đây chúng tôi giải quyết tất cả các nhiệm vụ khó khăn của chúng tôi. Bởi vì một luồng không chính không có quyền truy cập vào UI.

onPreExecute - được thực thi trước doInBackground và có quyền truy cập vào UI

onPostExecute - được thực hiện sau doInBackground (không hoạt động nếu AsyncTask bị hủy - về điều này trong các bài học tiếp theo) và có quyền truy cập vào UI.

Đây là lớp MyAsyncTask:

class MyAsyncTask extends AsyncTask<Void, Void, Void> {

  @Override
  protected void onPreExecute() {
    super.onPreExecute();
    tvInfo.setText("Start");
  }

  @Override
  protected Void doInBackground(Void... params) {
    // Your background method
    return null;
  }

  @Override
  protected void onPostExecute(Void result) {
    super.onPostExecute(result);
    tvInfo.setText("Finish");
  }
}

Và đây là cách gọi Hoạt động hoặc Đoạn của bạn:

MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute();

Re "về điều này trong các bài học tiếp theo" : Điều đó đề cập đến điều gì? Ví dụ, cái này được lấy từ đâu?
Peter Mortensen

0

nếu bạn mở lớp AsyncTask, bạn có thể thấy mã bên dưới.

public abstract class AsyncTask<Params, Progress, Result> {
    @WorkerThread
    protected abstract Result doInBackground(Params... params);
    @MainThread
    protected void onPreExecute() {
    }
    @SuppressWarnings({"UnusedDeclaration"})
    @MainThread
    protected void onPostExecute(Result result) {
    }
}

Các tính năng của AsyncTask

  1. AsyncTask là lớp trừu tượng
  2. AsyncTask có 3 thông số chung.
  3. AsyncTask có phương thức trừu tượng của doInBackground, onPreExecute, onPostExecute
  4. doInBackground là WorkerThread (bạn không thể cập nhật giao diện người dùng)
  5. onPreExecute là MainThread
  6. onPostExecute là MainThread (bạn có thể cập nhật giao diện người dùng)

thí dụ

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    mEmailView = (AutoCompleteTextView) findViewById(R.id.email);

    AsyncTask<Void, Void, Post> asyncTask = new AsyncTask<Void, Void, Post>() {
        @Override
        protected Post doInBackground(Void... params) {
            try {
                ApiClient defaultClient = Configuration.getDefaultApiClient();
                String authorization = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1ODIxMzM4MTB9.bA3Byc_SuB6jzqUGAY4Pyt4oBNg0VfDRctZ8-PcPlYg"; // String | JWT token for Authorization
                ApiKeyAuth Bearer = (ApiKeyAuth) defaultClient.getAuthentication("Bearer");
                Bearer.setApiKey(authorization);
                PostApi apiInstance = new PostApi();
                String id = "1"; // String | id
                Integer commentPage = 1; // Integer | Page number for Comment
                Integer commentPer = 10; // Integer | Per page number For Comment
                Post result;
                try {
                    result = apiInstance.apiV1PostsIdGet(id, authorization, commentPage, commentPer);
                } catch (ApiException e) {
                    e.printStackTrace();
                    result = new Post();
                }
                return result;
            } catch (Exception e) {
                e.printStackTrace();
                return new Post();
            }
        }

        @Override
        protected void onPostExecute(Post post) {
            super.onPostExecute(post);
            if (post != null) {
                mEmailView.setText(post.getBody());
                System.out.print(post);
            }
        }
    };
    asyncTask.execute();
}

-1

Thay đổi mã của bạn như được đưa ra dưới đây:

@Override
protected void onPostExecute(String result) {

    runOnUiThread(new Runnable() {
        public void run() {
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed");
        }
    });
}

1
Bạn không cần sử dụng runOnUiThread vì onPostExecute luôn chạy trên luồng 1 (có phải không?)
justdan0227 16/07/2016
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.