默认条件下,一个应用中的所有组件都运行在相同的进程和线程(主线程)。
如果你需要控制一个特定组件属于哪个进程,可以在manifest 文件中定义
manifest 文件中的每一种元素类型都有一个android:process 属性可以指定一个进程
可以在应用中的组件的指定不同的元素,或是不同应用中的不同组件使用相同的进程
进程的生命周期
系统会根据进程的重要性级别决定是否回收其资源。
按其重要列如下:(越靠前越不会回收)
1.前台进程
- It hosts an
Activitythat the user is interacting with (theActivity'sonResume()method has been called). - It hosts a
Servicethat's bound to the activity that the user is interacting with. - It hosts a
Servicethat's running "in the foreground"—the service has calledstartForeground(). - It hosts a
Servicethat's executing one of its lifecycle callbacks (onCreate(),onStart(), oronDestroy()). - It hosts a
BroadcastReceiverthat's executing itsonReceive()method.
2.可视的进程
- It hosts an
Activitythat is not in the foreground, but is still visible to the user (itsonPause()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
Servicethat'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改变时(例如屏幕转向)辅助线程可能会不可预测的重启。
这样有可能销毁你辅助线程。
线程的安全模式
在一些情况下,你实现的方法可能被超过一个的线程调用,因此要能保证能线程安全下写操作。
得用到线程池概念
待补充。。。。
进程间的通信
待补充。。。。
965

被折叠的 条评论
为什么被折叠?



