android-asynctask 안드로이드 - AsyncTask Android 예제





인터넷 method (13)


작업자 스레드에서 작업하는 경우 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 () 메서드에서 텍스트 뷰를 설정해야합니다.

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>



간단히:

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



제대로 실행되고 있지만 백그라운드 스레드의 UI 요소를 변경하려고하고 있지만 그렇게하지 않을 것이라고 확신합니다.

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

통화 클래스

참고 : AsyncTask 스레드를 실행하고 AsyncTask 자체를 확장하는 클래스가 아닌 곳에서는 onPostExecute() 사용하는 것이 좋습니다. 나는 코드가 읽기 쉽게 만들기 쉽다고 생각한다. 특히 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";
}      



배경 작업을 위해이 라이브러리를 사용하여 더 쉽게 삶을 살도록 권하고 싶습니다. https://github.com/Arasthel/AsyncJobLibrary

그것의 간단한이 ..

AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {

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



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

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

preExecute()postExecute() 를 사용하면이 새 스레드에서 많은 양이 발생하기 전과 후에 GUI에 액세스 할 수 있으므로 긴 작업의 결과를 postExecute() 로 전달하여 처리 결과를 표시 할 수도 있습니다.

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

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

PostExecute() 에 넣어

그런 다음 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;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = (Button) findViewById(R.id.button1);
        // because we implement OnClickListener we only have to pass "this"
        // (much easier)
        btn.setOnClickListener(this);
    }

    public void onClick(View view) {
        // detect the view that was "clicked"
        switch (view.getId()) {
        case R.id.button1:
            new LongOperation().execute("");
            break;
        }
    }

    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) {
                    Thread.interrupted();
                }
            }
            return "Executed";
        }

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

        @Override
        protected void onPreExecute() {}

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



비동기 작업이 실행되면 작업은 4 단계로 진행됩니다.

  1. onPreExecute ()
  2. doInBackground (Params ...)
  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);

이게 너를 도울 수 있기를 바란다.




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




개념과 코드는 여기에

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

개발자 참조




 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(),
                "Error is occured due to some probelm", Toast.LENGTH_LONG);
        toast.setGravity(Gravity.TOP, 25, 400);
        toast.show();

    }

}



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



다음 두 줄을 이동하십시오.

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

AsyncTask의 doInBackground 메소드에서 doInBackground 메소드에 넣습니다. 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);
    }
}



배경 / 이론

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. 백그라운드 스레드에서 doInBackground(Params...) 가 호출됩니다. (매개 변수는 Execute 함수에 전달되는 매개 변수입니다.)

    • 장기간 실행해야하는 작업

    • AsyncTask를 사용하려면 적어도 doInBackground() 를 대체해야합니다.

    • 백그라운드 계산이 아직 실행 중일 때 publishProgress(Progress...) 를 호출하여 사용자 인터페이스의 진행 상태 표시를 업데이트합니다. (예 : 진행률 표시 줄에 애니메이션을 적용하거나 텍스트 필드에 로그를 표시하십시오.)

      • 이로 인해 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);



BeeWareBeeWare . 이 질문에 답하는 순간 아직 초기 개발 단계에 있습니다. Android를 비롯하여 지원되는 모든 운영체제에 Python으로 기본 앱을 만들 수 있습니다.





android android-asynctask