AsyncTask Android 예제


Answers

내 대답은 here 에 있지만이 페이지의 다른 답변을 보완하는 설명 이미지가 있습니다. 나를 위해, 모든 변수가 어디로 가고 있는지 이해하는 것은 처음에는 가장 혼란스러운 부분이었습니다.

Question

AsyncTask 에 대해 읽고 있었는데, 아래 간단한 프로그램을 시도했습니다. 그러나 그것은 효과가없는 것처럼 보입니다. 어떻게 작동시킬 수 있습니까?

package com.test;

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



이론

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

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

UI 쓰레드는 메시지 큐와 핸들러를 가지고있어서 실행 가능한 객체와 메시지를 다른 쓰레드로부터 보내고 처리 할 수있다. AsyncTask는 직선적 인 인터페이스로이 동작을 래핑합니다.

이행

AsyncTask 는 제네릭 클래스입니다. (생성자에서 매개 변수화 된 형식을 사용한다는 의미이며, 각 generic 매개 변수는 기술적으로는 배열로 전달되는 세 개의 점이있는 Java 변수 인수로 정의됩니다.

AsyncTask 사용되는 세 가지 유형은 Params , ProgressResult .

  1. Params - 실행시 태스크에 보내지는 매개 변수 유형
  2. 진행률 - 백그라운드 계산 중에 진행 상황을 업데이트하기 위해 게시 된 유형
  3. Result - 백그라운드 계산의 결과의 형태

이 세 매개 변수는 AsyncTask 에서 재정의 할 수있는 세 가지 기본 함수에 해당합니다.

  • doInBackground()
  • onProgressUpdate()
  • onPostExecute()

    또한:

  • onPreExecute()

AsyncTask를 실행하려면

call 백그라운드 작업에 보낼 매개 변수를 사용하여 Execute .

무슨 일이야

  1. 메인 / UI 스레드에서 onPreExecute 가 호출됩니다. (이 스레드에서 무언가를 초기화하려면.)
  2. 백그라운드 스레드에서 Execute 함수에 전달 된 매개 변수로 doInBackground() 가 호출됩니다.
    • AsyncTask를 사용하려면 적어도 doInBackground() 를 대체해야합니다.
    • 장기간 실행해야하는 작업
    • Progress 매개 변수가있는 publishProgress() 를 호출하여 장기 실행 작업의 진행으로 일부 UI를 업데이트합니다. 이로 인해 onProgressUpdate() 가 호출됩니다.
  3. 백그라운드 스레드에서 결과는 doInBackground() task에서 리턴됩니다.
  4. 기본 / UI 스레드에서 반환 된 결과와 함께 호출 할 onPostExecute() .

다음 예제는 이미지를 다운로드하여 ImageView에 표시하는 예제입니다. 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);
    }
}



개념과 코드는 여기에

Android의 AsyncTask를 사용하는 간단한 예제를 만들었습니다. onPreExecute(), doInBackground(), publishProgress()onProgressUpdate() 합니다.

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

그러나 doInBackground 에서 위젯을 업데이트해야하는 경우 doInBackground 에서 publishProgress 를 호출하여 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();

개발자 참조




단추를 onclicklistener라고 선언해야합니다. 한 번 클릭하여 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);
        }
    }



작업자 스레드에서 작업하는 경우 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 () 메서드를 사용하거나 뷰에 메서드를 게시하십시오.

예를 들면 :

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

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

이것은 당신이 더 나은 것을 알 수 있도록 도와 줄 것입니다. 따라서 당신의 경우에는 onPostExecute () 메서드에서 텍스트 뷰를 설정해야합니다.




비동기식으로 일하는 가장 짧은 예제 :

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

그것을 실행하려면 :

(new MyAsyncTask()).execute();



간단히:

LongOperation MyTask = new LongOperation();
MyTask.execute();



Related