Android Async异步操作实例---加载网络图片(慕课网笔记)

来源:互联网 发布:大数据架构师指南 pdf 编辑:程序博客网 时间:2024/06/07 12:44

来自:http://www.imooc.com/learn/377
实例1 实现网络图片加载及进度条提示
这里写图片描述
1.1 布局文件
image.xml包括一个progressbar和imageview,activity_main.xml包括一个imagetest按钮;
image.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:padding="16dp"     android:layout_width="match_parent"    android:layout_height="match_parent">    <ImageView        android:id="@+id/id_image"        android:layout_width="match_parent"        android:layout_height="match_parent" />    <ProgressBar        android:id="@+id/id_progressbar"        android:visibility="gone"        android:layout_centerInParent="true"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></RelativeLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent">    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="loadImage"        android:text="ImageTest"        android:id="@+id/id_imagetest" />  </LinearLayout>

1.2 image.xml的代码实现,即ImageTest.java

public class ImageTest  extends Activity{    private ImageView mImageView;    private ProgressBar mProgressBar;    private static String URL = "https://images.unsplash.com/photo-1448975750337-b0290d621d6d?crop=entropy&fit=crop&fm=jpg&h=775&ixjsv=2.1.0&ixlib=rb-0.3.5&q=80&w=1600";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.image);        initView();        new MyAsyncTask().execute(URL);//调用MyAsyncTask异步任务    }    private void initView() {        mImageView = (ImageView)findViewById(R.id.id_image);        mProgressBar = (ProgressBar)findViewById(R.id.id_progressbar);    }    //新建一个内部类,实现AsyncTask异步操作    /*    * 第一个参数是执行AsyncTask时需要传入的参数,在这里我们传入的是一个URL;第二个参数是指后台执行任务时,如果需要在界面上显示进度,则使用    * 这里的泛型作为进度单位;第三个是后台任务成功后返回的结果的类型,我们在这里返回一个图片即可    * */    class MyAsyncTask extends AsyncTask<String, Void, Bitmap>    {        //在后台任务开始前调用,用于进行一些在界面上的初始化操作,在这里我们显示一个进度条        @Override        protected void onPreExecute() {            super.onPreExecute();            mProgressBar.setVisibility(View.VISIBLE);        }        //后台任务执行完毕后就调用这个方法,这个方法的参数就是执行后台任务的doInBackground的返回参数,        //我们就可以进行UI操作了,显示出我们设置的网络图像        @Override        protected void onPostExecute(Bitmap bitmap) {            super.onPostExecute(bitmap);            mProgressBar.setVisibility(View.GONE);//隐藏进度条            mImageView.setImageBitmap(bitmap);//显示图像        }        //doInBackground里面的操作是在另外一个线程中执行的        @Override        protected Bitmap doInBackground(String... params) {//耗时操作的任务都放在这里,接收一个可变长度的数组            String url = params[0];//我们这里只传递了一个参数,取出params数组中的URL            Bitmap bitmap = null;            URLConnection connection;            InputStream is;            try {                connection = new URL(url).openConnection();                is = connection.getInputStream();                BufferedInputStream bis = new BufferedInputStream(is);                Thread.sleep(2000);//由于只加载一个图片,加载速度还是比较快的,看不出来进度条,我们设置一个睡眠,人为的放慢加载速度                bitmap = BitmapFactory.decodeStream(bis);//将获取的输入流解析成bitmap                is.close();                bis.close();            } catch (IOException e) {                e.printStackTrace();            } catch (InterruptedException e) {                e.printStackTrace();            }            return bitmap;        }    }}

1.3 MainActivity.java

public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    //Image Test按钮的点击事件    public void loadImage(View v)    {        startActivity(new Intent(this, ImageTest.class));    }}

实例2 模拟进度条的更新
效果:
这里写图片描述
2.1 新建progressbar.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"    android:layout_height="match_parent">    <ProgressBar        style="?android:attr/progressBarStyleHorizontal"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/id_pg"        android:layout_centerVertical="true"        android:layout_centerHorizontal="true" /></RelativeLayout>

2.2 新建ProgressBarTest.java,引入progressbar.xml

public class ProgressBarTest extends Activity{    private ProgressBar mProgressBar;    private MyAsyncTask mTask;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.progressbar);        mProgressBar = (ProgressBar)findViewById(R.id.id_pg);        mTask = new MyAsyncTask();        mTask.execute();    }    //我们需要更新进度条,因此第二个参数为整型    class MyAsyncTask extends AsyncTask<Void,Integer,Void>    {        @Override        protected Void doInBackground(Void... params) {            for (int i=0; i<100; i++)//设置一个循环,模拟进度条更新            {                publishProgress(i);                try {                    Thread.sleep(300);//放慢速度                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            return null;        }        /*        * 在后台任务中调用了publishProgress方法后,就调用此方法,方法中的参数就是后台任务重传递过来的        * 在这个方法中可以对UI进行操作,利用参数中的数值对UI进行相应的更新        * */        @Override        protected void onProgressUpdate(Integer... values) {            super.onProgressUpdate(values);            mProgressBar.setProgress(values[0]);//获取进度更新值        }    }}

2.3 在主界面布局中添加一个按钮,并添加此按钮的点击事件即可
activity_main.xml

<Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="loadProgress"        android:text="ProgressTest"        android:id="@+id/id_progresstest" />

MainActivity.java

public void loadProgress(View v)    {        startActivity(new Intent(this, ProgressBarTest.class));    }

实例3 如何取消AsyncTask
实例2中存在一个问题,就是点击ProgressTest按钮之后开始显示进度条,这时候点击返回键,再点击ProgressTest按钮,发现进度条并没有变化,原因在于点击返回键之前上一个进度条进程的循环还没有走完,必须等上一个进程的进度条走完后才能继续本次的进度条。因此,这里我们要解决这个问题。就是将进度条的生命周期和activity的生命周期绑定。
修改一下ProgressBarTest.java

public class ProgressBarTest extends Activity{    private ProgressBar mProgressBar;    private MyAsyncTask mTask;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.progressbar);        mProgressBar = (ProgressBar)findViewById(R.id.id_pg);        mTask = new MyAsyncTask();        mTask.execute();    }    **@Override    protected void onPause() {        super.onPause();        //如果不为空而且正在运行        if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING)        {            mTask.cancel(true);//cancel方法只是将当前的AsyncTask标记为cancel状态,并不会取消本次线程        }    }**    //我们需要更新进度条,因此第二个参数为整型    class MyAsyncTask extends AsyncTask<Void,Integer,Void>    {        @Override        protected Void doInBackground(Void... params) {            for (int i=0; i<100; i++)//设置一个循环,模拟进度条更新            {                **if (isCancelled())//判断当前线程是否被我们标记为了cancel状态                {                    break;                }**                publishProgress(i);                try {                    Thread.sleep(300);//放慢速度                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            return null;        }        /*        * 在后台任务中调用了publishProgress方法后,就调用此方法,方法中的参数就是后台任务重传递过来的        * 在这个方法中可以对UI进行操作,利用参数中的数值对UI进行相应的更新        * */        @Override        protected void onProgressUpdate(Integer... values) {            super.onProgressUpdate(values);            **if (isCancelled())            {                return;            }**            mProgressBar.setProgress(values[0]);//获取进度更新值        }    }}

效果图:
这里写图片描述
源码在这里:http://download.csdn.net/detail/hnyzwtf/9373907

0 0
原创粉丝点击