AsyncTask Android 예제


680

에 대해 읽고 있었고 AsyncTask아래 간단한 프로그램을 시도했습니다. 그러나 작동하지 않는 것 같습니다. 어떻게 작동시킬 수 있습니까?

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) {
        }
    }
}

백그라운드 프로세스에서 5 초 후에 레이블을 변경하려고합니다.

이것은 내 main.xml입니다 .

<?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
또한 doInBackground () 메소드에서 publishprogress ()를 호출하여 진행 상태를 표시 할 수 있습니다.
osum

3
여기에 asynctask 예입니다 AsyncTask 예
Samir Mangroliya

다음은 이미지 다운로드의 비동기 작업 예제입니다 : android-ios-tutorials.com/182/…
Houcine


3
간단한 예 ... 링크
c49

답변:


702

좋아, 다른 스레드를 통해 GUI에 액세스하려고합니다. 이것은 기본적으로 좋은 습관이 아닙니다.

AsyncTask doInBackground()는 다른 스레드 내부의 모든 것을 실행 하며 뷰가있는 GUI에 액세스 할 수 없습니다.

preExecute()그리고 postExecute()당신은 이전과 무거운이 새로운 스레드에서 발생한 후 GUI에 대한 액세스를 제공하며, 당신도 할 수 긴 작업의 결과를 전달할 수있는 postExecute()후 처리의 결과를 표시합니다.

나중에 TextView를 업데이트하는 다음 행을 참조하십시오.

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

에 넣으십시오 onPostExecute().

그러면 doInBackground완료 후 TextView 텍스트가 업데이트 된 것을 볼 수 있습니다 .

onClick 리스너가 선택된보기를 확인하지 않는 것으로 나타났습니다. 가장 쉬운 방법은 switch 문을 사용하는 것입니다. 혼란을 피하기 위해 모든 제안 사항을 아래에서 편집 한 완전한 수업이 있습니다.

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
이 <code> btn.setOnClickListener (this)를 수행 할 수 없습니다. </ code> Eclipse에서 오류가 발생합니다 ----- "보기 형식의 setOnClickListener (View.OnClickListener) 메소드는 인수 (AsyncTaskActivity)에 적용 할 수 없습니다"
Fox

텍스트 설정을 정적이 아닌 것으로 변경하는 것이 좋지만 onPostExecute(String result)메서드 에서 인수를 가져옵니다 . 미래 독자에게는 인수가의 반환 값으로 채워지는 것이 더 명확 해집니다 doInBackground(String... params).
Eric

@Eric Tobias-댓글이 달린 섹션에서 이미 완료된 작업입니다. 전체 예제에서 사용자 질문을 따르고 대답했습니다.
Graham Smith

1
부록 및 구글 파종 자로서 (그리고 내가이 방법을 배우는 현재이 물건을 배우는 사람에게서 온 것) : 사용자에게 다시보고해야 할 부분에 대해 수행 할 UI 업데이트의 대부분은 ProProgressUpdate 메인 UI 스레드에서 실행됩니다.
RichieHH

1
어떤 이유로 든 활동이 회전되거나 파괴 된 경우에는 반드시 엉망이됩니다.
Sam

792

전체 답변은 여기 이지만이 페이지의 다른 답변을 보완하는 설명 이미지가 있습니다. 저에게 모든 변수가 어디로 가고 있는지 이해하는 것이 처음에는 가장 혼란스러운 부분이었습니다.

여기에 이미지 설명을 입력하십시오


3
params배열입니다. (위의 예에서는 String배열이었습니다.) 동일한 유형의 여러 매개 변수를 전달할 수 있습니다. 그런 다음에 이러한 매개 변수에 액세스 할 수 있습니다 params[0], params[1], params[2]예에서, 등, 단 하나 있었다 Stringparams배열입니다. 다른 유형 (예 : a String및 a int) 의 여러 매개 변수를 전달해야하는 경우이 질문을 참조하십시오 .
Suragch February

73

제대로 실행되고 있다고 확신하지만 백그라운드 스레드에서 UI 요소를 변경하려고 시도하지만 그렇지 않습니다.

다음과 같이 호출 및 AsyncTask를 수정하십시오.

호출 클래스

참고 : 개인적 onPostExecute()으로 AsyncTask 자체를 확장하는 클래스가 아닌 AsyncTask 스레드를 실행할 때마다 사용하는 것이 좋습니다 . 결과가 약간 다른 여러 위치에서 AsyncTask가 필요한 경우 특히 코드를 쉽게 읽을 수 있다고 생각합니다.

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

LongThread 클래스 (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
활동과 AsyncTask를 분리하는 예제를 제공해 주셔서 감사합니다
sthomps

1
예, 마지막으로 누군가가 작업과 활동을 분리합니다. 감사합니다 onPostExecute. 그리고 활동을 재정의하는 것은 훌륭합니다.
mcy

58

개념과 코드는 여기

Android의 AsyncTask를 사용하는 간단한 예를 만들었습니다. onPreExecute(), doInBackground(), publishProgress()마지막으로 시작합니다 onProgressUpdate().

여기서 doInBackground ()는 백그라운드 스레드로 작동하고 다른 스레드는 UI 스레드에서 작동합니다. doInBackground ()에서 UI 요소에 액세스 할 수 없습니다. 순서는 내가 언급 한 것과 같습니다.

당신이에서 어떤 위젯을 업데이트해야 할 경우에는 doInBackground, 당신은 할 수 publishProgress에서 doInBackground어떤 호출 onProgressUpdate하여 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);
    }
}

당신의 활동에서 이것을 다음과 같이 부르십시오 :

new TestAsync().execute();

여기 개발자 참조


3
클래스는 일반적으로 자바에서 대문자로 시작합니다. 일반적으로 다음과 같은 표기법입니다.
Vamsi Pavan Mahesh

20

이 두 줄을 이동하십시오.

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

AsyncTask의 doInBackground메소드에서 벗어나 메소드에 넣으십시오 onPostExecute. 당신 AsyncTask은 다음과 같이 보일 것입니다 :

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);
    }
}

이봐, 내가 서비스에서 비동기 작업을 실행하는 중 일부 값을 기본 UI 스레드로 반환하려고합니다.
Dipen

@ Dipen- 이 토론을 확인하십시오 . 두 가지 문제가 있습니다.에서 AsyncTask답변 을 제공하는의 결과보고 ; 및 서비스로부터 ui 스레드로 값을 전송하는 단계-다른 토론은 처리 함- 이러한 문제는 독립적입니다.
Ted Hopp

14

배경 / 이론

AsyncTask를 사용하면 결과를 UI 스레드에 게시하는 동안 백그라운드 스레드에서 작업을 실행할 수 있습니다.

사용자는 항상 앱과 상호 작용할 수 있어야하므로 웹에서 콘텐츠를 다운로드하는 등의 작업으로 기본 (UI) 스레드차단하지 않는 것이 중요 합니다 .

이것이 우리가를 사용하는 이유 AsyncTask입니다.

UI 스레드 메시지 큐와 처리기를 래핑하여 다른 스레드에서 실행 가능한 개체와 메시지를 보내고 처리 할 수 있는 간단한 인터페이스를 제공 합니다 .

이행

AsyncTask 는 일반 클래스입니다. ( 생성자에 매개 변수화 된 유형 을 사용합니다.)

다음 세 가지 일반 유형을 사용합니다.

Params -실행시 태스크로 전송되는 매개 변수 유형

Progress -백그라운드 계산 중에 게시 된 진행률 단위의 유형

Result -백그라운드 계산 결과의 유형.

모든 유형이 항상 비동기 작업에서 사용되는 것은 아닙니다. 유형을 사용하지 않는 것으로 표시하려면 Void 유형을 사용하십시오.

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

이 세 매개 변수 는 다음 에서 대체 할 수있는 세 가지 기본 기능에 해당합니다AsyncTask .

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

AsyncTask를 실행하려면

  • execute()백그라운드 작업으로 전송 될 파라미터를 사용하여 호출 합니다.

무슨 일이야

  1. 주 /의 UI 스레드 , onPreExecute()라고합니다.

    • 이 스레드에서 무언가를 초기화합니다. (예 : 사용자 인터페이스에 진행률 표시 줄이 표시됩니다.)
  2. A의 백그라운드 스레드 , doInBackground(Params...)라고합니다.

    • ( Params을 통해 전달되었습니다 execute.)
    • 장기 실행 작업이 발생하는 위치
    • doInBackground()AsyncTask를 사용하려면 최소한 재정의해야합니다 .

    • publishProgress(Progress...)백그라운드 계산이 여전히 실행되는 동안 진행률 표시 (예 : UI 애니메이션 또는 로그 텍스트 인쇄)로 사용자 인터페이스를 업데이트하려면 호출하십시오 .

      • 원인은 onProgressUpdate()호출 할 수 있습니다.
  3. 배경 스레드 결과는에서 반환됩니다 doInBackground().

    • (다음 단계가 시작됩니다.)
  4. 주 /의 UI 스레드 , onPostExecute()반환 된 결과라고합니다.

두 예에서 "차단 작업"은 웹에서 다운로드 한 것입니다.

  • 예제 A 는 이미지를 다운로드 하여 ImageView에 표시합니다.
  • 예제 B는 일부 파일을 다운로드 합니다 .

예 A

doInBackground()메소드는 이미지를 다운로드하여 BitMap 유형의 오브젝트에 저장합니다. 이 onPostExecute()메소드는 비트 맵을 가져와 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);
    }
}

실시 예 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");
     }
 }

예제 B 실행

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

매우 좋은 .. 그러나 반환 유형 충돌에 대한 오류가 계속 발생합니다. 호환되지 않는 반환 유형을 사용하려고합니다. 나는 모든 종류의 반환 유형을 시도했지만 동일한 오류가 발생했습니다.
john ktejik

안녕 @ johnktejik, 당신은 특정 문제를 검색 할 수 있습니다. 아마도 이것이 당신에게 일어나는 일일
TT--

1
우수한! 가는 고려 편집 ?
피터 Mortensen

12

비동기 작업이 실행될 때 작업은 다음 4 단계를 거칩니다.

  1. onPreExecute ()
  2. doInBackground (파람 ...)
  3. onProgressUpdate (진행 ...)
  4. onPostExecute (결과)

아래는 데모 예입니다.

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");
    }
 }

그리고 일단 생성하면 작업이 매우 간단하게 실행됩니다.

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

execute는 paremeter를 Runnable로 예상합니다. 문자열을 허용하지 않습니다. 귀하의 URL 유형은 무엇입니까? 문자열 여부

10

비동기 적으로 무언가를 수행하는 가장 간단한 예 :

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

그것을 실행하려면 :

(new MyAsyncTask()).execute();

10

AsyncTask에 사용 된 매개 변수를 기억하는 방법은 무엇입니까?

하지마

AsyncTask를 처음 사용하는 경우 AsyncTask를 작성하는 동안 혼란스러워하는 것이 일반적입니다. 주요 원인은 AsyncTask에서 사용되는 매개 변수입니다 (예 :) AsyncTask<A, B, C>. 에 기초하여 A, B, C (인수) 서명에 따라 상황이 더 혼란 스럽습니다.

간단하게 유지하십시오!

열쇠는 암기하지 않습니다 . 작업이 실제로 필요한 것을 시각화 할 수 있다면 첫 번째 시도에서 올바른 서명으로 AsyncTask를 작성하는 것이 케이크 조각 일 것입니다. 그냥 알아낼 것을 당신 Input, Progress그리고Output , 그리고 당신은 갈 수있을 것입니다.

그렇다면 AsyncTask는 무엇입니까?

AsyncTask는 백그라운드 스레드에서 실행되는 백그라운드 작업입니다. 그것은 Input수행 Progress하고 수행 합니다 Output.

, AsyncTask<Input, Progress, Output>.

예를 들면 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

방법과의 관계는 무엇입니까?

사이 AsyncTaskdoInBackground()

여기에 이미지 설명을 입력하십시오

doInBackground()onPostExecute(),onProgressUpdate () '과 같은 관련

여기에 이미지 설명을 입력하십시오

코드에서 작성하는 방법?

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
    }

}

이 작업을 어떻게 수행 하시겠습니까?

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

6

작업자 스레드에 있으면 Android에서 UI 요소를 직접 조작 할 수 없습니다.

AsyncTask를 사용하는 경우 콜백 메소드를 이해하십시오.

예를 들면 다음과 같습니다.

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;
    }
}

참고 : 작업자 스레드에서 UI 스레드에 액세스하려면 runOnUiThread () 메서드를 사용하거나보기에서 post 메서드를 사용하십시오.

예를 들어 :

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

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

이렇게하면 사물을 더 잘 알 수 있습니다. 따라서 귀하의 경우 onPostExecute () 메소드에서 텍스트보기를 설정해야합니다.


5

백그라운드 작업에이 라이브러리를 사용하여보다 쉽게 ​​생활을 할 것을 권장합니다.

https://github.com/Arasthel/AsyncJobLibrary

이 간단합니다 ...

AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {

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

3

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

클릭 리스너에서 버튼을 선언해야합니다. 클릭하면 AsyncTask 클래스 DownloadJson을 호출합니다.

과정은 다음과 같습니다.

@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();
    }

}

1

업데이트 : 2020 년 3 월

안드로이드 개발자 공식 문서 에 따르면 AsyncTask는 더 이상 사용되지 않습니다.

대신 kotlin corourines 를 사용하는 것이 좋습니다 . 간단히 말해, 순차적 인 스타일로 비동기 작업을 작성할 수 있습니다.


0

진행 상황이있는 샘플 AsyncTask 예제

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

비동기 작업;

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;
        }
    }

}

왜 수업 MyTask내부에 수업이 MainActivity있습니까? 그 관습입니까?
피터 Mortensen

0

AsyncTask로 작업하는 동안 클래스 후속 작업을 작성하고 필요한 메소드 구현을 등록해야합니다. 이 레슨에서는 세 가지 방법을 살펴 보겠습니다.

doInBackground- 새 스레드에서 실행되며 여기서 어려운 작업을 모두 해결합니다. 기본이 아닌 스레드는 UI에 액세스 할 수 없기 때문입니다.

onPreExecute -doInBackground 전에 실행되며 UI에 액세스 할 수 있습니다

onPostExecute -doInBackground 이후에 실행되고 (다음 학습에서 AsyncTask가 취소 된 경우 작동하지 않음) UI에 액세스 할 수 있습니다.

이것은 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");
  }
}

그리고 이것은 활동 또는 조각을 호출하는 방법입니다.

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

"다음 강의에서 이것에 대해" 다시 : 그것은 무엇을 의미합니까? 예, 어디에서 가져 왔습니까?
피터 Mortensen

0

AsyncTask 클래스를 열면 아래 코드를 볼 수 있습니다.

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) {
    }
}

AsyncTask 기능

  1. AsyncTask는 추상 클래스입니다
  2. AsyncTask에는 3 개의 일반 매개 변수가 있습니다.
  3. AsyncTask에는 doInBackground, onPreExecute, onPostExecute의 추상 메소드가 있습니다.
  4. doInBackground는 WorkerThread입니다 (UI를 업데이트 할 수 없음)
  5. onPreExecute는 MainThread입니다
  6. onPostExecute가 MainThread입니다 (UI를 업데이트 할 수 있음)

@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

아래와 같이 코드를 변경하십시오.

@Override
protected void onPostExecute(String result) {

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

1
onPostExecute가 항상 스레드 1에서 실행되므로 runOnUiThread를 사용할 필요는 없습니다 (그렇지 않습니까?)
justdan0227
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.