• Android之异步调用


    • 概述
      AsyncTask可以很好的,准确的使用UI线程,他可以将一个比较耗时(几秒钟)的动作运行在后台,并且能将结果返回至UI线程中,不需要通过(Thread操作和Handler操作)。
      使用时必须通过创建一个AsyncTask的子类,至少重写其doInBackground(顾名思义,你想在后台执行怎样的一个操作)方法,大多数也会重写onPostExcute(后台执行完之后你想将一个结果返回在UI线程的哪里)方法。

    • AsyncTask的三种泛型定义和四个步骤
      首先了解AsyncTask的三种泛型定义,如图:

      Params:执行后台操作时发给任务的参数类型,即doInBackground方法的参数,例:如果执行后台下载图片的文件,此处可为String 类型的imagePath。
      Progress:后台操作执行过程中进度的类型。
      Result:返回给UI线程的数据类型。即onPostExcute方法的参数,例:如果后台执行的是一个图片下载任务,此处肯定将返回一个Bitmap类型给UI线程。
      当然并不是所有的类型都会使用到,例如Progress,如果不需要显示进度条,将无需设计这个类型,直接用Void类型。
      其次了解其四个步骤:
      onPreExcute:执行后台任务之前做的操作,例如可以是弹出一个Dialog提示用户正在下载中。同时需要在onPostExcute方法中将该Dialog dismiss。
      onInBackground:略。前面已讲述。补充:此方法中可以使用publishProgress发布进度单元,且进度单元会发布在onProgressUpdate步骤中。
      onProgressUpdate:顾名思义就是进行进度条的更新操作。将进度单元显示在UI线程中。
      onPostExcute:略。补充:此方法的参数是doInBackground方法返回的结果。

    • AsyncTask正常运行的条件:
      ①必须在UI线程中加载AsyncTask类。
      ②必须在UI线程中创建任务实例。
      前面两点总结起来就是要在UI线程中创建AsyncTask的子类,并且必须在UI线程中实例化。
      ③在UI线程中调用excute()来执行任务。不要手动调用AsyncTask的四个步骤函数。

    • 为啥doInBackground方法中调用publishProgress,在onProgressUpdate可以实时更新进度条。
      因为在调用publishProgress之前,doInBackground的任何记忆效应对onProgressUpdate来说是可见的,而且后续的publishProgress不会影响onProgressUpdate正在进行的操作。

    • 下面展示一个异步加载图片的操作
      ①准备工作
      》访问网络图片,首先需要授予权限。Manifest.xml中节点之前添加如下语句开启APP访问网络的权限

      》请求下载网络图片需要到HttpClient这个类,但是在Android 6.0之后不再支持HttpClient,但是还是可以用,需要在APP的build.gradle中添加如下代码:

      ②代码

    package com.example.asynctask;
    
    import android.app.ProgressDialog;
    import android.content.DialogInterface;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.AsyncTask;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ImageView;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    public class MainActivity extends AppCompatActivity {
    
        private ImageView imageView;
        private Button btn;
        private String imagePath="http://img.daimg.com/uploads/allimg/190504/3-1Z504145110.jpg";
        private Bitmap bitmap;
        private MyTask myTask;
        private ProgressDialog progressDialog;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            progressDialog=new ProgressDialog(this);
            btn=(Button)findViewById(R.id.button);
            imageView=findViewById(R.id.imageview);
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);//设置进度条为水平的
            //progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            progressDialog.setButton(ProgressDialog.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
    
                }
            });
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    myTask=new MyTask();//必须实例化
                    myTask.execute(imagePath);
                }
            });
        }
    
        //三个参数分别为图片下载路径,进度条标示值大小,位图
        public class MyTask extends AsyncTask<String, Integer, Bitmap> {
    
            //异步后台执行之前的操作,后台下载提醒框
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                progressDialog.setTitle("温馨提示");
                progressDialog.setMessage("请稍后,正在下载中");
                progressDialog.show();
            }
    
            //后台执行操作
            @Override
            protected Bitmap doInBackground(final String... strings) {
                HttpClient httpClient=new DefaultHttpClient();
                HttpGet httpGet=new HttpGet(strings[0]);
                try {
                    HttpResponse httpResponse=httpClient.execute(httpGet);
                    long file_len=httpResponse.getEntity().getContentLength();//图片总大小
                    int total_len=0;//当前的大小
                    int len=0;//一次读取的大小
                    byte[] data1=new byte[1024];
                    InputStream inputStream=null;
                    if(httpResponse.getStatusLine().getStatusCode()==200){
                        //将请求返回的实体转换为字节码
                        byte []data= EntityUtils.toByteArray(httpResponse.getEntity());
                        //将字节码转为位图
                        bitmap = BitmapFactory.decodeByteArray(data,0,data.length);
                        inputStream=new ByteArrayInputStream(data);//将字节码转为流来读取图片
                        while((len=inputStream.read(data1))!=-1){
                            total_len+=len;
                            int progress_value=(int)((total_len/(float)file_len)*100);
                            System.out.println(progress_value);//测试进度条变化
                            publishProgress(progress_value);//进度条更新
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return bitmap;
            }
    
            //进度条变化,与在doInBackground中执行publishProgress方法配合使用
            @Override
            protected void onProgressUpdate(Integer... values) {
                progressDialog.setProgress(values[0]);
                super.onProgressUpdate(values);
            }
    
            //结果返回
            @Override
            protected void onPostExecute(Bitmap bitmap) {
                super.onPostExecute(bitmap);
                imageView.setImageBitmap(bitmap);//将得到的位图加载到图片组件中
                progressDialog.dismiss();//关闭进度条
            }
        }
    }
    
    
  • 相关阅读:
    Python 绘制图表方法 收藏链接
    Python 安装 numpy 以及 matplotlib 的过程
    Project Euler 31 1000-digit Fibonacci number( DP )
    red hat 6.5 红帽企业Linux.6.5 yum This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register. 解决办法
    修改system 密码
    本地服务器 windows server 2008 datacenter conn /as sysdba 提示 ora-01031 insufficient privileges
    妙用Outlook2003群发商业邮件
    批量修改文件名称
    SQl server 2012安装问题 error code 0x858C001b 解决方法
    peoplesoft function PSTREENODE 通过 deptid 获得部门树 一级部门 名称
  • 原文地址:https://www.cnblogs.com/21-T/p/10940179.html
Copyright © 2020-2023  润新知