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系统对线程的要求是这样的:

  1. Do not block the UI thread
  2. Do not access the Android UI toolkit from outside the UI thread
  1. 不要阻塞UI线程。
  2. 不要在非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

 

未完待续……

posted @ 2012-09-05 12:58  孤~影  阅读(305)  评论(0编辑  收藏  举报