Android--异步任务AsyncTask

异步任务AsyncTask

什么是异步任务?
    逻辑上:以多线程的方式完成功能的需求
    API上:指AsyncTask类

AsyncTask的理解:
    在没有AsyncTask之前,我们用Handler+Thread就可以实现异步任务的功能需求
    AsyncTask是对Handler和Thread的封装,使用它编码更加简洁,更高效(就类似于问答题和填空题的区别)
    AsyncTask封装了ThreadPool,比直接使用Thread效率更高


相关API
    AsyncTask:简化Handler处理多线程通信的问题
    AsyncTask<Params,Progress,Result>
        Params启动任务执行的输入参数,比如HTTP请求的URL
        Progress后台任务执行的百分比
        Result后台执行任务最终返回的结果,比如String
    execute(Params...params)
        启动任务,开始任务的执行流程
    void onPreExecute()
        在分线程工作开始之前在UIThread中执行,一般用来显示提示视图
    Result doInBackground(Params...params)
        在workerThread中执行,完成任务的主要工作,通常需要较长的时间
    void onPostExecute(Result result)
        在doInBackground()执行完后在UIThread中执行,一般用来更新界面
    publicProgress(Progress...values):在分线程中,发布当前进度
    void onProgressUpdate(Progress...values):在主线程中更新进度

案例:
从本地服务器中下载一个APK

public class MainActivity extends AppCompatActivity {

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

    private ProgressDialog pd;
    private File apkFile;

    public void downloadAPK(View view){
        new AsyncTask<Void,Integer,Void>(){

            //主线程显示视图
            @Override
            protected void onPreExecute() {
                pd=new ProgressDialog(MainActivity.this);
                pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                pd.show();
                apkFile=new File(getExternalFilesDir(null),"update.apk");
            }

            //分线程,联网请求
            @Override
            protected Void doInBackground(Void... voids) {
                HttpURLConnection connection= null;
                try {
                    String path="http://192.168.137.1:8080/cookie_war_exploded/123.apk";
                    URL url=new URL(path);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(5000);
                    connection.setReadTimeout(5000);
                    int responseCode = connection.getResponseCode();
                    if(responseCode==200){
                        pd.setMax(connection.getContentLength());
                        InputStream is=connection.getInputStream();
                        FileOutputStream fos=new FileOutputStream(apkFile);
                        byte[] buffer=new byte[1024];
                        int len;
                        while((len=is.read(buffer))!=-1){
                            fos.write(buffer,0,len);
                            //显示进度,这里看上去是在分线程中执行,但是内部是使用了Handler更新界面(这里假设不能在分线程执行,所以注释掉)
                            //pd.incrementProgressBy(len);
                            //发布进度,则会执行下面的onProgressUpdate方法。这两个是一起的
                            publishProgress(len);
                        }
                        is.close();
                        fos.close();
                    }
                    connection.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                return null;
            }

            //主线程,更新界面
            @Override
            protected void onPostExecute(Void aVoid) {
                pd.dismiss();
                //installAPK();
            }


            @Override
            protected void onProgressUpdate(Integer... values) {
                pd.incrementProgressBy(values[0]);
            }
        }.execute();
    }

    //下载完后,进入安装应用界面,频繁报错,不知道为什么(进行这步需要权限,错误原因以后再探究)
//    private void installAPK(){
//        Intent intent=new Intent("android.intent.INSTALL_PACKAGE");
//        intent.setDataAndType(Uri.fromFile(apkFile),"application/vnd.android.package-archive");
//        startActivity(intent);
//    }

}
发布了117 篇原创文章 · 获赞 1 · 访问量 7060

猜你喜欢

转载自blog.csdn.net/qq_43616001/article/details/104375411