AsyncTask专题三之趁热打铁 从网络上下载图片

现在正是我们趁热打铁的好时机,赶紧的,板凳放好,瓜子,咖啡自备,小王要撸一发(~~别误会,我说的是撸代码)
有了前面的基础,我们来动手开发一个很小的应用,为啥说他小呢,一个界面就可以了,但是麻雀虽小,五脏俱全。
我们要用到什么知识呢?
1)网络访问 HttpURLConnection(新知识)
2)AsyncTask
3)任务的进度显示
学以致用嘛,学过的东西要用才能成为自己的
4)任务的取消(新知识)
5)接口回调(新知识)

至于为啥不用HttpClient呢,是这样的高版本的android已经不再提供对HttpClient的支持了,另外如果需要用HttpClient需要导入jar包
一个关键点,如果要让我们的应用支持网络访问,必须加上网络的权限 在 清单文件中去加AndroidMenifest.xml中
稍后会说到。
关于上面的东西,如果不会了,可以查询相关资料。这些网络上都有。
第一步:准备材料,下载图片我们总要知道图片的地址吧
以火狐浏览器为例:打开百度图片,右键,选择复制图片地址,OK
第二步:
界面布局设计:
下载前:
下载图片
下载后:
这里写图片描述
两个按钮Button:下载,取消
一个视图ImageView 显示下载的图片
一个ProgressBar 显示进度
一个TextView: 用于显示进度的百分比
布局代码:

<?xml version="1.0" encoding="utf-8"?>
<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="com.cc.myapplication.MainActivity">

    <Button
        android:id="@+id/btn_download"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onBtnClick"
        android:text="下载图片"
        />

    <Button
        android:id="@+id/btn_cancle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:onClick="onBtnClick"
        android:text="取消下载"/>

    <ImageView
        android:id="@+id/image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_download"
        android:layout_centerHorizontal="true"
        android:adjustViewBounds="true"
        android:maxHeight="300dp"
        android:maxWidth="300dp"/>

    <ProgressBar
        android:id="@+id/pro_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/image_view"
        android:visibility="visible"
        />

    <TextView
        android:id="@+id/tv_progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@id/pro_bar"
        android:text="进度"

        />
</RelativeLayout>

MainActivity.java

package com.cc.myapplication;

import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.cc.async.MyAsyncTask;
import com.cc.utils.URLContant;

public class MainActivity extends AppCompatActivity {
    private ImageView mImageView;
    private ProgressBar mProgressBar;
    private TextView mTextView;
    private MyAsyncTask mAsyncTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获取控件
        initView();


    }
    public void initView(){
        mImageView = (ImageView) findViewById(R.id.image_view);
        mProgressBar = (ProgressBar) findViewById(R.id.pro_bar);
        mTextView = (TextView) findViewById(R.id.tv_progress);
    }

    public void onBtnClick(View view){
        switch (view.getId()){
            case R.id.btn_download:
                //启动异步任务下载图片
                mAsyncTask = new MyAsyncTask(new MyAsyncTask.MyCallback() {
                    @Override
                    public void sendImageData(byte[] bytes) {
                        //doinbackground()执行完成就返回图片
                        mImageView.setImageBitmap(BitmapFactory.decodeByteArray(bytes,0,bytes.length));

                        //当下载完毕,就把进度条,和 进度状态显示栏隐藏掉
                        mProgressBar.setVisibility(View.GONE);
                        mTextView.setVisibility(View.GONE);
                    }

                    @Override
                    public void sendProgress(Integer... values) {
                        int current = values[0];
                        int total = values[1];
                        //更新进度条
                        mProgressBar.setProgress(current);
                        mProgressBar.setMax(total);
                        //更新进度条状态
                        mTextView.setText(100*current/total + "%");
                    }
                });
                //执行异步任务
                mAsyncTask.execute(URLContant.IMAGE_URL);
                break;
            case R.id.btn_cancle:
                //取消下载
                //只能取消正在执行的,如果mAsyncTask已执行完毕,或者已经取消掉,都不能再取消
                if (mAsyncTask != null){
                    mAsyncTask.cancel(true);
                }
                break;
        }

    }
}

MyAsyncTask主要处理网络下载图片,并通过接口回调的方法,返回结果到MainActivity中 更新 ImageView 和 progressbar TextView

package com.cc.async;

import android.os.AsyncTask;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Created by My on 2016/7/10.
 */
public class MyAsyncTask extends AsyncTask<String, Integer, byte[]> {
    private MyCallback mMyCallback;
    public MyAsyncTask(MyCallback mMyCallback){
        this.mMyCallback = mMyCallback;
    }

    @Override
    protected void onPreExecute() {

    }

    @Override
    protected byte[] doInBackground(String... params) {
        String baseUrl = params[0];
        //网络下载
        if (baseUrl != null && baseUrl.length() > 0) {
            try {
                URL url = new URL(baseUrl);
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                //如果请求码==200就继续
                if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    InputStream inputStream = urlConnection.getInputStream();
                    //使用内存流
                    ByteArrayOutputStream bStream = new ByteArrayOutputStream();
                    int len = 0;
                    //当前下载量
                    int current = 0;
                    //通过连接对象调用getContentLength()获取图片的总大小
                    int total = urlConnection.getContentLength();
                    byte[] data = new byte[1024];
                    while ((len = inputStream.read(data)) != -1) {
                        bStream.write(data, 0, len);
                        current += len;
                        //发布进度,每发送一次,onProgressUpdate就会执行一次,也就会把值
                        //通过接口回调的方式发送给MainActivity,更新UI界面的进度条,进度百分比
                        publishProgress(current,total);
                    }
                    //返回下载的图片内容
                    return bStream.toByteArray();
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
//当doInBackground()方法执行完成后,代表图片已经下载完毕,而 onPostExecute
    //中的参数其实就是图片的数据
    @Override
    protected void onPostExecute(byte[] bytes) {
        if (bytes != null && bytes.length > 0){
            //下载完成后,向MainActivity返回数据,使用接口回调
            mMyCallback.sendImageData(bytes);
        }
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        if (values != null && values.length > 0){
            //向MainActivity返回数据,使用接口回调
            mMyCallback.sendProgress(values);
        }
    }
//自定义接口,用于不同类之间传递数据
    public interface MyCallback{
    //发送数据,谁实现,谁获取
        void sendImageData(byte[] bytes);
        void sendProgress(Integer... values);
    }
}

最后最最重要的是别忘了,加网络权限:

<uses-permission android:name="android.permission.INTERNET"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值