安卓——AsyncTask初学(AsyncTask作为独立类和内部类实现图片下载)

异步任务:

安卓的单线程模型

耗时的任务放在其他线程

AsyncTask

在子线程中更新UI

封装、简化异步操作




目的:



图片转化成流:基本的网络操作




上面是慕课网的AsyncTask的讲解(https://www.imooc.com/learn/377),老师把继承了AsyncTask的子类写做内部类,下面我来展示一下独立类的写法



AsyncTask作为独立类

我要感谢这篇博客https://blog.csdn.net/shadow066/article/details/17380399,它用了接口的回调实现


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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.lenovo.androidasynctask.MainActivity">


    <ImageView
        android:layout_weight="100"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/image"
        />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/button"
        android:text="下载图片"
        />
</LinearLayout>

然后是一个接口,这个很重要

TaskListener.java

package com.example.lenovo.androidasynctask;

import android.graphics.Bitmap;

/**
 * Created by lenovo on 2018/3/22.
 */

public interface TaskListener {
    public void onCompletedListener(Bitmap result);
}

MainActivity.java

在按钮点击事件中new一个Mytask类,加上构造参数并执行我们图片的目标地址。

然后在里面实现一下接口的抽象方法onCompletedListener()方法,这个方法的参数就是下载的图片以bitmap形式存储的。然后在方法里给ImageView填充图片。

package com.example.lenovo.androidasynctask;

import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

    private ProgressDialog dia;
    String picture = "http://b.hiphotos.baidu.com/image/pic/item/908fa0ec08fa513d17b6a2ea386d55fbb2fbd9e2.jpg";
    private Button button;
    private ImageView imageView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button=(Button)findViewById(R.id.button);
        imageView=(ImageView)findViewById(R.id.image);



        dia=new ProgressDialog(this);


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                imageView.setImageBitmap(null);
                new Mytask(dia,MainActivity.this,new TaskListener(){

                    @Override
                    public void onCompletedListener(Bitmap result) {
                        imageView.setImageBitmap(result);
                    }
                }).execute(picture);
            }
        });
    }
}

最后是继承了AsyncTask的独立类Mytask

这个类的构造方法有三个参数(ProgressDialog,Context,TaskListener),第三个参数就是我们可爱的接口

当任务执行完后,在onPostExecute()方法中调用TaskListener接口中的onCompletedListenr()方法,放心我们会在MainActivity的点击事件实现这个方法的。

package com.example.lenovo.androidasynctask;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

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 android.content.Context;
import android.os.AsyncTask;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;
import android.widget.ProgressBar;

import com.example.*;

/**
 * Created by lenovo on 2018/3/22.
 */

public class Mytask extends AsyncTask<String ,Integer,Bitmap> {

    private Context context;
    private TaskListener taskListener;
    private ProgressDialog dia;

    //MyTask的构造方法
    public Mytask(ProgressDialog dias,Context context, TaskListener listener) {
        super();
        dia=dias;
        this.context = context;
        this.taskListener = listener;
    }

    //在doInBackground()方法执行前调用,主要执行一些初始化的工作,在UI线程中执行
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        dia.setTitle("提示信息");
        dia.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dia.setCancelable(false);
        dia.show();
    }

    //干活的代码写在这里
    @Override
    protected Bitmap doInBackground(String... strings) {
        Bitmap bitmap=null;
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        InputStream inputStream=null;

        try{
         HttpClient httpClient = new DefaultHttpClient();
         HttpGet httpGet = new HttpGet(strings[0]);
         HttpResponse httpResponse = httpClient.execute(httpGet);
         if(httpResponse.getStatusLine().getStatusCode()==200){
             inputStream = httpResponse.getEntity().getContent();
             //先获得文件的总长度

             long file_length = httpResponse.getEntity().getContentLength();
             int len=0;
             byte [] data =new byte[1024];
             int total_length=0;
             int value=0;
             while((len = inputStream.read(data))!=-1){
                 total_length+=len;
                 value=(int)((total_length/(float)file_length)*100);
                 //调用updata函数,跟新进度
                 publishProgress(value);
                 outputStream.write(data,0,len);
             }
             byte[] result =outputStream.toByteArray();
             bitmap= BitmapFactory.decodeByteArray(result,0,result.length);
         }
        }
        catch (Exception e){
                e.printStackTrace();
        }finally {
            if(inputStream!=null){
                try{
                    inputStream.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
        return bitmap;
    }

    //更新进度条
    //在任务执行过程中调用publishProgress()方法报告进度,此方法被调用,并在UI县城中执行
    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        dia.setProgress(values[0]);
    }

    //在工作完成后次方法被调用,在UI线程中执行
    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
        dia.dismiss();
        taskListener.onCompletedListener(result);
    }

    @Override
    protected void onCancelled(Bitmap result) {
        super.onCancelled(result);
    }
}

这期间还遇到了几个小插曲


上图总的doInbackground()方法中那些http的类,我也不知道用的哪个jar包,总之在上图右边的libs我把要用的都加上了,有想要的在评论里留下邮箱哦。


然后这么多jar包在一块就变异出错了,出错的话看这俩博客

1.解决了jar包里重复文件的问题

https://www.cnblogs.com/skyeblogs/p/8514187.html


2.解决了

Error:Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.

> More than one file was found with OS independent path 'META-INFXXX'

https://blog.csdn.net/pyfysf/article/details/78486201

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水之积也不厚,则其负大舟也无力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值