Android开发高级进阶(二)—多线程(实现简单下载器)
2016-09-07 18:06
507 查看
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; } @Override protected 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; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); progressDialog.dismiss(); Toast.makeText(context, "下载完成", Toast.LENGTH_LONG).show(); } @Override protected 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(); } @Override protected 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; @Override protected 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); } @Override public 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
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
相关文章推荐
- Android开发高级进阶—多线程(实现简单下载器)
- 【Android游戏开发十六】Android Gesture之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能!
- Android开发学习笔记(8):浅谈Handler实现多线程和异步处理
- 【Android游戏开发十六】Android Gesture之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能!
- Android开发之简单的电子相册实现
- android网游开发之socket的简单设计和实现
- Android 3D游戏开发(高级篇)——Opengl ES游戏引擎实现(送源代码)
- 【Android游戏开发十六】Android Gesture之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能!
- android网游开发之socket的简单设计和实现
- Android开发历程_2(实现简单的乘法计算)
- Android开发(14)-- 多线程中实现利用自定义控件绘制小球并完成小球自动下落的功能
- 16—【Android游戏开发十六】Android Gesture之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能
- 【Android游戏开发十六】Android Gesture之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能!
- android游戏开发框架libgdx的使用(十八)—简单的AVG游戏效果实现
- 【Android2D游戏开发十六】(上文之触摸屏手势)详解Android Gesture 手势操作!利用手势实现一个简单切换图片的功能!
- 【Android游戏开发十六】Android Gesture之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能!
- Android 3D游戏开发(高级篇)——Opengl ES游戏引擎实现(更新完毕)
- Android高级进阶七 Android OpenGL开发四棱锥和立方体
- android UI进阶之弹窗开发--实现通讯录的弹窗效果
- android开发之多线程实现方法概述