Activity的最佳實踐

前言


        如果你對Activity的知識點還不夠了解,那請看http://blog.csdn.net/xhbxhbsq/article/details/53142075#t10這篇文章。學習完Activity的知識點後,相信你已經掌握了關於Activity非常多的知識,不過恐怕離能夠完全靈活運用還有一段距離。雖然知識點只有這麼多,但運用的技巧卻是多種多樣。所以,在這裏我準備教你幾種關於活動的最佳實踐技巧,這些技巧在你以後的開發工作當中將會非常受用。

知曉當前是在哪一個活動


        這個技巧將教會你如何根據程序當前的界面就能判斷出這是哪一個活動。可能你會覺得挺納悶的,我自己寫的代碼怎麼會不知道這是哪一個活動呢?很不辛的是,在你真正進入到企業之後,更有可能的是接收一份別人寫的代碼,因爲你剛進公司就正好有一個新項目啓動的概率並不高。閱讀別人的代碼時有一個很頭疼的問題,就是當你需要在某個界面上修改一些非常簡單的東西時,卻半天找不到這個界面對應的活動是哪一個。學會了本節的技巧之後,這對你來說就再也不是難題了。
        首先創建一個ActivityTest項目,並實現三個Activity,分別是FirstActivity,SecondActivity和ThirdActivity,然後需要新建一個BaseActivity類。右擊com.example.activitytest包 --> New --> JavaClass,在彈出的窗口處輸入BaseActivity。
        注意這裏BaseActivity和普通活動的創建方式並不一樣,因爲我們不需要讓BaseActivity在AndroidManifest.xml中註冊,所以選擇創建一個普通的Java類就可以了。然後讓BaseActivity繼承自Activity,並重寫onCreate()方法,如下所示:
public class BaseActivity extends Activity{
private static final String TAG = "BaseActivity";
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate: " + getClass().getSimpleName());
}
 
@Override
protected void onDestroy() {
super.onDestroy();
}
}
        我們在onCreate()方法中獲取了當前實例的類名,並通過Log打印了出來。
        接下來我們需要讓BaseActivity成爲ActivityTest項目中所有活動的父類。修改FirstActivity,SecondActivity和ThirdActivity的繼承結構,讓它們不再繼承自Activity,而是繼承自BaseActivity。而由於BaseActivity又是繼承自Activity,所以項目中所有活動的現有功能並不受影響,它們仍然完全繼承了Activity中的所有特性。
        現在重新運行程序,然後通過點擊按鈕分別進入到FirstActivity,SecondActivity和ThirdActivity的界面,這時觀察logcat中的打印信息,就可以知道當前界面顯示的是哪個Activity。

隨時隨地退出程序


        如果目前你手機的界面還停留在ThirdActivity,你會發現當前想退出程序是非常不方便的,需要連按3次Back鍵才行。按Home鍵只是把程序掛起,並沒有退出程序。其實這個問題就足以引起你的思考,如果我們的程序需要一個註銷或者退出的功能該怎麼辦呢?必須要有一個隨時隨地都能退出程序的方案才行。
        其實解決思路也很簡單,只需要用一個專門的集合類對所有的活動進行管理就可以了,下面我們就來實現一下。
        新建一個ActivityCollector類作爲活動管理器,代碼如下所示:
public class ActivityCollector {
 
private static List<Activity> activities = new ArrayList<>();
 
public static void addActivity(Activity activity) {
activities.add(activity);
}
 
public static void removeActivity(Activity activity) {
activities.remove(activity);
}
 
public static void finishAll() {
for(Activity activity : activities) {
if(!activity.isFinishing()) {
activity.finish();
}
}
}
}
        在活動管理器中,我們通過一個List來暫存活動,然後提供了一個addActivity()方法用於向List中添加一個活動,提供了一個removeActivity()方法用於從List中移除活動,最後提供了一個finishAll()方法用於將List中存儲的活動全部銷燬掉。
        接下來修改BaseActivity中的代碼,如下所示:
public class BaseActivity extends Activity{
private static final String TAG = "BaseActivity";
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate: " + getClass().getSimpleName());
ActivityCollector.addActivity(this);
}
 
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
}
        在BaseActivity的onCreate()方法中調用了ActivityCollector的addActivity()方法,表明將當前正在創建的活動添加到活動管理器裏。然後在BaseActivity中重寫onDestroy()方法,並調用了ActivityCollector的removeActivity()方法,表明將一個馬上要銷燬的活動從活動管理器裏移除。
        從此以後,不管你想在什麼地方退出程序,只需要調用ActivityCollector.finishAll()方法就可以了。例如在ThirdActivity界面想通過點擊按鈕直接退出程序,只需將代碼改成如下所示:
public class ThirdActivity extends BaseActivity {
private static final String TAG = "ThirdActivity";
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
Log.d(TAG, "onCreate: Task id is " + getTaskId());
 
Button button3 = (Button) findViewById(R.id.button_3);
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCollector.finishAll();
Process.killProcess(Process.myPid());
}
});
}
}
        當然你還可以在銷燬所有活動的代碼後面再加上殺掉當前進程的代碼,以保證程序完全退出,殺掉進程的代碼如下所示:
android.os.Process.killProcess(android.os.Process.myPid());
       其中,killProcess()方法用於殺掉一個進程,它接收一個進程id參數,我們可以通過myPid()方法來獲得當前程序的進程id。需要注意的是,killProcess()方法只能用於殺掉當前程序的進程,我們不能使用這個方法去殺掉其他程序。

啓動活動的最佳寫法


        啓動活動的方法相信你已經非常熟悉了,首先通過Intent構建出當前的“意圖”,然後調用startActivity()或startActivityForResult()方法將活動啓動起來,如果有數據需要從一個活動傳遞到另一個活動,也可以藉助Intent來完成。
        假設SecondActivity中需要用到兩個非常重要的字符串參數,在啓動SecondActivity的時候必須要傳遞過來,那麼我們很容易會寫出如下代碼:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("param1", "data1");
intent.putExtra("param2", "data2");
startActivity(intent);
        這樣寫是完全正確的,不管是從語法上還是規範上,只是在真正的項目開發中經常會有對接的問題出現。比如SecondActivity並不是由你開發的,但現在你負責的部分需要有啓動SecondActivity這個功能,而你卻不清楚啓動這個活動需要傳遞哪些數據。這時無非就有兩種辦法,一個是你自己去閱讀SecondActivity中的代碼,二是詢問負責編寫SecondActivity的同事。你會不會覺得很麻煩呢?其實只需要換一種寫法,就可以輕鬆解決掉上面的窘境。
        修改SecondActivity中的代碼,如下所示:
public class SecondActivity extends BaseActivity {
private static final String TAG = "SecondActivity";
 
public static void actionStart(Context context, String data1, String data2) {
Intent intent = new Intent(context, SecondActivity.class);
intent.putExtra("param1", data1);
intent.putExtra("param2", data2);
context.startActivity(intent);
}
......
}
        我們在SecondActivity中添加了actionStart()方法,在這個方法中完成了Intent的構建,另外所有SecondActivity中需要的數據都是通過actionStart()方法的參數傳遞進來的,然後把他們存儲到Intent中,最後調用startActivity()方法啓動SecondActivity。
        這樣寫的好處在哪裏呢?最重要的一點就是一目瞭然,SecondActivity所需要的數據在方法參數中體現出來了,這樣即使不用閱讀SecondActivity中的代碼,不去詢問負責編寫SecondActivity的同事,你也可以非常清晰地知道啓動SecondActivity需要傳遞哪些數據。另外,這樣寫還簡化了啓動活動的代碼,現在只需要一行代碼就可以啓動SecondActivity,如下所示:
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SecondActivity.actionStart(FirstActivity.this, "data1", "data2");
}
});
        養成一個良好的習慣,給你編寫的每個活動都添加類似的啓動方法,這樣不僅可以讓啓動活動變得非常簡單,還可以節省不少有同事過來詢問你的時間。





























發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章