zoukankan      html  css  js  c++  java
  • AsyncTask的使用

    加载一张网络图片

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
        private ImageView iv;
        private ProgressBar pb;
        private Button btn;
        public static final String URL = "http://pic3.zhongsou.com/image/38063b6d7defc892894.jpg";
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            iv = (ImageView) findViewById(R.id.iv);
            pb = (ProgressBar) findViewById(R.id.pb);
            btn = (Button) findViewById(R.id.enter_progress);
    
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    intent.setClass(MainActivity.this,ProgressBarActivity.class);
                    startActivity(intent);
                }
            });
    
            new MyAsyncTask().execute(URL);
        }
    
        /**
         * 方法执行顺序
         * onPreExecute()
         * doInBackground(String... params),里面回调publishProgress()方法会使用onProgressUpdate(Void... values)
         * onPostExecute(Bitmap bitmap)
         * */
    
        //内部类
        class MyAsyncTask extends AsyncTask<String,Void,Bitmap> {
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                pb.setVisibility(View.VISIBLE);
            }
    
            @Override
            protected Bitmap doInBackground(String... params) {
                //可以写入多个值params[1],params[2].....
                String url = params[0];
                Bitmap bitmap = null;
                URLConnection connection ;
                InputStream is ;
                try {
                    connection = new URL(url).openConnection();
                    is = connection.getInputStream();
                    BufferedInputStream bis = new BufferedInputStream(is);
                    bitmap = BitmapFactory.decodeStream(bis);
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    is.close();
                    bis.close();
    
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return bitmap;
            }
    
            @Override
            protected void onPostExecute(Bitmap bitmap) {
                super.onPostExecute(bitmap);
                pb.setVisibility(View.GONE);
                iv.setImageBitmap(bitmap);
            }
    
            @Override
            protected void onProgressUpdate(Void... values) {
                super.onProgressUpdate(values);
            }
        }
    }

    记得在AndroidManifest.xml里面添加访问网络的权限

    <uses-permission android:name="android.permission.INTERNET" />

    activity_main.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".MainActivity">
        <Button
            android:text="Enter"
            android:id="@+id/enter_progress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
        <ImageView
            android:id="@+id/iv"
            android:background="#e6c7c7"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <ProgressBar
            android:id="@+id/pb"
            android:visibility="gone"
            android:layout_centerInParent="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </RelativeLayout>

    运行效果

    模拟更新进度条

    ProgressBarActivity.java

    public class ProgressBarActivity extends AppCompatActivity {
        private ProgressBar pb;
        private MyAsync myAsync;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_progress_bar);
    
            pb = (ProgressBar) findViewById(R.id.pb_simulate);
            myAsync = new MyAsync();
            myAsync.execute();
        }
    
        /**
         点击'加载进度条'按钮后程序看起来运行正常.但是,正如上面图示,如果接着点击BACK键,紧接
         着再次点击'加载进度条'按钮,会发现进度条的进度一直是零,过了一会才开始更新.这是为什么呢?
         根据上述的讲解,我们知道,AsyncTask是基于线程池进行实现的,当一个线程没有结束时,后面的线程是
         不能执行的.所以必须等到第一个task的for循环结束后,才能执行第二个task.我们知道,当点击BACK键
         时会调用Activity的onPause()方法.为了解决这个问题,我们需要在Activity的onPause()方法中将正在
         执行的task标记为cancel状态,在doInBackground方法中进行异步处理时判断是否是cancel状态来决定是
         否取消之前的task.
         * */
    
        @Override
        protected void onPause() {
            super.onPause();
            if (myAsync != null && myAsync.getStatus() == AsyncTask.Status.RUNNING) {
                //cancel方法只是将对应的AsyncTask标记为cancel状态,并不是真正的取消线程的执行.
                myAsync.cancel(true);
            }
        }
    
        class MyAsync extends AsyncTask<Void, Integer, Void> {
    
            //不能在这里更新UI
            @Override
            protected Void doInBackground(Void... params) {
                //模拟进度更新
                for (int i = 0; i < 100; i++) {
                    //如果task是cancel状态,则终止for循环,以进行下个task的执行.
                    if (isCancelled()){
                        break;
                    }
                    publishProgress(i);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
    
    
                return null;
            }
    
            @Override
            protected void onProgressUpdate(Integer... values) {
                super.onProgressUpdate(values);
                if (isCancelled()) {
                    return;
                }
    
                //values的值是publishProgress(i)中i的值,0表示第一个值
                pb.setProgress(values[0]);
            }
        }
    }

    activity_progress_bar.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:orientation="vertical"
        tools:context="my.com.example.x550v.asynctaskdemo.ProgressBarActivity">
        <ProgressBar
            style="?android:attr/progressBarStyleHorizontal"
            android:id="@+id/pb_simulate"
            android:layout_gravity="center"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    </LinearLayout>

    运行效果

  • 相关阅读:
    什么是浮动IP
    How can I detect multiple logins into a Django web application from different locations?
    git add -A使用说明
    理解水平扩展和垂直扩展
    php != 和 !== 的区别
    wireshark:Couldn't run /usr/bin/dumpcap in child process: Permission denied
    Unable to VNC onto Centos server remotely
    systemctl使用说明
    KiB、MiB与KB、MB的区别
    python带setup.py的包的安装
  • 原文地址:https://www.cnblogs.com/tianhengblogs/p/5251587.html
Copyright © 2011-2022 走看看