Android 4.0 statusbar加载icon(2)

二、PhoneStatusBar.java

public class PhoneStatusBar extends StatusBar {

}

PhoneStatusBar StatusBar(extends SystemUI)的子类,真正和StatusBarManagerService交互的实际上就是它。

对于SystemUI,首先启动的是Start();

public void start() {

……

//调用StatusBar start方法,建立和StatusbarManagerService之间的联系

super.start();//StatusBarstart中实现makeStatusBarView然后初始化statusbar icon状态

//启动更新Icon的方法

mIconPolicy = new PhoneStatusBarPolicy(mContext);

}

super.start()中我们看到,StatusBar是一个abstract类,真正要建立View是不能够的,必须在子类中创建。

实际上,StatusBar中也这样定义protected abstract View makeStatusBarView()

PhoneStatusBar 中:

protected View makeStatusBarView() {

final Context context = mContext;

Resources res = context.getResources();

//定义Icon的大小,缩放率和彼此间距

loadDimens();

mIconSize =                                                                  

res.getDimensionPixelSize(com.Android.internal.R.dimen.status_bar_icon_size);

//状态栏下拉时的view

ExpandedView expanded = (ExpandedView)View.inflate(context,

                R.layout.status_bar_expanded, null);

//真正显示的statusbar是根据是否是双卡来选择xml文件

PhoneStatusBarView sb;

if (TelephonyManager.getDefault().isMultiSimEnabled()) {

    sb = (PhoneStatusBarView)View.inflate(context,

                    R.layout.msim_status_bar, null);

} else {

    sb = (PhoneStatusBarView)View.inflate(context,

                    R.layout.status_bar, null);

}

//获取statusbar的实例

sb.mService = this;

mStatusBarView = sb;

//显示statusbar iconview

mStatusIcons = (LinearLayout)sb.findViewById(R.id.statusIcons);

//显示notificationview

mNotificationIcons = (IconMerger)sb.findViewById(R.id.notificationIcons);

mMoreIcon = sb.findViewById(R.id.moreIcon);

//定义下拉状态栏,显示Notifications

mExpandedDialog = new ExpandedDialog(context);

/*这个expanded就是指layout下的status_bar_expanded.xml解析所得下拉状态栏*/

        mExpandedView = expanded;

//显示Notification的控件,NotificationRowLayout是处理函数,

        mPile = (NotificationRowLayout)expanded.findViewById(R.id.latestItems);

        mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout);

        //android2.3中显示onGoing等信息的textviewandroid4.0已经不用了

mNoNotificationsTitle = (TextView)expanded.findViewById(R.id.noNotificationsTitle);

        mNoNotificationsTitle.setVisibility(View.GONE);

……

}

在步骤一的函数start()中的标识处调用的是PhoneStatusBar的函数,在那里初始化status bar icon

前面说了,在registerStatusBar时获得的iconList是没有icon

  public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {

//依据config.xml中的config_statusBarIcons定义的字符串创建StatusBarIconView,注意

//mContextPhoneStatusBarmContext

        StatusBarIconView view = new StatusBarIconView(mContext, slot, null);

//设置显示的icon

        view.set(icon);

//添加到msim_status_bar.xml的保存iconview中去

        if (FeatureQuery.FEATURE_ANNUCIATOR_NEW_STATUSBAR_STYLE) {

            mStatusIcons.addView(view, viewIndex, 

new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, mIconSize));

        } else {

            mStatusIcons.addView(view, viewIndex, 

new LinearLayout.LayoutParams(mIconSize, mIconSize));

        }

}

PhoneStatusBar.java中用到下面这两个类

StatusBarIconsView.java

public class StatusBarIconView extends AnimatedImageView 

public StatusBarIconView(Context context, String slot, Notification notification) {

final Resources res = context.getResources();

mSlot = slot;

mNumberPain = new Paint();

         mNumberPain.setTextAlign(Paint.Align.CENTER);

         mNumberPain.setColor(res.getColor(R.drawable.notification_number_text_color));

         mNumberPain.setAntiAlias(true);

         mNotification = notification;

……

setScaleType(ImageView.ScaleType.CENTER);

}

}

class的声明可以看出,StatusBarIconView 是一个AnimatedImageView,因此,可以显示icon

public boolean set(StatusBarIcon icon) {

final boolean iconEquals = mIcon != null

                && streq(mIcon.iconPackage, icon.iconPackage)

                && mIcon.iconId == icon.iconId;

        final boolean levelEquals = iconEquals

                && mIcon.iconLevel == icon.iconLevel;

        final boolean visibilityEquals = mIcon != null

                && mIcon.visible == icon.visible;

        final boolean numberEquals = mIcon != null

                && mIcon.number == icon.number;

//icon信息拷贝给mIcon

        mIcon = icon.clone();

if (!iconEquals) {

       Drawable drawable = getIcon(icon);

       if (drawable == null) {

                return false;

        }

//下面两步就是获取drawable,然后设置到view中去

        setImageDrawable(drawable);

 }

}

private Drawable getIcon(StatusBarIcon icon) {

//我们在PhoneStatusBar中创建StatusBarIconView时传了mContext,因此这里getContext()

//也是PhoneStatusBar

        return getIcon(getContext(), icon);

}

public static Drawable getIcon(Context context, StatusBarIcon icon) {

……

try {

 //获取icon

     return r.getDrawable(icon.iconId);

} catch (RuntimeException e) {

            

}

return null;

}

只有在下面这个类中才正式显示iconstatusbar

PhoneStatusBarPolicy.java

ContextPhoneStatusBarmContext

public PhoneStatusBarPolicy(Context context) {

//StatusBarManagerService

mService = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE);

mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);

mStorageManager.registerListener(

       new com.android.systemui.usb.StorageNotification(context));

// TTY status

mService.setIcon("tty",  R.drawable.stat_sys_tty_mode, 0, null);

// Alarm clock

        mService.setIcon("alarm_clock", R.drawable.stat_sys_alarm, 0, null);

        mService.setIconVisibility("alarm_clock", false);

// volume

        mService.setIcon("volume", R.drawable.stat_sys_ringer_silent, 0, null);

        mService.setIconVisibility("volume", false);

        updateVolume();

//headset 

mService.setIcon("headset", com.android.internal.R.drawable.stat_sys_headset, 0, null);

        mService.setIconVisibility("headset", false);

}

上面的mServiceStatusBarManager,那么setIcon是操作如下:

StatusBarManager.java

public void setIcon(String slot, int iconId, int iconLevel, String contentDescription) {

        try {

//StatusBarManagerService的本地代理service

            final IStatusBarService svc = getService();

            if (svc != null) {

                svc.setIcon(slot, mContext.getPackageName(), iconId, iconLevel,

                    contentDescription);

            }

        } catch (RemoteException ex) {

            // system process is dead anyway.

            throw new RuntimeException(ex);

        }

}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/pszyp.html