비동기 작업 의 AsyncTask 구현

전송 출처 를 밝 혀 주세요:http://blog.csdn.net/qq_28055429/article/details/51934966
프롤로그:handler+message 로 비동기 작업 이 상대 적 으로 복잡 하기 때문에 간단 한 비동기 작업 만 하면 비동기 작업 AsyncTask 로 이 루어 집 니 다.
1.기본 지식:
(1)원형:

android.os.AsyncTask
세 개의 매개 변수
Params---HTTP 가 요청 한 URL 과 같은 작업 수행 을 시작 하 는 입력 매개 변수 입 니 다.
Progress---백 스테이지 작업 수행 의 백분율.
Result-----백그라운드 에서 임 무 를 수행 하고 최종 적 으로 돌아 온 결과,예 를 들 어 Drawable.

 
 (2)基本步骤: 
  
 

4个步骤:

onPreExecute():  执行后台操作前回调的函数,常用来设置任务,例如:在用户界面中显示一个进度条。

doInBackground(Void... params) :后台执行耗时的操作,常用于接受参数返回结果,结果返回到onPostExecute()中

不能直接操作UI,在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。

onProgressUpdate(Progress...) : 在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。

onPostExecute (String result):执行后台操作完毕后自动回调此函数,后台操作结束后的结果会返回到这里,来使用

(3)基本方法:

boolean   cancel(boolean mayInterruptIfRunning)  :尝试取消,如任务下载时,突然想停止,可设置XX.cancel(true);

execute(Params... params)       :根据参数来开始执行

get():如果有必要,就等待计算完成,然后取它的结果

get(long timeout, TimeUnit unit)  :如果有必要,等待规定时间的计算,然后取它的结果

boolean isCancelled()    :判断操作是否已经取消了

 AsyncTask.Status  getStatus()  :获取当前任务的状态,

(4)4个原则:

1.异步任务的实例必须在UI线程中创建。

2.execute(Params... params)方法必须在UI线程中调用。

3.不要手动调用onPreExecute(),doInBackground(Params... params),onProgressUpdate(Progress... values),onPostExecute(Result result)这几个方法。

4.一个任务实例只能执行一次,如果执行第二次将会抛出异常。

(5)用法:一般都是一个类去继承AsyncTask,重写里面的方法,一般重写的方法有:doInBackground和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));
         }
         return totalSize;
     }

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

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

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

둘째,예:
예(1):네트워크 그림 불 러 오기:
레이아웃:activitythird:그림 을 표시 하기 위해 imageView 를 설치 합 니 다.
<?xml version="1.0" encoding="utf-8"?>
<!--      :LinearLayout-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <!--    imageView     -->
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:src="@drawable/load"/>

</LinearLayout>

비동기 클래스:ImageAsyncTask:AsyncTask에서 계승 하여 구현 하 는 방법:
package testsdcard.com.maiyu.s04_79.domain;

import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.widget.ImageView;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import testsdcard.com.maiyu.s04_79.R;

/**   ImageAsynTask ,        
 * Created by maiyu on 2016/7/17.
 */
public class ImageAsynTask extends AsyncTask<Void ,Void ,Drawable> {
    private ImageView m ;       //      
    private String imageUrl ;   //        

    //  imageView          ,    
    public ImageAsynTask(ImageView i , String t){
        m  = i ;
        imageUrl = t ;
    }
    //         
    @Override
    protected Drawable doInBackground(Void... voids) {
        return loadImages(imageUrl);    //          
    }

    //                
    @Override
    protected void onPostExecute(Drawable drawable) {
        super.onPostExecute(drawable);
        if(drawable != null){       //          
            m.setImageDrawable(drawable);
        }else {
            m.setImageResource(R.drawable.failed);
        }
    }
    //            
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    //        
    private Drawable loadImages(String url) {
        try{
            //  URL  
            URL mUrl = new URL(url);
            //  inputStream
            InputStream inputStream = (InputStream)mUrl.openStream();
            return Drawable.createFromStream(inputStream , "test"); //       

        }catch(IOException e){
            e.printStackTrace();
        }
        return null;
    }
}

테스트 클래스:ThridActivity:그림 불 러 오 는 것 을 테스트 하기 위해 새로 만 든 비동기 작업:
new ImageAsynTask(mImage , "http://p4.so.qhimg.com/t01aade72dccf26cffe.jpg").execute();
코드 는 다음 과 같 습 니 다:
package testsdcard.com.maiyu.s04_79.activity;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;

import testsdcard.com.maiyu.s04_79.R;
import testsdcard.com.maiyu.s04_79.domain.ImageAsynTask;

/**
 * Created by maiyu on 2016/7/17.
 */
public class ThirdActivity extends Activity {
    private ImageView mImage ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);
        mImage = (ImageView)findViewById(R.id.imageView);
        //        ,        
        new ImageAsynTask(mImage , "http://p4.so.qhimg.com/t01aade72dccf26cffe.jpg").execute();
    }
}

네트워크 권한 추가 기억 하기:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>

결과:약,,,
예 2:인터넷 주소 에 따라 네트워크 Html 내용 을 다운로드 하면 다운 로드 를 중단 할 수 있 습 니 다.즉,테스트 클래스 cancel(boolean)방법 입 니 다.
레이아웃:activityfour:editText 를 설치 하고 두 단 추 를 누 르 면 다운로드 와 정지 입 니 다.하나의 ScrollView(안에 TextView 를 설치)는 내용 을 표시 하 는 데 사 용 됩 니 다.
<?xml version="1.0" encoding="utf-8"?>
<!--         ;LinearLayout-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <!--                 -->
    <EditText
        android:id="@+id/Et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/four_edt1"/>
    <!--              -->
    <Button
        android:id="@+id/BtnStart"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/four_btn1"/>
    <!--              -->
    <Button
        android:id="@+id/BtnStop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/four_btn2"/>
    <!--      -->
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/Tv"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </ScrollView>

</LinearLayout>

비동기 클래스:HtmlAsyncTask 는 AsyncTask에서 계승 하여 안쪽 방법 을 실현 합 니 다.
코드 는 다음 과 같 습 니 다:
package testsdcard.com.maiyu.s04_79.domain;

import java.io.IOException;

import android.os.AsyncTask;
import android.util.Log;
import android.widget.TextView;

//   ImageAsynTask ,        
public class HtmlAsyncTask extends AsyncTask<Void, Void, String> {
    //                     TextView  
    private TextView m;
    //           
    private String url;

    //    ,  TextView       
    public HtmlAsyncTask(TextView i, String t) {
        m = i;
        url = t;
    }

    //         
    @Override
    protected String doInBackground(Void... params) {
        return requestByHttpGet(url);
    }

    //                
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        Log.e("isCancelled()", isCancelled() + "");
        //           
        if (isCancelled()) {
            m.setText("    ");
        }
        //                     ,  textview    
        else if (null != result) {
            m.setText(result);
        }
        //           ,      
        else {
            m.setText("    ");
        }
    }

    //            
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }


    //    url     
    public String requestByHttpGet(String url) {
        //  HttpGet  
        HttpGet httpGet = new HttpGet(url);
        //  HttpClient  
        HttpClient httpClient = new DefaultHttpClient();
        //  HttpResponse  
        HttpResponse httpResp;
        try {
            httpResp = httpClient.execute(httpGet);
            //         
            if (httpResp.getStatusLine().getStatusCode() == 200) {
                //        
                String result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");
                Log.e("TAG", "HttpGet      ,      :");
                return result;
            } else {
                Log.e("TAG", "HttpGet      ");
            }
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

테스트 클래스:같은 이치:코드 는 다음 과 같 습 니 다.
package testsdcard.com.maiyu.s04_79.activity;

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

import testsdcard.com.maiyu.s04_79.R;
import testsdcard.com.maiyu.s04_79.domain.HtmlAsyncTask;

//         Activity
public class FourActivity extends Activity {
    //      TextView  
    private TextView tv;
    //      EditText  
    private EditText et;
    //          Button  
    private Button btnstart;
    //          Button  
    private Button btnstop;
    //      html       
    protected HtmlAsyncTask hat;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findView();
        setListener();
    }

    private void setListener() {
        //  btn      
        btnstart.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //  textview   
                tv.setText("Html   .........");
                //  EditText      
                String str = et.getText().toString();
                //             url    html
                hat = new HtmlAsyncTask(tv, str);
                hat.execute();
            }
        });
        btnstop.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //      
                hat.cancel(true);
            }
        });
    }

    private void findView() {
        //      TextView   
        tv = (TextView) findViewById(R.id.Tv);
        //      EditText   
        et = (EditText) findViewById(R.id.Et);
        //           Button   
        btnstart = (Button) findViewById(R.id.BtnStart);
        //           Button   
        btnstop = (Button) findViewById(R.id.BtnStop);
    }
}

네트워크 권한 추가:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
  : ,,

3.요약:
AsyncTask 에서 사용 하 는 일반적인 절차:
(1)클래스 를 만 들 고 AsyncTask<매개 변수 1,매개 변수 2,매개 변수 3>을 계승 합 니 다.매개 변 수 는 보통입 니 다.
예:ImageAsyncTask extends AsyncTask {}//그림 가 져 오기
StringAsyncTask extends AsyncTask{}/문자열 데이터 가 져 오기
(2)그리고 그 방법 을 다시 쓰 는 방법 은 doInBackground 와 onPost Execute 가 있 습 니 다.
대략
(3)테스트 클래스 에서 호출 하고 execute()방법 을 실행 합 니 다.
   이전 예 에서:
new HtmlAsyncTask(tv, str).execute();

좋은 웹페이지 즐겨찾기