Android开发高级进阶(二)—多线程(实现简单下载器)

来源:互联网 发布:xp telnet 23端口打开 编辑:程序博客网 时间:2024/06/07 13:00

AsyncTask

AsyncTask适用于简单的异步处理,不需要借助线程和Handler即可实现。

AsyncTask

使用AsyncTask的步骤:

创建AsyncTask的子类,并为三个泛型参数指定类型。如果某个泛型参数不需要指定类型,则可将它指定为void。

根据需要实现以下方法:

  • doInBackground(Params…):后台线程将要完成的任务。该方法可以调用
  • publishProgress(Progress… values)方法更新任务的执行进度。
  • onProgressUpdate(Progress… values):在doInBackground()方法中调用publishProgress()方法更新任务的执行进度后,将会触发该方法。
  • onPreExecute():该方法将在执行后台耗时操作前被调用。通常用于完成一些初始化准备工作。
  • onPostExecute(Result result):当doInBackground()完成后,系统会自动调用onPostExecute()方法,并将doInBackground()方法的返回值传给该方法。

调用AsyncTask子类的实例的execute(Params… params)开始执行耗时任务。
这里通过实现一个简单的下载器来学习AsyncTask。

这个下载器就一个界面,包含一个输入框,用来输入下载地址,一个按钮,用来开始下载。

界面代码如下:activity_download.xml

<?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:layout_marginLeft="16dp"android:layout_marginTop="16dp"tools:context="com.trampcr.downloaddemo.MainActivity"><EditText    android:id="@+id/et_url"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_marginTop="20dp"    android:hint="请输入下载地址" /><Button    android:id="@+id/btn_start_download"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_below="@id/et_url"    android:layout_centerHorizontal="true"    android:layout_marginTop="50dp"    android:background="@drawable/button_style"    android:text="开始下载"    android:textColor="#000000" /></RelativeLayout>

里是自定义按钮的形状。代码如下:button_style.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><corners android:topLeftRadius="10dp"    android:radius="8dp"    android:topRightRadius="10dp"    android:bottomLeftRadius="10dp"    android:bottomRightRadius="10dp" /><stroke android:color="#000000"    android:width="0.7dp"/></shape>

根据上面的步骤,第一步是实现AsyncTask的子类,代码如下:DownloadAsyncTask.java

public class DownloadAsyncTask extends AsyncTask<URL, Integer, String> {private ProgressDialog progressDialog;private int hasRead = 0;private Context context;public DownloadAsyncTask(Context context) {    this.context = context;}@Overrideprotected String doInBackground(URL... params) {    try {        URLConnection urlConnection = params[0].openConnection();        InputStream inputStream= urlConnection.getInputStream();        String downloadFolderName = Environment.getExternalStorageDirectory() + File.separator + "trampcr" + File.separator;        File file = new File(downloadFolderName);        if (!file.exists()){            file.mkdir();        }        String fileName = downloadFolderName + "zxm.apk";        File apkFile = new File(fileName);        if (apkFile.exists()) {            apkFile.delete();        }        byte[] buff = new byte[1024];        int length = 0;        OutputStream outputStream = new FileOutputStream(fileName);        while ((length = inputStream.read(buff)) != -1) {            outputStream.write(buff, 0, length);            hasRead++;            publishProgress(hasRead);        }        outputStream.close();        inputStream.close();    } catch (IOException e) {        e.printStackTrace();    }    return null;}@Overrideprotected void onPostExecute(String s) {    super.onPostExecute(s);    progressDialog.dismiss();    Toast.makeText(context, "下载完成", Toast.LENGTH_LONG).show();}@Overrideprotected void onPreExecute() {    super.onPreExecute();    progressDialog = new ProgressDialog(context);    //设置对话框标题    progressDialog.setTitle("任务正在进行中");    //设置对话框显示的内容    progressDialog.setMessage("正在下载,请稍等...");    //设置对话框的取消按钮    progressDialog.setCancelable(true);    //设置进度条的最大值    progressDialog.setMax(2000);    //设置进度条风格    progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);    //设置对话框的进度条是否显示进度    progressDialog.setIndeterminate(false);    progressDialog.show();}@Overrideprotected void onProgressUpdate(Integer... values) {    super.onProgressUpdate(values);    //更新进度    progressDialog.setProgress(values[0]);   }}

这里在onPreExecute()方法中实现了初始化并显示进度对话框,在doBackground()方法通过读文件、写文件完成下载任务,并调用publishProgress()方法发出更新进度,在onProgressUpdate()方法中执行更新进度,在onPostExecute()方法中销毁进度条对话框,并弹出Toast提示下载完成。

DownloadActivity.java

public class DownloadActivity extends AppCompatActivity implements View.OnClickListener{//    public static final String DOWNLOAD_URL = "http://psoft.33lc.com:801/small/rootexplorer_33lc.apk";private Button mBtnStartDownload;private EditText mEtUrl;private String mUrl;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_download);    mEtUrl = (EditText) findViewById(R.id.et_url);    mBtnStartDownload = (Button) findViewById(R.id.btn_start_download);    mBtnStartDownload.setOnClickListener(this);}@Overridepublic void onClick(View v) {    mUrl = mEtUrl.getText().toString().trim();    DownloadAsyncTask downloadAsyncTask = new DownloadAsyncTask(DownloadActivity.this);    try {//            downloadAsyncTask.execute(new URL(DOWNLOAD_URL));        downloadAsyncTask.execute(new URL(mUrl));    } catch (MalformedURLException e) {        e.printStackTrace();        }     }}

上一步实现了AsyncTask的子类,这一步就需要创建该子类的实例,并执行execute()开始执行任务。

所需要的权限:

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

效果图如下:

文/trampcr(简书作者)
原文链接:http://www.jianshu.com/p/6a558a23084a
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

0 0
原创粉丝点击