从使用的角度来说:
- Activity主要处理需要用户参与的任务
- Service主要后台处理一些不需要用户参与的任务
从实现角度来看,是什么造成了它们之间的区别,我很好奇的翻了翻源码,发现:
Activity和Service 都是由共同的祖先派生下来的,其实Activty和Service之间最大的区别是 Activity包含了一个Window,但是Service没有。
那么Window是如何和Activity勾搭上的呢?
1. Activity里面所有的View都是放在Window里面管理的
对应每一个Activity来说,都包含了一个 Window,
在Acitivy里面有这个定义,
private Window mWindow;
当前Acitivy所有显示的view都是放在这个window里面的。window里面有一个非常重要的变量:
private DecorView mDecor;// This is the top-level view of the window, containing the window decor.
这个是window里面最顶层的View。然后用户自己定义的View是放在下面这个变量里面:
// This is the view in which the window contents are placed. It is either
// mDecor itself, or a child of mDecor where the contents go.
private ViewGroup mContentParent
我们会在Activity 里面调用下面的函数,setContentView(R.layout. activity_test );
这个函数的作用就是把包含我们的 layout局部的View放到mContentParent 里面
它们的之间的关系如下图所示:
Activty如果想获取某个View,都是用下面这个函数
public View findViewById(int id) {
return getWindow().findViewById(id);
}
可以看到,其实也是通过Window来得到某一个View
2. Acitivy响应用户事件也是通过Window响应的
用户操作屏幕的事件传递也是通过window 来进行的。具体流程如下:
事件传递给DecorView ,然后传递给ChildView,如果ChildView不处理,就把事件返回给上层处理。如果所有的View都不处理事件,就返回到Activity里面。
为什么最后能返回到Acitivity里面了,原来Acitivy实现了一个重要的回调接口 Window.Callback
代码如下:在为Acitivy创建window 的时候,为window设置了回调的入口:
mWindow = PolicyManager.makeNewWindow(this);
mWindow.setCallback(this); //看一下这个callback接口的定义,
就发现里面包含了public boolean dispatchKeyEvent(KeyEvent event); 等事件传递的回调接口定义
mWindow.setOnWindowDismissedCallback(this);
这样就能把事件从View传递到Activity里面了。
3.总结
我们可以看到其实所有的View都是是通过window来维护的。用户时间也是通过窗口系统来传递
- Activity有了Window之后,就可以展示界面给用户,也可以响应用户的操作了。
- Service没有Window,只能默默的处理一些后台的任务。
两者的使命不同决定的,也决定了两者的生命周期也不一样。
另外要注意的是Activity 和Service都是继承自ContextWrapper,他们都运行在主线程里面。所以Service在运行后台任务的时候,一般都需要额外创建一个线程。