此篇文章针对android5.1 systemUI源码进行分析

下面我们进行分析,
1.1 frameworks/base/packages/SystemUI/AndroidManifest.xml
我们先来看下这个文件下的内容:
android:name=”.SystemUIApplication”
android:persistent=”true”
android:allowClearUserData=”false”
android:allowBackup=”false”
android:hardwareAccelerated=”true”
android:label=”@string/app_label”
android:icon=”@drawable/icon”
android:process=”com.android.systemui”
android:supportsRtl=”true”
android:theme=”@style/systemui_theme”>
………………………………………
android:exported=”true”
/>
android:process=”:screenshot”
android:exported=”false” />
android:exported=”true” />
android:permission=”android.permission.BIND_WALLPAPER”
android:exported=”true” />
………………………………………
………………………………………
………………………………………

 我们可以看到,AndroidManifest.xml注册了很多的service 和 广播,那么是怎么启动的服务呢?    我们继续看下这个所注册的三个服务,               SystemUIService /               .screenshot.TakeScreenshotService /              .LoadAverageService/.ImageWallpaper

这三个服务是怎么启动的呢,我们仔细来看下这句注释:
“Broadcast receiver that gets the broadcast at boot time and starts up everything else.”
看里这个注释,我们就应该知道,首先启动的应该是SystemUIService这个服务。
那么SystemUIService这个服务是怎么启动的呢,启动服务我们知道多数的通用方法是
startService(intent)和bindService(intent)
那么我们就在SystemUI下全局搜索“SystemUIService”,可以看下结果
frameworks/base/services/java/com/android/server/SystemServer.java: “com.android.systemui.SystemUIService”));
我们打开SystemServer.java这个文件来看下是怎么调用的,

static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(“com.android.systemui”,
“com.android.systemui.SystemUIService”));
//Slog.d(TAG, “Starting service: ” + intent);
context.startServiceAsUser(intent, UserHandle.OWNER);
}

原来是 intent.setComponent()启动了SystemUIService这个服务。

1.2 frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java

下面我们来分析一下SystemUIService.java:

@Override    public void onCreate() {        super.onCreate();        ((SystemUIApplication) getApplication()).startServicesIfNeeded();    }

在oSystemUIService中的onCreate只调用了
((SystemUIApplication) getApplication()).startServicesIfNeeded();
这么一个语句,下面我们来看看startServicesIfNeeded()这里面有啥东西

public void startServicesIfNeeded() {            if (mServicesStarted) {                 return;    }                                   if (!mBootCompleted) {                  // check to see if maybe it was already completed long before we began        // see ActivityManagerService.finishBooting()        if ("1".equals(SystemProperties.get("sys.boot_completed"))) {             mBootCompleted = true;              if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent");                }    }    Log.v(TAG, "Starting SystemUI services.");    final int N = SERVICES.length;      for (int i=0; i cl = SERVICES[i];          if (DEBUG) Log.d(TAG, "loading: " + cl);         try {            mServices[i] = (SystemUI)cl.newInstance();        } catch (IllegalAccessException ex) {                    throw new RuntimeException(ex);              } catch (InstantiationException ex) {                    throw new RuntimeException(ex);              }        mServices[i].mContext = this;                    mServices[i].mComponents = mComponents;          if (DEBUG) Log.d(TAG, "running: " + mServices[i]);        mServices[i].start();        if (mBootCompleted) {            mServices[i].onBootCompleted();              }    }    mServicesStarted = true;}

}

在这里我们看到mServices启动了不止一个服务,那么这些都是那些服务呢,
我们看这个语句
mServices[i] = (SystemUI)cl.newInstance();
这里的语句付给了mServices[i].start()一个对象,
我们往上去找,可以看到这Class cl = SERVICES[i];
cl是SERVICES[i]这个数组中的一个值,在java的定义中,我们可以看到这个SERVICES的初始化
private final Class[] SERVICES = new Class[] {
com.android.systemui.keyguard.KeyguardViewMediator.class,
com.android.systemui.recent.Recents.class,
com.android.systemui.volume.VolumeUI.class,
com.android.systemui.statusbar.SystemBars.class,
com.android.systemui.usb.StorageNotification.class,
com.android.systemui.power.PowerUI.class,
com.android.systemui.media.RingtonePlayer.class
};
SERVICES中添加要start的所有服务选项,这里,我们重点关注一下
com.android.systemui.statusbar.SystemBars.class,
这是我们进行下一步分析的重要线索。

1.3 frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java

我们看下SystemBars.java这个文件中的start()中到底写了些什么东西,

public void start() {    if (DEBUG) Log.d(TAG, "start");    mServiceMonitor = new ServiceMonitor(TAG, DEBUG,            mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);    mServiceMonitor.start();  // will call onNoService if no remote service is found}   

这里,启动了另外一个服务mServiceMonitor,除了启动这个服务外什么都没有做,那我们继续往下面去看看
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/ServiceMonitor.java
在这个文件里面,对star()方法的调用
public void start() {
…………………
mHandler.sendEmptyMessage(MSG_START_SERVICE);
}
在这个函数里,这个sendEmptyMessage语句是一个非常关键的调用,这个调用也是启动了一个服务,我们去看下这个mHandler都干了些啥事,

private final Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch(msg.what) {
case MSG_START_SERVICE:
startService();
break;
case MSG_CONTINUE_START_SERVICE:
continueStartService();
break;
case MSG_STOP_SERVICE:
stopService();
break;
case MSG_PACKAGE_INTENT:
packageIntent((Intent)msg.obj);
break;
case MSG_CHECK_BOUND:
checkBound();
break;
case MSG_SERVICE_DISCONNECTED:
serviceDisconnected((ComponentName)msg.obj);
break;
}
}
};

在这里我们看到
case MSG_START_SERVICE:
startService();
break;
这里才是真正的启动了一个服务,mCallbacks.onNoService();
private void startService() {
mServiceName = getComponentNameFromSetting();
if (mDebug) Log.d(mTag, “startService mServiceName=” + mServiceName);
if (mServiceName == null) {
mBound = false;
mCallbacks.onNoService();
} else {
long delay = mCallbacks.onServiceStartAttempt();
mHandler.sendEmptyMessageDelayed(MSG_CONTINUE_START_SERVICE, delay);
}
}
我们来看下if (mServiceName == null) 这个判断的结果是怎么来的,
private ComponentName getComponentNameFromSetting() {
String cn = Settings.Secure.getStringForUser(mContext.getContentResolver(),
mSettingKey, UserHandle.USER_CURRENT);
return cn == null ? null : ComponentName.unflattenFromString(cn);
}
由以上的代码我们可知,cn返回的是null值,在startService()中就调用了 mCallbacks.onNoService();

我们来看下frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java
onNoService()的调用,

public void onNoService() {
if (DEBUG) Log.d(TAG, “onNoService”);
createStatusBarFromConfig();
}

private void createStatusBarFromConfig() {
…………………………………..
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
mStatusBar.start();
…………………………………..
}
在createStatusBarFromConfig()中终于有了实际的行动来进行关于status的一下相关操作了,一直到这里,其实前面所做的都是一些服务的调用,并没有对screen进行任何的view类级别的操作,其实上面的流程,只是在系统框架先进行的一些服务注册,及逻辑方面的一些准备。

1.4 frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
下面我们来着重分析下BaseStatusBar.start().

public void start() {
…………………….
createAndAddWindows();
…………………….
}
在BaseStatusBar.start()中,这个语句是重点中的重点,是对整个status的布局,我们进到这个函数中去看个究竟
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
public void createAndAddWindows() {
addStatusBarWindow();
}
在createAndAddWindows中也只是调用了这么一个函数,没有其他的东西了,我们接着看
addStatusBarWindow();
其实在addStatusBarWindow所做的东西也不多,就是两步
makeStatusBarView()和mStatusBarWindowManager.add();
但是这两步确实非常重要的两部。
private void addStatusBarWindow() {
makeStatusBarView();
mStatusBarWindowManager = new StatusBarWindowManager(mContext);
mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
}

我们先来看看akeStatusBarView()这个里面是什么情况
protected PhoneStatusBarView makeStatusBarView() {
…………………………
mStatusBarWindow = (StatusBarWindowView) View.inflate(context,R.layout.super_status_bar, null);
…………………………..

}

我们在super_status_bar.xml中这个文件可以看到
<-com.android.systemui.statusbar.phone.StatusBarWindowView
//xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:fitsSystemWindows=”true”>
…………………………..
<-com.android.systemui.statusbar.ScrimView android:id=”@+id/scrim_behind”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:importantForAccessibility=”no” />

……………………………………
<-com.android.systemui.statusbar.phone.PanelHolder
android:id=”@+id/panel_holder”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:background=”@color/transparent” >
<-include layout=”@layout/status_bar_expanded”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:visibility=”gone” />
<-/com.android.systemui.statusbar.phone.PanelHolder>
在这里,我们主要注意上面所示status_bar / panel_holder才是我们要关注的重中之重,是我们整个view的最直观的显示,也是客户化定制比较多的地方,下面我们来进行进一步的细分。

1.5 frameworks/base/packages/SystemUI/res/layout/status_bar.xml

<-com.android.systemui.statusbar.phone.PhoneStatusBarView
23 xmlns:android=”http://schemas.android.com/apk/res/android”
24 xmlns:systemui=”http://schemas.android.com/apk/res/com.android.systemui”
25 android:id=”@+id/status_bar”
26 android:background=”@drawable/system_bar_background”
27 android:orientation=”vertical”
28 android:focusable=”true”
29 android:descendantFocusability=”afterDescendants”
30 >
………………………………
71 <-com.android.systemui.statusbar.phone.IconMerger android:id=”@+id/notificationIcons”
72 android:layout_width=”match_parent”
73 android:layout_height=”match_parent”
74 android:layout_alignParentStart=”true”
75 android:gravity=”center_vertical”
76 android:orientation=”horizontal”/>
77 <-/com.android.keyguard.AlphaOptimizedLinearLayout>
78 <-/com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
79
80 <-com.android.keyguard.AlphaOptimizedLinearLayout android:id=”@+id/system_icon_area”
81 android:layout_width=”wrap_content”
82 android:layout_height=”match_parent”
83 android:orientation=”horizontal”
84 >
85
86 <-include layout=”@layout/system_icons” />
87
88 <-com.android.systemui.statusbar.policy.Clock
89 android:id=”@+id/clock”
90 android:textAppearance=”@style/TextAppearance.StatusBar.Clock”
91 android:layout_width=”wrap_content”
92 android:layout_height=”match_parent”
93 android:singleLine=”true”
94 android:paddingStart=”7dp”
95 android:gravity=”center_vertical|start”
96 />
97 <-/com.android.keyguard.AlphaOptimizedLinearLayout>
98 <-/LinearLayout>

我们来看下对比图是怎样的:

———–android:id= “@+id/notificationIcons”
该部分内容显示USB/T卡/wifi链接等一些通知选项图标。
———–android:id=”@+id/system_icon_area”
该部分内容主要显示的是SIM卡/电池/时间等…………………

1.6 frameworks/base/packages/SystemUI/res/layout/status_bar_expanded.xml
我们先来看看这个文件中所码的内容:

<-com.android.systemui.statusbar.phone.NotificationPanelView
22 xmlns:android=”http://schemas.android.com/apk/res/android”
23 xmlns:systemui=”http://schemas.android.com/apk/res/com.android.systemui”
24 android:id=”@+id/notification_panel”
25 android:layout_width=”match_parent”
26 android:layout_height=”match_parent”
27 android:background=”@android:color/transparent”
28 >
29
30 <-include
31 layout=”@layout/carrier_label_group”
32 android:layout_height=”wrap_content”
33 android:layout_width=”match_parent”
34 android:layout_marginBottom=”@dimen/close_handle_height”
35 android:layout_gravity=”bottom”
36 />
37
38 <-include
39 layout=”@layout/keyguard_status_view”
40 android:layout_height=”wrap_content”
41 android:visibility=”gone” />
42
43 <-TextView
44 android:id=”@+id/emergency_calls_only”
45 android:textAppearance=”@style/TextAppearance.StatusBar.Expanded.Network.EmergencyOnly”
46 android:layout_height=”wrap_content”
47 android:layout_width=”match_parent”
48 android:padding=”4dp”
49 android:gravity=”center”
50 android:visibility=”gone”
51 />
52
53 <-com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer
54 android:layout_width=”match_parent”
55 android:layout_height=”match_parent”
56 android:layout_gravity=”@integer/notification_panel_layout_gravity”
57 android:id=”@+id/notification_container_parent”
58 android:clipToPadding=”false”
59 android:clipChildren=”false”>
60
<-com.android.systemui.statusbar.phone.ObservableScrollView
62 android:id=”@+id/scroll_view”
63 android:layout_width=”@dimen/notification_panel_width”
64 android:layout_height=”match_parent”
65 android:layout_gravity=”@integer/notification_panel_layout_gravity”
66 android:scrollbars=”none”
67 android:overScrollMode=”never”
68 android:fillViewport=”true”>
69 <-LinearLayout
70 android:layout_width=”match_parent”
71 android:layout_height=”wrap_content”
72 android:orientation=”vertical”>
73 <-include
74 layout=”@layout/qs_panel”
75 android:layout_marginTop=”@dimen/status_bar_header_height_expanded”
76 android:layout_width=”match_parent”
77 android:layout_height=”wrap_content”
78 android:layout_marginLeft=”@dimen/notification_side_padding”
79 android:layout_marginRight=”@dimen/notification_side_padding”/>
80
81
82
83 <-View
84 android:id=”@+id/reserve_notification_space”
85 android:layout_height=”@dimen/min_stack_height”
86 android:layout_width=”match_parent”
87 android:layout_marginTop=”@dimen/notifications_top_padding” />
88
89 <-View
90 android:layout_height=”@dimen/notification_side_padding”
91 android:layout_width=”match_parent” />
92 <-/LinearLayout>
93 <-/com.android.systemui.statusbar.phone.ObservableScrollView>
94
95 <-com.android.systemui.statusbar.stack.NotificationStackScrollLayout
96 android:id=”@+id/notification_stack_scroller”
97 android:layout_width=”@dimen/notification_panel_width”
98 android:layout_height=”match_parent”
99 android:layout_gravity=”@integer/notification_panel_layout_gravity”
100 android:layout_marginTop=”-10dp”
101 android:layout_marginBottom=”@dimen/close_handle_underlap”
102 android:importantForAccessibility=”no” />
103
104 <-ViewStub
105 android:id=”@+id/keyguard_user_switcher”
106 android:layout=”@layout/keyguard_user_switcher”
android:layout_height=”match_parent”
108 android:layout_width=”match_parent” />
109
110 <-include
111 layout=”@layout/keyguard_status_bar”
112 android:visibility=”invisible” />
113
114 <-/com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer>
115
116 <-include
117 layout=”@layout/keyguard_bottom_area”
118 android:visibility=”gone” />
119
120 <-include layout=”@layout/status_bar_expanded_header” />
121
122 <-com.android.systemui.statusbar.AlphaOptimizedView
123 android:id=”@+id/qs_navbar_scrim”
124 android:layout_height=”96dp”
125 android:layout_width=”match_parent”
126 android:layout_gravity=”bottom”
127 android:visibility=”invisible”
128 android:background=”@drawable/qs_navbar_scrim” />
129
130 <-/com.android.systemui.statusbar.phone.NotificationPanelView>

我们先来看看真机上的效果图:

这就是我们真机上的效果图,这是我们status展开后的效果图,没有展开的我们上面已经分析过了,这里就不再重复。

下面我们来看下这个效果图主要是由那些部分组合而成的,

这个部分我们看到,并没有在这status_bar_expanded.xml中直接进行定义,但是我们可以通过
android:id=”@+id/header”
这个ID反方向去寻找在status_bar_expanded.xml中是怎么调用的,我们通过搜索知道
android:id=”@+id/header”
这个其实是在
status_bar_expanded_header.xml
这里进行定义的,找到这里,我们就能清楚的看到,其实在status_bar_expanded.xml中有对status_bar_expanded_header.xml的调用,
<-include layout=”@layout/status_bar_expanded_header” />
到了这里,我们就不继续对status_bar_expanded_header.xml这个文件进行分析了,进入到该文件中,我们能清楚明白的看到各个id的应用。

下面我们继续看最地下的通知信息栏是在哪里加载的,如下如所示:

在这里,该部分内容是在
<-com.android.systemui.statusbar.stack.NotificationStackScrollLayout
96 android:id=”@+id/notification_stack_scroller”
97 android:layout_width=”@dimen/notification_panel_width”
98 android:layout_height=”match_parent”
99 android:layout_gravity=”@integer/notification_panel_layout_gravity”
100 android:layout_marginTop=”-10dp”
101 android:layout_marginBottom=”@dimen/close_handle_underlap”
102 android:importantForAccessibility=”no” />
这里进行添加的,我们可以看到otification_stack_scroller其实在这个效果图里面是没有展开的,而是重叠在一起的,但是我们在这里不进行进一步的分析。

现在,我们来看最后一部分内容,就是快捷键的使用,我们先看下效果图,如下:

通过android:id的定位,我们知道,该部分内容是在这里
<-com.android.systemui.statusbar.phone.ObservableScrollView
62 android:id=”@+id/scroll_view”
63 android:layout_width=”@dimen/notification_panel_width”
64 android:layout_height=”match_parent”
65 android:layout_gravity=”@integer/notification_panel_layout_gravity”
66 android:scrollbars=”none”
67 android:overScrollMode=”never”
68 android:fillViewport=”true”>
69 <-LinearLayout
70 android:layout_width=”match_parent”
71 android:layout_height=”wrap_content”
72 android:orientation=”vertical”>
73 <-include
74 layout=”@layout/qs_panel”
75 android:layout_marginTop=”@dimen/status_bar_header_height_expanded”
76 android:layout_width=”match_parent”
77 android:layout_height=”wrap_content”
78 android:layout_marginLeft=”@dimen/notification_side_padding”
79 android:layout_marginRight=”@dimen/notification_side_padding”/>
80
81
82 <-!– Layout height: notification_min_height + bottom_stack_peek_amount –>
83 <-View
84 android:id=”@+id/reserve_notification_space”
85 android:layout_height=”@dimen/min_stack_height”
86 android:layout_width=”match_parent”
87 android:layout_marginTop=”@dimen/notifications_top_padding” />
88
89 <-View
90 android:layout_height=”@dimen/notification_side_padding”
91 android:layout_width=”match_parent” />
92 <-/LinearLayout>
93 <-/com.android.systemui.statusbar.phone.ObservableScrollView>
进行加载.

2.0 下面我们来对相关的各个模块一一进行剖析
2.0.1 下面我们先来分析 android:id=”@+id/brightness_slider”
先上图:

我们全局搜索“brightness_slider”看看有什么收获
1 33 frameworks/base/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml <<>>
android:id=”@+id/brightness_slider”
2 109 frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java <<>>
(ToggleSlider) findViewById(R.id.brightness_slider));
3 126 frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java <<>>
ToggleSlider brightnessSlider = (ToggleSlider) findViewById(R.id.brightness_slider);
4 127 frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java <<>>
ToggleSlider mirror = (ToggleSlider) c.getMirror().findViewById(R.id.brightness_slider);
5 51 frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java <<>>
final ToggleSlider slider = (ToggleSlider) findViewById(R.id.brightness_slider);

从这里我们看到,brightness_slider是在quick_settings_brightness_dialog.xml里添加的id,那么我们就在看看是哪里调用的quick_settings_brightness_dialog.xml文件,
1 99 frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java <>
R.layout.quick_settings_brightness_dialog, this, false);
2 48 frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java <>
setContentView(R.layout.quick_settings_brightness_dialog);
原来是在QSPanel.java中调用的xml,
mBrightnessView = LayoutInflater.from(context).inflate(R.layout.quick_settings_brightness_dialog, this, false);
为了更直观的看到这个调用顺序,我们在
public QSPanel(Context context, AttributeSet attrs)
中把调用堆栈给打印出来看看:
0java.lang.Throwable
at com.android.systemui.qs.QSPanel.(QSPanel.java:89)
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
at android.view.LayoutInflater.createView(LayoutInflater.java:607)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.parseInclude(LayoutInflater.java:916)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:802)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.parseInclude(LayoutInflater.java:916)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:802)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at android.view.View.inflate(View.java:18547)
at com.android.systemui.statusbar.phone.PhoneStatusBar.makeStatusBarView(PhoneStatusBar.java:648)
at com.android.systemui.statusbar.phone.PhoneStatusBar.addStatusBarWindow(PhoneStatusBar.java:3087)
at com.android.systemui.statusbar.phone.PhoneStatusBar.createAndAddWindows(PhoneStatusBar.java:3083)
at com.android.systemui.statusbar.BaseStatusBar.start(BaseStatusBar.java:564)
at com.android.systemui.statusbar.phone.PhoneStatusBar.start(PhoneStatusBar.java:598)
at com.android.systemui.statusbar.SystemBars.createStatusBarFromConfig(SystemBars.java:107)
at com.android.systemui.statusbar.SystemBars.onNoService(SystemBars.java:59)
at com.android.systemui.statusbar.ServiceMonitor.startService(ServiceMonitor.java:228)
at com.android.systemui.statusbar.ServiceMonitor.access 000(ServiceMonitor.java:49)atcom.android.systemui.statusbar.ServiceMonitor 1.handleMessage(ServiceMonitor.java:73)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5345)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:947)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:742)

从上面的调用中我们可以看到,
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
的protected PhoneStatusBarView makeStatusBarView(){};
mStatusBarWindow = (StatusBarWindowView) View.inflate(context,R.layout.super_status_bar, null);
这个语句中动态加载的。

2.1 设置header视图中的位置信息: updateHeaderShade()

at com.android.systemui.statusbar.phone.NotificationPanelView.**updateHeaderShade**(NotificationPanelView.java:1510)    at com.android.systemui.statusbar.phone.NotificationPanelView.updateHeader(NotificationPanelView.java:1502)    at com.android.systemui.statusbar.phone.NotificationPanelView.onHeightUpdated(NotificationPanelView.java:1379)    at com.android.systemui.statusbar.phone.PanelView.setExpandedHeightInternal(PanelView.java:660)    at com.android.systemui.statusbar.phone.PanelView.onTouchEvent(PanelView.java:315)    at com.android.systemui.statusbar.phone.NotificationPanelView.onTouchEvent(NotificationPanelView.java:707)    at com.android.systemui.statusbar.phone.PanelBar.onTouchEvent(PanelBar.java:131)    at com.android.systemui.statusbar.phone.PhoneStatusBarView.onTouchEvent(PhoneStatusBarView.java:158)    at android.view.View.**dispatchTouchEvent**(View.java:8481)    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2432)    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2103)    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2438)    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2132)    at com.android.systemui.statusbar.phone.StatusBarWindowView.dispatchTouchEvent(StatusBarWindowView.java:165)    at android.view.View.dispatchPointerEvent(View.java:8681)    at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4123)    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3989)    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680)    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3737)    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5817)    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5791)    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5762)    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5907)    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)    at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)    at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176)    at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:5878)    at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:5930)    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)    at android.view.Choreographer.doCallbacks(Choreographer.java:580)    at android.view.Choreographer.doFrame(Choreographer.java:548)    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)    at android.os.Handler.handleCallback(Handler.java:739)    at android.os.Handler.dispatchMessage(Handler.java:95)    at android.os.Looper.loop(Looper.java:135)    at android.app.ActivityThread.main(ActivityThread.java:5345)    at java.lang.reflect.Method.invoke(Native Method)    at java.lang.reflect.Method.invoke(Method.java:372)    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:947)    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:742)

我们看到,每当有点击事件的时候,都会去更新header的y轴的数据信息,从负值一直到零,注意这里最大的值是零。

总结,以上是对SystemUi的一些简单分析,在这里对启动的流程,各个文件的布局进行了一些简单的分析,这里面有许多细节的东西没有去进行更进一步的剖析,后面有时间会讲这些细节的东西补上。

更多相关文章

  1. Android中Service(服务)详解
  2. Android基本组件
  3. Android调用本机地图APP
  4. android ios vue 互调
  5. Android(安卓)浏览网页
  6. Android的NDK开发(1)————Android(安卓)JNI简介与调用流程
  7. 关于Android的Activity的onCreate多次调用的问题
  8. Android(安卓)中使用MediaRecorder进行录像详解(视频录制)
  9. android前端怎样php后台交互(基础篇)

随机推荐

  1. Android 中文 API (34) ―― RadioGroup
  2. Android 制作.9.png图片之利用Android 9-
  3. Android 安装卸载程序
  4. Android(安卓)Spinner
  5. Android(安卓)水果机游戏实例解析
  6. Android splitActionBarWhenNarrow Actio
  7. Android(安卓)Dagger2 初学笔记
  8. android中各种图标尺寸以及多分辨率支持
  9. android开发每日汇总【2011-10-31】
  10. Android菜单Menu的创建