android的多线程操作(一)
“By default, all components of the same application run in the same process and thread (called the "main" thread).”
在通常的情况下,android应用程序都是运行在单一进程与线程之中的。这个线程就是“main”线程,也常被称为”UI线程”。
但是很多情况下我们的应用都可能会执行一些比较耗时的操作,例如获取一个网络的资源、一个文件的传输。如果我们把这些操作放在主线程。就会使线程阻塞(block),如果长时间的阻塞,我们还会看到臭名昭著的“应用程序失去响应”的对话框。所以,为了避免这和情况,我们首先想到的就是多开一个线程出来执行这些操作。但是,android的UI toolkit并不是线程安全(thread-safe)的。android系统对线程的要求是这样的:
- Do not block the UI thread
- Do not access the Android UI toolkit from outside the UI thread
- 不要阻塞UI线程。
- 不要在非UI线程中操作UI组件。
所以假如我们执行类似这样的代码:
new Thread() { public void run() { tv_content.setText("abc"); }; }.start();
就会在运行的时候报错。因为它违反了第二条约定。
anroid系统还是给我们提供了多种的解决方法的。
首先来看看第一类:
(1) 让操作在UI线程中运行(不让我在其实线程更新,那就在UI线程中更新呗!):
我们可以调用以下方法:
所以我们上边的代码改成这样就没问题了:
new Thread() { public void run() { runOnUiThread(new Runnable() { public void run() { tv_content.setText("abc"); } }); }; }.start();
这种方法虽然简单,可是代码的逻辑性并不好。如果是更复杂的操作,这种代码看起来是很“恶心的”。所以,这个方法仅在一些简单操作上才推荐使用。
(2) 使用AsyncTask的子类来实现异步操作:
AsyncTask是一个抽象类,专门用来处理一些异步操作。
这个类中我们经常使用的方法有三个:
protected void onPreExecute()
protected abstract Result doInBackground(Params... params)
protected void onProgressUpdate(Progress... values)
protected void onPostExecute(Result result)
这四个方法对应着三个过程:执行前à执行中à执行完。
在执行的过程中,我们可以自己更新进度,使用方法:
protected final void publishProgress(Progress... values)
其中onPreExecute()、onProgressUpdate()和onPostExcute()这三个方法是在UI线程中执行的。doInBackground()方法是在其它线程运行的。
下面是一个demo:
public class MainActivity_Asyn extends Activity { private Button btn_get; private TextView tv_content; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_get = (Button) findViewById(R.id.btn_get); tv_content = (TextView) findViewById(R.id.tv_content); btn_get.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new DownloadString().execute("http:www.baidu.com"); } }); } private class DownloadString extends AsyncTask<String, String, String> { @Override protected void onPreExecute() { super.onPreExecute(); tv_content.setText("开始获取"); } @Override protected String doInBackground(String... params) { HttpClient client = new DefaultHttpClient(); HttpGet get = new HttpGet(params[0]); StringBuilder sb = new StringBuilder(); try { publishProgress("下载 中..."); HttpResponse response = client.execute(get); InputStream is = response.getEntity().getContent(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String buffer = null; while ((buffer = reader.readLine()) != null) { sb.append(buffer); } } catch (Exception e) { e.printStackTrace(); } return sb.toString(); } @Override protected void onProgressUpdate(String... values) { super.onProgressUpdate(values); tv_content.setText(values[0]); } @Override protected void onPostExecute(String result) { super.onPostExecute(result); tv_content.setText(result); } } }
从这个demo 可以看出AsyncTask的大概执行过程。
这篇博文也是讲AsyncTask的,可以看看。
http://www.cnblogs.com/dawei/archive/2011/04/18/2019903.html
未完待续……