Android开发AsyncTask异步处理任务
转自: http://android.tgbus.com/Android/tutorial/201109/369193.shtml

  在开发Android应用时必须遵守单线程模型的原则:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。在单线程模型中始终要记住两条法则:

  1.不要阻塞UI线程
  2.确保只在UI线程中访问Android UI工具包

  当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。

  比如说从网上获取一个网页,在一个TextView中将其源代码显示出来,这种涉及到网络操作的程序一般都是需要开一个线程完成网络访问,但是在获得页面源码后,是不能直接在网络操作线程中调TextView.setText()的因为其他线程中是不能直接访问主UI线程成员。

  Android提供了几种在其他线程中访问UI线程的方法。

  java代码:
  Activity.runOnUiThread( Runnable )
  View.post( Runnable )
  View.postDelayed( Runnable, long )

  Hanlder
  这些类或方法同样会使你的代码很复杂很难理解。然而当你需要实现一些很复杂的操作并需要频繁地更新UI时这会变得更糟糕。

  为了解决这个问题,Android 1.5提供了一个工具类:AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单。不需要借助线程和Handler即可实现。

  AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。
  Params 启动任务执行的输入参数,比如HTTP请求的URL。
  Progress 后台任务执行的百分比。
  Result 后台执行任务最终返回的结果,比如String。

  AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。

  1) 子类化AsyncTask
  2) 实现AsyncTask中定义的下面一个或几个方法

  onPreExecute(), 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。

  doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。

  onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。

  onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread。

  为了正确的使用AsyncTask类,以下是几条必须遵守的准则:

  1) Task的实例必须在UI thread中创建
  2) execute方法必须在UI thread中调用
  3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
  4) 该task只能被执行一次,否则多次调用时将会出现异常

=========== 以下是自己写的代码 ==================

代码 写道 package com.aking86.test_asynctask;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends Activity {

MyTask myTask;
String tag = "MainActivity";
String msg = "--- ";

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
printMethodName();

myTask = new MyTask();
dispost(new String[] { "TASKADD|T-1001", "TASKADD|T-1002" });
dispost(" TASKUPDATE|T-2001");

// myTask.cancel(true);
// new MyTask().execute(" TASKUPDATE|T-2001");

// try {
// myTask.wait();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
//
// try {
// myTask.wait(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }

}

private Long dispost(String... params) {

if (myTask == null) {
myTask = new MyTask();
}

AsyncTask.Status status = myTask.getStatus();
Log.i(tag, msg + " Status: " + status.toString() + " ordinal: "
+ status.ordinal());

switch (status) {
case PENDING:
myTask.execute(params);
// try {
// return myTask.execute(params).get(); // 耗时的操作
// } catch (InterruptedException e) {
// e.printStackTrace();
// } catch (ExecutionException e) {
// e.printStackTrace();
// }
break;
case RUNNING:
break;
case FINISHED:
break;
}
return null;
}

/**
* 打印运行的方法的名称
*/
private void printMethodName() {
Log.i(tag, msg + new Exception().getStackTrace()[1].getMethodName());
}

/**
* 结束进程
*/
private void killProcess() {
android.os.Process.killProcess(android.os.Process.myPid());
}

/**
* 异步任务<br>
* // AsyncTask<Params, Progress, Result>
* <p>
* 当Activity 销毁onDestory()时,MyTask可能还在运行;<br>
* 当 killProcess 时,MyTask 全部被杀死;<br>
* 如果一个 MyTask 实例发生了异常,其它MyTask实例也会被结束掉;<br>
* 如果想在 onDestory()时关掉MyTask,可以killProcess;<br>
* 执行顺序: onPreExecute(), doInBackground(...),onPostExecute(.)<br>
*/
private class MyTask extends AsyncTask<String, Void, Long> {

String tag = "MyTask";
String msg = "--- ";

@Override
protected void onPreExecute() {
Log.i(tag, msg + new Exception().getStackTrace()[0].getMethodName());
super.onPreExecute();
}

@Override
protected Long doInBackground(String... params) {
Log.i(tag, msg + new Exception().getStackTrace()[0].getMethodName());
int i = 0;
while (i < 10) {
if (i < params.length)
Log.i(tag, msg + params[i++] + " " + (i++));
else
Log.i(tag, msg + params[0] + " " + (i++) + " OK...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return (long) params.length;
}

@Override
protected void onPostExecute(Long result) {
Log.i(tag, msg + new Exception().getStackTrace()[0].getMethodName());
super.onPostExecute(result);
}

@Override
protected void onCancelled() {
Log.i(tag, msg + new Exception().getStackTrace()[0].getMethodName());
super.onCancelled();
}

@Override
protected void onProgressUpdate(Void... values) {
Log.i(tag, msg + new Exception().getStackTrace()[0].getMethodName());
super.onProgressUpdate(values);
}

}

@Override
protected void onDestroy() {
printMethodName();
killProcess(); // 销毁时, 结束进程
super.onDestroy();
}

}

更多相关文章

  1. Android文本输入框EditText属性和方法说明
  2. Android内部存储和外部存储的获取方法
  3. 在本地UI使用webview,在html页面用js与android通信方法。
  4. Java、Android中的回调使用 Java回调方法
  5. android设置屏幕禁止休眠的方法
  6. Android中使用Streams的两种方法
  7. 我的Android进阶之旅------>Ubuntu下不能识别Android设备的解决
  8. 动态修改Android参数信息的方法绕过改机检测
  9. android 横竖屏限制的配置方法

随机推荐

  1. ch026 Android(安卓)Socket
  2. Android菜鸟的成长笔记(15)—— Android中
  3. android的布局练习
  4. Android真的很火吗?
  5. Android(安卓)Linux 内核介绍
  6. android 选中效果xml文件
  7. Android进程 Handler Message Looper
  8. Android(安卓)Socket 发送广播包的那些坑
  9. android 设置主页面的方式
  10. Android(安卓)Framework分析 ---- 1消息