Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 關於Google 教程中 Manage the Activity Lifecycle 示例的學習

關於Google 教程中 Manage the Activity Lifecycle 示例的學習

編輯:關於Android編程

昨天晚上我看了Google training裡面Manage the Activity Lifecycle這一節,看了以後學到很多以前看書,看視頻都沒有了解過的東西,Google關於如何恰當地使用這些方法來是我們的APP運行流暢,符合用戶的預期給出了很好的指導意見,比如Pause()裡面釋放不需要的系統資源,停止UI動畫等消耗內存的東西,不要進行密集CPU操作以影響Activity的過渡等等,還有SaveInstanceStates()作用及用法的詳細講解。。。。反正好多好多了。

於是,我就忍不住下載了官方示例,看看Google的實例APP是怎麼樣的。在Studio裡面運行一看,果然不一樣。一般的教程都是給你看看Log就好了吧,而且只運行一個Activity,讓你看看單個Activity的變化是怎麼樣的。瞬間差距就出來了。。。。。Google的示例不僅僅將Activity的數量范圍變大到3個,還用圖形化的方式更直觀的給我們展示了Activity生命周期的變化過程。

有圖為證:
Activity A

Activity B

DIALOG Activity

看著確實是厲害了很多呢,如果只是從圖形化的角度去看看Activity的生命周期在各種情況下的變化,學習Activity生命周期的目的應該達到了,但我很好奇他是怎麼做出來,因為我是Android新手,所以就看了看源碼,下面是我從源碼裡面的學到東西的摘要。

如果大家對這個示例也感興趣,可以點擊這裡進行示例的下載.


第一個問題:

如何在多個Activity切換的時候,追蹤Activity的狀態變化信息,然後顯示出來?

第一個回答:

首先在每個Activity使用一樣的布局,然後定義一個工具類A來存貯所有Activity變化的狀態信息,所有的Activity共用一個靜態工具類A變量,這保證了狀態信息的共享。然後定義一個工具類B,分別在每個Activity的不同狀態打印信息。

好了,讓我們先看一下工具類A的代碼吧。

public class StatusTracker {
  private Map mStatusMap;
  private List mMethodList;
  private static StatusTracker ourInstance = new StatusTracker();
  private static final String STATUS_SUFFIX = "ed";

  public static StatusTracker getInstance() {
    return ourInstance;
  }

  private StatusTracker() {
    mStatusMap = new LinkedHashMap();
    mMethodList = new ArrayList();
  }

  public List getMethodList() {
    return mMethodList;
  }

  public void clear() {
    mMethodList.clear();
    mStatusMap.clear();
  }

  /**
   * Adds the status value for the given activityName into the Map.
   *
   * @param activityName
   * @param status
   */
  public void setStatus(String activityName, String status) {
    mMethodList.add(activityName + "." + status + "()");
    if (mStatusMap.containsKey(activityName)) mStatusMap.remove(activityName);
    mStatusMap.put(activityName, status);
  }

  /**
   * Gets the status value for the given activityName.
   *
   * @param activityName
   * @return
   */
  public String getStatus(String activityName) {
    String status = mStatusMap.get(activityName);
    status = status.substring(2, status.length());

    // String manipulation to ensure the status value is spelled correctly.
    if (status.endsWith("e")) {
      status = status.substring(0, status.length() - 1);
    }
    if (status.endsWith("p")) {
      status = status + "p";
    }
    status = status + STATUS_SUFFIX;
    return status;
  }

  public Set keySet() {
    return mStatusMap.keySet();
  }
}

首先,我們看到 StatusTracker 這個類內部定義了一個靜態的自身變量和 getInstance() 方法,這樣我們只要在不同的地方直接調用這個靜態方法就能得到相同的 StatusTracker 變量了。

public class StatusTracker {
  private Map mStatusMap;
  private List mMethodList;
  private static StatusTracker ourInstance = new StatusTracker();
  private static final String STATUS_SUFFIX = "ed";

  public static StatusTracker getInstance() {
    return ourInstance;
  }
  。。。。

然後我們再看它存貯狀態信息的代碼 它定義了一個 Map 用來存貯不同Activity狀態(最多3個),定義了一個List用來存貯所有Activity狀態變化的歷史信息。因為Map不能存貯重復的鍵值對,而List可以存儲重復的信息。

然後通過 setStatus 這個方法來更新Activity最新的狀態。

public void setStatus(String activityName, String status) {
    mMethodList.add(activityName + "." + status + "()");
    if (mStatusMap.containsKey(activityName)) mStatusMap.remove(activityName);
    mStatusMap.put(activityName, status);
  }

只需要每次把Activity的名字和它對應的狀態作為參數放進去就好。

好了,現在讓我們看看示例是如何用這個相同的示例進行UI內容的更新的吧。也就是工具類B,我們先看看代碼:

public class Utils {

  private static StatusTracker mStatusTracker = StatusTracker.getInstance();

  /**
   * Helper method to print out the lifecycle state of each Activity.  Note this has
   * been wrapped in a Handler to delay the output due to overlaps in lifecycle state
   * changes as one Activity launches another.
   * @link http://developer.android.com/guide/topics/fundamentals/activities.html#CoordinatingActivities
   * @param viewMethods TextView to list out the lifecycle methods called
   * @param viewStatus TextView to list out the status of all Activity classes
   */
  public static void printStatus(final TextView viewMethods, final TextView viewStatus) {
      Handler handler = new Handler();
      handler.postDelayed(new Runnable() {
        public void run() {
          // Get the stack of Activity lifecycle methods called and print to TextView
          StringBuilder sbMethods = new StringBuilder();
          List listMethods = mStatusTracker.getMethodList();
          for (String method : listMethods) {
              sbMethods.insert(0, method + "\r\n");
          }
          if(viewMethods != null) {
              viewMethods.setText(sbMethods.toString());
          }

          // Get the status of all Activity classes and print to TextView
          StringBuilder sbStatus = new StringBuilder();
          for (String key : mStatusTracker.keySet()) {
            sbStatus.insert(0,key + ": " + mStatusTracker.getStatus(key) + "\n");
          }
          if(viewStatus != null) {
              viewStatus.setText(sbStatus.toString());
          }
        }
      }, 750);
    }
}

我們看到它只有一個成員變量,一個方法。

成員變量是和所有Activity相同的變量,這樣保證數據的一致性。方法只有打印打印狀態信息的方法,接受兩個TextView參數,這兩個參數分別是貼圖中的兩個TextView。

可以看到 Utils 類的方法是通過Handle來更新UI的,內容比較簡單就不說了。

好了這是代碼部分,最後貼一下ActivityA的內容,B,C代碼基本一致,只是少了onDestroy()方法裡面clear()函數的調用,因為A先啟動,結束的時候肯定也是A最後銷毀,在Destroy的時候我們應該釋放最後沒有釋放的資源,這裡是清理,而其他的時候應該保留。

public class ActivityA extends Activity {

    private String mActivityName;
    private TextView mStatusView;
    private TextView mStatusAllView;
    private StatusTracker mStatusTracker = StatusTracker.getInstance();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_a);
        mActivityName = getString(R.string.activity_a);
        mStatusView = (TextView)findViewById(R.id.status_view_a);
        mStatusAllView = (TextView)findViewById(R.id.status_view_all_a);
        mStatusTracker.setStatus(mActivityName, getString(R.string.on_create));
        Utils.printStatus(mStatusView, mStatusAllView);
    }

    @Override
    protected void onStart() {
        super.onStart();
        mStatusTracker.setStatus(mActivityName, getString(R.string.on_start));
        Utils.printStatus(mStatusView, mStatusAllView);
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        mStatusTracker.setStatus(mActivityName, getString(R.string.on_restart));
        Utils.printStatus(mStatusView, mStatusAllView);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mStatusTracker.setStatus(mActivityName, getString(R.string.on_resume));
        Utils.printStatus(mStatusView, mStatusAllView);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mStatusTracker.setStatus(mActivityName, getString(R.string.on_pause));
        Utils.printStatus(mStatusView, mStatusAllView);
    }

    @Override
    protected void onStop() {
        super.onStop();
        mStatusTracker.setStatus(mActivityName, getString(R.string.on_stop));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mStatusTracker.setStatus(mActivityName, getString(R.string.on_destroy));
        mStatusTracker.clear();
    }

    public void startDialog(View v) {
        Intent intent = new Intent(ActivityA.this, DialogActivity.class);
        startActivity(intent);
    }

    public void startActivityB(View v) {
        Intent intent = new Intent(ActivityA.this, ActivityB.class);
        startActivity(intent);
    }

    public void startActivityC(View v) {
        Intent intent = new Intent(ActivityA.this, ActivityC.class);
        startActivity(intent);
    }

    public void finishActivityA(View v) {
        ActivityA.this.finish();
    }

}

這就是代碼部分了。

在XML布局文件裡我可看了看,這裡簡單貼一下代碼

變量的命名規范,還有layout_toRightOf,這個方法我都沒怎麼用,以前一直都用的絕對大小,學習一下。

還有我在TextView裡面看到了,這個屬性 android:typeface=”monospace”,我之前沒怎麼見過,就搜了一下,找到了這麼個說法。

問:

How to change the font on the TextView? How to change the font in a TextView, as default it’s shown up as Arial? How to change it to Helvetica?

答:

First, the default is not Arial. The default is Droid Sans.
Second, to change to a different built-in font, use android:typeface in layout XML or setTypeface() in Java.
Third, there is no Helvetica font in Android. The built-in choices are Droid Sans (sans), Droid Sans Mono (monospace), and Droid Serif (serif). While you can bundle your own fonts with your application and use them via setTypeface(), bear in mind that font files are big and, in some cases, require licensing agreements

原來這是改變字體的屬性。。(⊙o⊙)…還能改字體

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved