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>

 

运行效果

 

posted @ 2016-03-07 19:23  玉天恒  阅读(227)  评论(0编辑  收藏  举报