Android 4.0 ICS SystemUI淺析——StatusBar工作流程之時間日期設定

來源:互聯網
上載者:User

前面幾篇文章:

       《Android 4.0 ICS SystemUI淺析——SystemUI啟動流程》

       《Android 4.0 ICS SystemUI淺析——StatusBar結構分析》

       《Android 4.0 ICS SystemUI淺析——StatusBar載入流程分析》

       《Android 4.0 ICS SystemUI淺析——StatusBar載入流程之Notification》

       本文主要分析StatusBar上的Clock以及Date載入以及工作流程,這算是比較簡單的了,不過它們的實現還是值得一探究竟的,那麼果斷開始吧!

       註:本文來自:http://blog.csdn.net/yihongyuelan 歡迎轉載 請務必註明出處!

       首先還是看看我們前面文章有提到的StatusBar組成結構圖,1

圖1

         首先我們先找到SourceCode/framework/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java中的start()方法,至於為什麼要找到這裡,我們在前面的文章已有敘述,代碼如下:

         public void start() {        // 因為我們前面已經分析過start方法,因此這裡就不重複了,有興趣的朋友請翻看前面的文章,這裡主要引出Clock的初始化.        ... ...        // 這雷根據switches[0]的值,決定知否載入Clock        disable(switches[0]);        setSystemUiVisibility(switches[1]);        topAppWindowChanged(switches[2] != 0);        // StatusBarManagerService has a back up of IME token and it's restored here.        setImeWindowStatus(binders.get(0), switches[3], switches[4]);        setHardKeyboardStatus(switches[5] != 0, switches[6] != 0);        ... ...        mDoNotDisturb = new DoNotDisturb(mContext);    }

         根據這裡的disable(),通過Open Implementation跳轉到PhoneStatusBar中的disable方法,代碼如下:

    /**     * State is one or more of the DISABLE constants from StatusBarManager.     */    public void disable(int state) {        final int old = mDisabled;        final int diff = state ^ old;        mDisabled = state;        ... ...        if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {            boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;            // 根據show的值(true/false)是否顯示Clcok            showClock(show);        }        ... ...        }    }

         因為我們只關心Clock,因此其餘部分代碼在這裡就省略了。繼續跟蹤showClock方法,代碼如下:

        public void showClock(boolean show) {        // 這裡就完成了clock的初始化了 這裡的mStatusBarView實際上就是圖1中的id/icons。可以通過查看mStatusBarView初始化知道。        View clock = mStatusBarView.findViewById(R.id.clock);        if (clock != null) {            clock.setVisibility(show ? View.VISIBLE : View.GONE);        }    }

          初始化既然完成了,那麼Clock是如何工作的呢?這就不得不找到Clock的實現了,那麼該如何尋找呢?首先,找到clock的在id/icons中的布局檔案,根據前文我們可以知道是msim_status_bar.xml,在其中可以看到:

        <com.android.systemui.statusbar.policy.Clock            android:id="@+id/clock"            android:textAppearance="@style/TextAppearance.StatusBar.Clock"            android:layout_width="wrap_content"            android:layout_height="match_parent"            android:singleLine="true"            android:paddingRight="6dip"            android:gravity="center_vertical|left"            />

          我們可以看到clock是一個自訂View,以此我們可以找到其具體實現在:SourceCode/framework/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java中,代碼如下:

public class Clock extends TextView {    ... ...    @Override    protected void onAttachedToWindow() {        super.onAttachedToWindow();        if (!mAttached) {            mAttached = true;            IntentFilter filter = new IntentFilter();            filter.addAction(Intent.ACTION_TIME_TICK);            filter.addAction(Intent.ACTION_TIME_CHANGED);            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);            filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);            getContext().registerReceiver(mIntentReceiver, filter, null, getHandler());        }        updateClock();    }    @Override    protected void onDetachedFromWindow() {        super.onDetachedFromWindow();        if (mAttached) {            getContext().unregisterReceiver(mIntentReceiver);            mAttached = false;        }    }    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) {            String action = intent.getAction();            if (action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {                String tz = intent.getStringExtra("time-zone");                mCalendar = Calendar.getInstance(TimeZone.getTimeZone(tz));                if (mClockFormat != null) {                    mClockFormat.setTimeZone(mCalendar.getTimeZone());                }            }            updateClock();        }    };    final void updateClock() {        mCalendar.setTimeInMillis(System.currentTimeMillis());        setText(getSmallTime());    }    ... ...    }}

          通過以上代碼(省略了部分代碼),我們可以看到,Clock實際上繼承自TextView,TextView的內容更新需要SetText。因此這裡通過廣播的方式來實現了這一過程,更新Clock主要由方法updateClock()來完成,觸發條件為接收到相應的廣播。Clock的更新流程了:

      1.Clock類繼承TextView;

      2.在初始化StatusBar時同時也註冊了Clock中的廣播;

      3.Clock中的廣播等待接收並執行更新時間;

      通過以上方法,實際上就實現了一個可以自動更新內容的TextView。

     下面我將通過一個Demo來簡單的類比這個過程,Demo內容:通過點擊按鈕觸發廣播,廣播接收器在自訂TextView中,在該TextView中完成內容的更新。效果2:

圖2

       貼出實現代碼,如下:

public final class ClockView extends TextView {private boolean update = false;    public Context mContext;    //調用Activity中的ACTION要一致    public static final String ACTION = "com.seven.update";    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) {            String action = intent.getAction();            if (ACTION.equals(action)) {                updateClock();            }        }    };    public ClockView(Context context, AttributeSet attrs) {        super(context, attrs);        this.mContext = context;         setUpdates();    }    //更新介面內容    private final void updateClock() {    if(update){    update = false;    setText("11:15 AM");    }else {update = true;setText("22:22 PM");}    }    //註冊廣播接收private void setUpdates() {IntentFilter filter = new IntentFilter();filter.addAction(ACTION);mContext.registerReceiver(mIntentReceiver, filter);}}

      布局檔案如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="@string/name" />        <com.seven.viewTest.ClockView         android:id="@+id/myCV"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:textColor="#00ff00"        android:textSize="30dip"        android:text="@string/content"        />        <Button         android:id="@+id/myBtn"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="@string/send"        /></LinearLayout>

       調用Activity代碼如下:

public class UpdateActivity extends Activity{private ClockView mDateView;private Button mButton;public static final String ACTION = "com.seven.update";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                WindowManager.LayoutParams.FLAG_FULLSCREEN);        requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.main);mDateView = (ClockView) findViewById(R.id.myCV);mButton = (Button) findViewById(R.id.myBtn);mButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {sendBroadcast(new Intent(ACTION)); }});}}

          
總結:關於Clock的載入以及工作流程比較簡單,但其中通過自訂view實現自動更新TextView還是值得學習。Clock的工作流程和Date的工作流程是一致的,也就是它們都是通過廣播這種方式來更新內容的。

       本文涉及到的代碼以及圖片資源下載請點擊這裡!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.