Android 进程和线程详解(3)

发表于:2013-03-27来源:Csdn作者:引路蜂点击数: 标签:线程
[java] view plaincopyprint? public void onClick(View v) { new DownloadImageTask().execute(http://example.com/image.png); } private class DownloadImageTask extends AsyncTask { /** The system calls this

  [java] view plaincopyprint?

  public void onClick(View v) {

  new DownloadImageTask().execute("http://example.com/image.png");

  }

  private class DownloadImageTask extends AsyncTask {

  /** The system calls this to perform work in a worker thread and

  * delivers it the parameters given to AsyncTask.execute() */

  protected Bitmap doInBackground(String... urls) {

  return loadImageFromNetwork(urls[0]);

  }

  /** The system calls this to perform work in the UI thread and delivers

  * the result from doInBackground() */

  protected void onPostExecute(Bitmap result) {

  mImageView.setImageBitmap(result);

  }

  }

  public void onClick(View v) {

  new DownloadImageTask().execute("http://example.com/image.png");

  }

  private class DownloadImageTask extends AsyncTask {

  /** The system calls this to perform work in a worker thread and

  * delivers it the parameters given to AsyncTask.execute() */

  protected Bitmap doInBackground(String... urls) {

  return loadImageFromNetwork(urls[0]);

  }

  /** The system calls this to perform work in the UI thread and delivers

  * the result from doInBackground() */

  protected void onPostExecute(Bitmap result) {

  mImageView.setImageBitmap(result);

  }

  }

  现在UI是安全的而且代码变的更简单,因为它把在工作线程中的工作和在UI线程的工作很好的分隔开。

  你应该参考AsyncTask的详细文档以便更好的理解它的工作原理,这里给出它的基本步骤:

  · 你可以使用generics为Task指定参数类型,返回值类型等

  · 方法doInBackground()将自动在一个工作线程中执行。

  · 方法onPreExecute(),onPostExecute()和onProgressUpdate都在UI线程中调用。

  · 方法doInBackground()的返回值将传递给onPostExecute()方法。

  · 你可以在doInBackground()中任意调用publishProgress()方法,该方法将会调用UI线程中的onProgressUpdate()方法,你可以用它来报告任务完成的进度。

  · 你可以在任意线程中任意时刻终止任务的执行。

  要注意的是,由于系统配置的变化(比如屏幕的方向转动)你的工作线程可能会碰到意外的重新启动,这种情况下,你的工作线程可能被销毁,你可以参考Android开发包中Shelves示例来处理线程重新的问题。

  编写“线程安全”方法

  在某些情况下,你编写的方法可能会被多个线程调用,此时你实现方法时要保证它是“线程安全”的。

  “线程安全”是可以被远程调用方法实现的基本规则—比如支持“绑定”的Service中的方法。当在实现IBinder接口同一进程中调用IBinder对象的方法时,该方法运行在调用者运行的同一线程中。然而,如果调用来自不同进程,系统将使用和实现IBinder接口的进程关联的线程池中的某个线程(非该进程中的UI线程)来执行IBinder的方法。比如,一个Service的onBind()方法会在某个Service进程的UI线程中调用,而由onBind()返回的对象(比如实现远程调用RPC方法的子类)的方法会在线程池的某个线程中执行。由于Service可能服务于多个客户端,那么可能有线程池中的多个线程同时执行IBinder对象的某个方法,因此IBinder对象的方法必须保证是线程安全的。

  同样的,一个Content Provider可以接受来自其它多个进程的数据请求。尽管ContentResolver和ContentProvider类隐藏了处理这些数据请求时进程间通信的详细机制,这些请求方法有query(), insert (), delete (), update () 及getType() 等。这些方法会在Content Provider的进程的线程池的某个线程中执行。由于这些方法同时有不定数量的线程同时调用,因此这些方法也必须是线程安全的。

  进程间通信

  Android系统支持使用远程调用(RPC)来实现进程间通信(IPC)的机制。此时在一个Activity或其它程序组件调用某个方法,而该方法的实现执行是在另外的进程中(远程进程)。远程调用可能给调用者返回结果。这就要求将方法调用和相关数据分离到某个层次,以便能让操作系统理解,能从本地进程传送数据到远程进程地址空间,在远程能够重新构造数据以执行方法,返回数据也能够反向返回。Android支持能够完成这些进程间通信事务的所有代码,从而使你可以只关注于定义和实现远程调用的接口。

  为了使用进程间通信(IPC),你的应用需要使用bindService()绑定到某个Service。

原文转自:http://blog.csdn.net/mapdigit/article/details/8711799