android 进程与线程 相关

默认条件下,一个应用中的所有组件都运行在相同的进程和线程(主线程)。

  如果你需要控制一个特定组件属于哪个进程,可以在manifest 文件中定义

manifest 文件中的每一种元素类型都有一个android:process 属性可以指定一个进程

 可以在应用中的组件的指定不同的元素,或是不同应用中的不同组件使用相同的进程

 

进程的生命周期

 

系统会根据进程的重要性级别决定是否回收其资源。

按其重要列如下:(越靠前越不会回收)

1.前台进程

2.可视的进程

  • It hosts an Activity that is not in the foreground, but is still visible to the user (its onPause() method has been called). This might occur, for example, if the foreground activity started a dialog, which allows the previous activity to be seen behind it.
  • It hosts a Service that's bound to a visible (or foreground) activity.

3.服务进程

由startService()开始的进程

4.后台进程

5.空进程

 

线程

 

当一个应用启动时,系统就会分配给他一个主线程去执行。这个线程负责分配事件给合适的用户界面widget

也是这个线程与从android的UI交互。所以也叫UI线程。

    系统不会为一个组件的每个实例分配一个线程。同一个进程中所有组件会被在UI线程中实例化。

系统调用从UI线程分配的组件。

因此,响应系统回调的函数总是在UI线程了。

如,当用户点击屏幕时,你的应用的UI线程就会分配点击事件给相应的widget

 

当用这种单一线程模式处理耗时操作时(UI线程阻塞超过5秒)就会出现无响应错误。

而且android的UI工具箱不是线程安全的。不能用辅助线程操作UI,必须用主线程操作

有个原则:

1.不能阻塞UI线程

2.不能用其他的线程处理androidUI行为

 

辅助线程

由于这种单一线程模式,所以如果你的操作不需要即时响应, 你可以使用单独的线程(后台或是辅助线程)

如,用一个辅助线程操作androidUIx行为,将会导致不可预测的行为,这些行为很难被捕捉,将有CalledFromWrongThreadException

抛出

以正常方式建立新线程:

public void onClick(View v) {
   
new Thread(new Runnable() {
       
public void run() {
           
Bitmap b = loadImageFromNetwork("http://example.com/image.png");
            mImageView
.setImageBitmap(b);
       
}
   
}).start();
}

 

此违反第二条原则。

 

为了解决这个问题,android提供了几种方法让其他线程来处理UI。

上个例子可修改为:

public void onClick(View v) {
   
new Thread(new Runnable() {
       
public void run() {
           
final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
            mImageView
.post(new Runnable() {
               
public void run() {
                    mImageView
.setImageBitmap(bitmap);
               
}
           
});
       
}
   
}).start();
}

 

这种实现是安全的。

但是随着操作的复杂性的增长,这种代码将变得很难维护。

为了处理更复杂的与辅助线程的交互,应该在辅助线程中用Handle,去处理从UI线程的消息。

拓展AsyncTask类,它可以简化需要与UI交互的辅助线程任务的执行。

 

使用AsyncTask

 

AsyncTask允许你在用户界面表现出异步工作。也就是在辅助线程的阻塞操作,只是向UI线程传递一个结果。

不需要你处理线程。

对于使用AsyncTask,你完成AsyncTask的子类并实现doInBackground() 回调函数。

它在后台线程池运行。为了更新UI界面,你应该实现onPostExecute(),它接收了从 doInBackground()

的结果并它是运行在UI线程的。这样就可以安全更新UI。你可以在UI线程调用AsyncTask的execute()运行这个

任务。

public void onClick(View v) {
   
new DownloadImageTask().execute("http://example.com/image.png");
}

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
   
/** 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大概是这样工作的

1.你可以使用泛型指定参数,进度值,任务的返回值的类型。

2.doInBackground()自动在一个辅助线程执行。

3.onPreExecute(), onPostExecute(), 和 onProgressUpdate() 都在UI线程调用

4.doInBackground返回的值将送给onPostExecute

5.你可以在doInBackground中任何时间调用publishProgress() 让UI 线程调用onProgressUpdate()

6.你可以从任意的线程取消这个任务。

 

注意, 当runtime configuration change改变时(例如屏幕转向)辅助线程可能会不可预测的重启。

这样有可能销毁你辅助线程。

 

线程的安全模式

 

在一些情况下,你实现的方法可能被超过一个的线程调用,因此要能保证能线程安全下写操作。

 

得用到线程池概念

待补充。。。。

进程间的通信

待补充。。。。

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值