Android AsyncTask分析
—修复內容逐渐—
由于android的UI进程是不安全的,假如你UI进程里实行一些用时每日任务,非常容易就造成程序流程奔溃。而且现阶段互联网每日任务都不可以在UI进程里实行。解决这种难题除开立即写一个进程之外,Android还出示一个AsyncTask(多线程每日任务类)来更简易的解决一些用时每日任务。
AsyncTask<>是一个抽象类,一般 用以承继,承继时必须特定三个泛型主要参数。
1、Params:运行每日任务时传到的主要参数的种类。这是一个二维数组,能够传好几个主要参数。启用时应用params[0]、params[1]、params[2]来获得。
2、Progress:后台任务进行的进展值的种类。
3、Result:后台任务实行结束回到結果的种类。
应用AsyncTask必须以下三步:
1、承继抽象类,完成一个子类,传到三个泛型主要参数。如果有主要参数不用应用应设为Void。
2、依据必须,可完成下列方式。
- doInBackground(Params…):该方式是务必的,这一方式下写的是后台管理进程要实行的每日任务,而且会在子进程运作(别的方式全是在UI进程实行)。。该方式能够启用publicProgress(Progress…values)方式升级每日任务的进展。
- onProgressUpdate(Progress… values):该方式在上一步启用publicProgress时开启。
- onPreExecute():该方式会在实行doInBackground方式前实行,用以做一些准备工作。
- onPostExecute(Result result):当doInBackground实行完毕以后,系统软件会全自动启用该方式,返回值也会传入此涵数。我们可以在这儿进行后台管理进程实行后的結果。
3、最终用新创建大家承继类后的結果,随后启用execute(Params… params)。
留意:目标务必在UI进程中建立、execute方式务必在UI进程中启用、之上四个方式都需系统软件全自动启用、每一个目标只有强制执行一次,数次启用引起出现异常。
案例
讲了那么多埋下伏笔,使我们而言个事例吧~
现在我想从互联网技术上免费下载一张图片,就应用这一AsyncTask来做一下吧~
为让全部方式都完成一次,大家用二种方式完成:1、免费下载结束后立即开展表明。2、一边载入一边表明进展,载入结束表明照片。
下边是第一种的编码,相对性简单一点,仅用了2个涵数。
public class MainActivity extends Activity { int downloadSize; int fileSize; Button bn; ImageView iv; ProgressBar progressBar; String url = "/hvtimg/bjafjc/3xglb9xf.jpg"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bn = (Button) findViewById(R.id.down); iv = (ImageView) findViewById(R.id.image); MyOnClickListener myOnClickListener = new MyOnClickListener(); bn.setOnClickListener(myOnClickListener); } class MyOnClickListener implements android.view.View.OnClickListener{ @Override public void onClick(View v) { AsyncDownload asyncDownload = new AsyncDownload(); asyncDownload.execute(url); } } class AsyncDownload extends AsyncTask<String, Integer, Bitmap> { @Override protected Bitmap doInBackground(String... params) { String imageUrl = params[0]; URL url; try { url = new URL(imageUrl); InputStream is = url.openStream(); BitmapFactory.Options op = new BitmapFactory.Options(); op.inSampleSize = 2; Bitmap bitmap = BitmapFactory.decodeStream(is, null, op); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Bitmap result) { super.onPostExecute(result); iv.setImageBitmap(result); } } }
上边的编码的作用是点一下按键,随后doInBackground后台管理保存图片,免费下载结束onPostExecute表明照片。只是应用了2个涵数,可是完成了AsyncTask的关键作用。
随后使我们感受一下可以表明进展的。
public class MainActivity extends Activity { int downloadSize; int fileSize; Button bn; ImageView iv; ProgressBar progressBar; String url = "/hvtimg/bjafjc/3xglb9xf.jpg"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bn = (Button) findViewById(R.id.down); iv = (ImageView) findViewById(R.id.image); progressBar = (ProgressBar) findViewById(R.id.bar); MyOnClickListener myOnClickListener = new MyOnClickListener(); bn.setOnClickListener(myOnClickListener); } Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { } }; class MyOnClickListener implements android.view.View.OnClickListener{ @Override public void onClick(View v) { AsyncDownload asyncDownload = new AsyncDownload(); asyncDownload.execute(url); } } class AsyncDownload extends AsyncTask<String, Integer, Void> { @Override protected Void doInBackground(String... params) { String imageUrl = params[0]; try { URL url = new URL(imageUrl); URLConnection conn = url.openConnection(); conn.connect(); InputStream is = conn.getInputStream(); fileSize = conn.getContentLength(); publishProgress(0x111); FileOutputStream fos = new FileOutputStream(getPath()); byte[] bytes = new byte[1024]; int len = -1; while((len = is.read(bytes))!=-1) { fos.write(bytes, 0, len); downloadSize =len; publishProgress(0x222); } publishProgress(0x333); is.close(); fos.close(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); switch(values[0]) { case 0x111: progressBar.setMax(fileSize); break; case 0x222: progressBar.setProgress(downloadSize); break; case 0x333: try { if(getPath().endsWith(".jpg")||getPath().endsWith(".png")){ FileInputStream fis = new FileInputStream(getPath()); iv.setImageBitmap(BitmapFactory.decodeStream(fis)); } downloadSize = 0; fileSize = 0; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } break; } } } public String getPath() { File root = getExternalCacheDir(); if (root != null) { return root.getAbsolutePath() "test.jpg"; } return null; } }
这儿完成的作用是立即下载按键,后台管理从互联网技术载入文档,最先获得图片大小,设定progressbar最高值,随后一边免费下载、一边存进当地、一边设定progressbar的值,完成时间轴。免费下载结束从当地获得照片表明出去。这一次多应用了表明进展的涵数onProgressUpdate。
实际上,onProgressUpdate这一涵数一般我们在线程里用到Handler来完成。
在AsyncTask给大家把平时应用进程开展多线程实际操作的常用物品装包在一起了,不得不承认的确省了一些事。
事实上可以用AsyncTask完成的物品彻底能够立即用进程来完成~
我还在些第二个编码的情况下写顺了手,用Handler完成了一遍,大伙儿在下面能够看一下。
public class MainActivity extends Activity { int downloadSize; int fileSize; Button bn; ImageView iv; ProgressBar progressBar; String url = "/hvtimg/bjafjc/3xglb9xf.jpg"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bn = (Button) findViewById(R.id.down); iv = (ImageView) findViewById(R.id.image); progressBar = (ProgressBar) findViewById(R.id.bar); MyOnClickListener myOnClickListener = new MyOnClickListener(); bn.setOnClickListener(myOnClickListener); } Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { switch(msg.what) { case 0x111: progressBar.setMax(fileSize); break; case 0x222: progressBar.setProgress(downloadSize); break; case 0x333: try { if(getPath().endsWith(".jpg")||getPath().endsWith(".png")){ FileInputStream fis = new FileInputStream(getPath()); iv.setImageBitmap(BitmapFactory.decodeStream(fis)); } downloadSize = 0; fileSize = 0; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } break; } } }; class MyOnClickListener implements android.view.View.OnClickListener{ @Override public void onClick(View v) { AsyncDownload asyncDownload = new AsyncDownload(); asyncDownload.execute(url); } } class AsyncDownload extends AsyncTask<String, Integer, Void> { @Override protected Void doInBackground(String... params) { String imageUrl = params[0]; try { URL url = new URL(imageUrl); URLConnection conn = url.openConnection(); conn.connect(); InputStream is = conn.getInputStream(); fileSize = conn.getContentLength(); handler.sendEmptyMessage(0x111); FileOutputStream fos = new FileOutputStream(getPath()); byte[] bytes = new byte[1024]; int len = -1; while((len = is.read(bytes))!=-1) { fos.write(bytes, 0, len); downloadSize =len; handler.sendEmptyMessage(0x222); } handler.sendEmptyMessage(0x333); is.close(); fos.close(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } } public String getPath() { File root = getExternalCacheDir(); if (root != null) { return root.getAbsolutePath() "test.jpg"; } return null; } }
喔喔喔喔,就到这儿吧~