先扯兩句
終于把檔案的事搞定了,據(jù)傳聞,如果畢業(yè)兩年后檔案還留校沒有調(diào)到生源地人社局或者是工作單位所在城市人社局的話,檔案就會(huì)變成“死檔”,
“死檔”有兩種情況,一是超過擇業(yè)期未就業(yè)的同學(xué),檔案在打回原籍過程中丟失;二是檔案拿在自己手里超過兩年。如果檔案處理不得當(dāng),很有可能影響你報(bào)考公務(wù)員、事業(yè)單位等,也會(huì)影響以后的職稱評定和工齡認(rèn)定。
所以如果有還沒有辦理的可要快點(diǎn)嘍,雖然我們碼農(nóng)一時(shí)半會(huì)都用不上,但是有備無患嘛。
好了,閑言少敘,老規(guī)矩還是先上我的Git,然后開始正文吧。
MyBaseApplication (https://github.com/BanShouWeng/MyBaseApplication)
正文
Toast
通過上一篇“《一個(gè)Android工程的從零開始》階段總結(jié)與修改BaseActivity上(抽象處理),已經(jīng)對BaseActivity的進(jìn)行了面目全非的調(diào)整,若是在遇到一個(gè)奇葩錯(cuò)誤之前,原本這次BaseActivity的封裝已經(jīng)結(jié)束了,下面就將進(jìn)入BaseLayoutActivity的封裝(也就是原本的BaseActivity的布局部分),可人算不如天算,公司拿APP出去演示,演示機(jī)華為暢享7忘記關(guān)閉飛行模式時(shí)打開APP,直接崩潰了,而導(dǎo)致崩潰的正是下面的錯(cuò)誤。
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
以我的英文水平翻譯過來就是“在Looper沒有準(zhǔn)備好的時(shí)候,在子線程中無法創(chuàng)建handler。”,看了一眼代碼,問題是出在了:
/**
* 消息提示框
*
* @param message 提示消息文本
*/
public void toast(String message) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
作為一個(gè)自成老頭子的小菜鳥自然一臉懵逼,多虧Xuelong_li大神的Can't toast on a thread that has not called Looper.prepare()中發(fā)現(xiàn)了答案,原來是由于
在子線程中彈出Toast,會(huì)報(bào)錯(cuò):java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare()。
需要加以修改,所以這里,我將自己的Toast封裝,做了如下調(diào)整:
private Toast toast;
/**
* 消息提示框
*
* @param message 提示消息文本
*/
@SuppressLint("ShowToast")
public void toast(String message) {
try {
if (toast != null) {
toast.setText(message);
} else {
toast = Toast.makeText(context, message, Toast.LENGTH_SHORT);
}
toast.show();
} catch (Exception e) {
// 解決在子線程中調(diào)用Toast的異常情況處理
Looper.prepare();
toast = Toast.makeText(context, message, Toast.LENGTH_SHORT);
toast.show();
Looper.loop();
}
}
- 首先將Toast提出來創(chuàng)建一個(gè)對象,防止每次toast都需要重新創(chuàng)建浪費(fèi)資源;
- 當(dāng)?shù)谝淮握{(diào)用,或者toast對象被回收時(shí),toast為空,則創(chuàng)建新的toast:toast = Toast.makeText(context, message, Toast.LENGTH_SHORT);
- 從第二次開始直接調(diào)用toast.setText(message)替換顯示文本;
- 無論toast之前處于什么狀態(tài),經(jīng)過上面的判斷或復(fù)制后,都確定toast存在,并有所要顯示的文本信息,所以調(diào)用toast.show()顯示toast信息;
- 當(dāng)出現(xiàn)開篇所述的異常時(shí),會(huì)被try-catch捕捉,此時(shí)采用Xuelong_li博客中所述的方法。
細(xì)心的或許會(huì)發(fā)現(xiàn),上面為什么會(huì)有@SuppressLint("ShowToast"),這個(gè)說實(shí)話,我也很無奈啊,由于上面調(diào)用的時(shí)候,有Toast.makeText(context, message, Toast.LENGTH_SHORT),很明顯,這里我沒有直接調(diào)用show展示,于是好心的AS專程提醒我了一下:
[圖片上傳失敗...(image-6303db-1522941221454)]
所以強(qiáng)迫癥的我為了不看到這個(gè)提示,只能加上忽略警告的注解,當(dāng)然,這是因?yàn)樵诖a中,雖然沒有直接飲用,但是后面肯定會(huì)調(diào)用到show方法,才添加的這條注解,在開發(fā)過程中,可不要習(xí)慣性不管三七二十一直接加上這條注解,到時(shí)候Toast真害羞不出來,都沒地方哭去。
jumpTo
這個(gè)方法從翻譯也能看出來,就是“跳轉(zhuǎn)到”,原本的BaseActivity封裝中也是有的,只是當(dāng)初命名是startActivity,最基本的封裝如下:
/**
* 跳轉(zhuǎn)頁面
*
* @param targetActivity 所跳轉(zhuǎn)的目的Activity類
*/
public void startActivity(Class<?> targetActivity) {
startActivity(new Intent(this, targetActivity);
}
代碼也很簡單,意圖(Intent)一共兩個(gè)參數(shù),當(dāng)前Activity.this和目標(biāo)activity的class——targetActivity。因?yàn)楫?dāng)前所定義的是將來所要調(diào)用后的activity的父類,所以這里的this就可以指代子類的this,就好像我們小時(shí)候出去,別人對我們的第一印象首先不是我們是誰誰誰,而是,我們是誰誰誰的兒子/女兒。
所以其實(shí)這里我們需要的參數(shù)也就只有targetActivity而已(傳參的暫不考慮,后面會(huì)添加),所以就有了上述方法的形式。不過這里就會(huì)有個(gè)問題,那就是我們無法判斷自己傳入的targetActivity的正確性(是否是Activity的class、該Activity是否在manifest文件中注冊過),所以很可能因?yàn)槲覀兊囊粫r(shí)手誤,填寫了一個(gè)不正當(dāng)?shù)膮?shù)APP程序崩潰。所以當(dāng)前的BaseActivity做了如下處理:
/**
* 跳轉(zhuǎn)頁面
*
* @param targetActivity 所跳轉(zhuǎn)的目的Activity類
*/
public void jumpTo(Class<?> targetActivity) {
Intent intent = new Intent(this, targetActivity);
if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
startActivity(intent);
} else {
Logger.e(getName(), "activity not found for " + targetActivity.getSimpleName());
}
}
if中的判斷條件就是驗(yàn)證當(dāng)前Activity是正確,如果正確,則執(zhí)行startActivity(intent);不正確,項(xiàng)目中只是不執(zhí)行對應(yīng)的跳轉(zhuǎn)操作,但是會(huì)打印出哪個(gè)類無法獲取的Error。
下面列舉的是當(dāng)前的BaseActivity中的所有跳轉(zhuǎn)界面封裝方法,因?yàn)镮ntent封裝到j(luò)umpTo方法中了,所以無法直接為其賦值。所以這里的傳參選擇了使用Bundle,看過我的《一個(gè)Android工程的從零開始》階段總結(jié)與修改3-BaseActivity上(抽象處理)的也會(huì)知道,我在其中封裝了一個(gè)抽象方法getBundle(Bundle bundle),正是用來接收這里傳遞過去的Bundle的。而如果想要調(diào)用startActivityForResult,自然需要在前面說到的this和targetActivity的基礎(chǔ)上再加上一個(gè)int型的參數(shù)requestCode,在多個(gè)事件調(diào)用startActivityForResult時(shí),可以用于區(qū)分,所以組合下來一共有下面的四種方法。
/**
* 跳轉(zhuǎn)頁面
*
* @param targetActivity 所跳轉(zhuǎn)的目的Activity類
*/
public void jumpTo(Class<?> targetActivity) {
Intent intent = new Intent(this, targetActivity);
if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
startActivity(intent);
} else {
Logger.e(getName(), "activity not found for " + getName(targetActivity))?);
}
}
/**
* 跳轉(zhuǎn)頁面
*
* @param targetActivity 所跳轉(zhuǎn)的目的Activity類
* @param bundle 跳轉(zhuǎn)所攜帶的信息
*/
public void jumpTo(Class<?> targetActivity, Bundle bundle) {
Intent intent = new Intent(this, targetActivity);
if (bundle != null) {
intent.putExtra("bundle", bundle);
}
if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
startActivity(intent);
} else {
Logger.e(getName(), "activity not found for " + getName(targetActivity)));
}
}
/**
* 跳轉(zhuǎn)頁面
*
* @param targetActivity 所跳轉(zhuǎn)的Activity類
* @param requestCode 請求碼
*/
public void jumpTo(Class<?> targetActivity, int requestCode) {
Intent intent = new Intent(this, targetActivity);
if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
startActivityForResult(intent, requestCode);
} else {
Logger.e(getName(), "activity not found for " + getName(targetActivity)));
}
}
/**
* 跳轉(zhuǎn)頁面
*
* @param targetActivity 所跳轉(zhuǎn)的Activity類
* @param bundle 跳轉(zhuǎn)所攜帶的信息
* @param requestCode 請求碼
*/
public void jumpTo(Class<?> targetActivity, int requestCode, Bundle bundle) {
Intent intent = new Intent(this, targetActivity);
if (bundle != null) {
intent.putExtra("bundle", bundle);
}
if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
startActivityForResult(intent, requestCode);
} else {
Logger.e(getName(), "activity not found for " + getName(targetActivity));
}
}
當(dāng)然上述的判斷條件添加前需要大家先斟酌一下:
其一這里需要先聲明一點(diǎn),雖然使用上述的方法,可以避免方法targetActivity不存在時(shí)的崩潰問題,但是卻也不會(huì)真正跳轉(zhuǎn)到用戶期望的Activity中去,治標(biāo)不治本。
其二雖然加上了提示,可是畢竟只是在日志中打印出一個(gè)找不到的類名而已,開發(fā)中,并沒有崩潰日志中的定位信息來得那么直接,容易查找。
所以,建議大家在上線時(shí),為了避免意外崩潰時(shí)可以加上這些判斷的,但是開發(fā)者過程中還是不要添加了,也盡量測試到所有跳轉(zhuǎn)情況,讓這些方法加上,也不要有用武之地
getName
最近兩篇博客,大家一定不少看到這個(gè)方法,但是直接調(diào)用的話,系統(tǒng)是沒有提供對應(yīng)的方法,或許會(huì)有人疑問,這個(gè)方法是用來做什么的呢?解密之前先來看看封裝的方法,或許有人就能知道具體是做什么的了:
/**
* 獲取當(dāng)前Activity類名
*
* @return 類名字符串
*/
protected String getName() {
return getClass().getSimpleName();
}
/**
* 獲取目標(biāo)類的類名
*
* @param clz 需要獲取名稱的類
* @return 類名字符串
*/
protected String getName(Class<?> targetClass) {
return targetClass.getSimpleName();
}
沒錯(cuò),這兩個(gè)方法就是用來獲取類名的,畢竟開發(fā)中出現(xiàn)了問題,卻不知道究竟應(yīng)該到哪個(gè)類中查找(崩潰日志除外)。
當(dāng)然,其實(shí)獲取類名一共有三個(gè)方法,我們這里使用的是getSimpleName(),還有兩個(gè)分別為getName()和getCanonicalName()(這第三個(gè)是我查前兩個(gè)區(qū)別的時(shí)候才發(fā)現(xiàn)的,又學(xué)到了新知識啊),具體三者之間又什么區(qū)別呢?Ju_Sang的簡單比較 getName()、getCanonicalName()、getSimpleName() 的異同
getName()方法,以String的形式,返回Class對象的‘實(shí)體’名稱;
getSimpleName()方法,是獲取源代碼中給出的‘底層類’簡稱;
對于我們這些入門級選手基本就夠用了,再具體的信息,就請大家自行百度
(能翻墻的選手自行Google)。我個(gè)人的理解就是而這里,個(gè)人的習(xí)慣getSimpleName()就足夠用,而不需要再加上完整的包名,當(dāng)需要查對應(yīng)的類在哪里時(shí),我們只需要在AS界面雙擊Shift,就可以在彈出的彈窗中輸入想要查找的類了。當(dāng)然,以上的觀點(diǎn)都是建立在你不會(huì)頻繁的在不同包下創(chuàng)建同名類的前提下。
而這里之所以要定義兩個(gè)方法,完全是因?yàn)橛械臅r(shí)候,我們想要獲取的類名的類并不是當(dāng)前的Activity本身,所以這個(gè)時(shí)候就需要第二個(gè)方法,我們將對應(yīng)的類傳入,就可以獲取類名,更加的靈活。
activities與activitiesMap
剛看到這節(jié)的標(biāo)題或許會(huì)有人比較困惑,本篇博客不是叫方法封裝嗎,可是從這節(jié)標(biāo)題看,怎么出來一個(gè)List和一個(gè)Map,怎么都有點(diǎn)掛羊頭賣狗肉的意思呢?
好吧,首先我不得不承認(rèn),這兩個(gè)缺失不是方法名,但是它們卻與下面要說明的幾個(gè)方法有著千絲萬縷的關(guān)系。
首先呢,我們要?jiǎng)?chuàng)建一個(gè)List集合activities,目的就是用來存儲我們打開過的Activity;然后呢,新打開一個(gè)Activity就添加一條,沒關(guān)閉一個(gè)Activity就刪除對應(yīng)的一條;最后呢,接收到要返回的Activity,就將該Activity后打開的所有Activity統(tǒng)統(tǒng)調(diào)用一遍finish即可。
當(dāng)我們調(diào)用backTo的時(shí)候,防止出現(xiàn)想要返回的不存在,多見于同一個(gè)Activity會(huì)返回多個(gè)Activity時(shí)的判斷出現(xiàn)邏輯錯(cuò)誤,返回了還未開啟的Activity,雖然說一般情況下,這個(gè)錯(cuò)誤都會(huì)隨著自測或者公司測試的同事測試時(shí)反饋回來予以修改,可不怕一萬就拍萬一,尤其一些初創(chuàng)的小團(tuán)隊(duì),團(tuán)隊(duì)的一切都透露著慢慢的隨意的時(shí)候,這部分處理雖然還是治標(biāo)不治本,但至少不會(huì)讓用戶看到崩潰的不好體驗(yàn)。
首先是純Activity集合的部分,這部分過了在來敘述為什么會(huì)比原本的BaseActivity封裝多出了一個(gè)Map集合:
/**
* 當(dāng)前打開Activity存儲List
*/
private static List<Activity> activities = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activities.add(this);
...
}
@Override
protected void onDestroy() {
super.onDestroy();
// 移除當(dāng)前的Activity
activities.remove(this);
...
}
/**
* 返回歷史界面
*
* @param targetActivity 指定的Activity對應(yīng)的class
*/
public static void backTo(Class<?> targetActivity) {
int size = activities.size();
for (int i = size - 1; i >= 0; i--) {
if (targetActivity.equals(activities.get(i).getClass())) {
break;
} else {
activities.get(i).finish();
}
}
}
以上就是前面說到的基本流程,這樣就能維持activities中的Activity能夠與當(dāng)前打開的頁面層級保持一致。
- backTo中沒有調(diào)用remove移除activities中的Activity是因?yàn)樵谡{(diào)用finish()的時(shí)候,對應(yīng)結(jié)束的Activity會(huì)調(diào)用自己的onDestroy(),這樣可以確保:a、當(dāng)Activity正常退出時(shí),在onDestroy()方法中remove保證activities與打開的頁面層級相同;b、當(dāng)backTo被中調(diào)用時(shí),其間的每個(gè)Activity都能夠被activities remove;c、當(dāng)backTo被調(diào)用時(shí),不會(huì)因?yàn)樵赽ackTo中remove了對應(yīng)Activity而導(dǎo)致在onDestroy中調(diào)用時(shí)由于不存在對應(yīng)Activity而導(dǎo)致的異常。
- 采用靜態(tài)方法,完全是因?yàn)榉庆o態(tài)時(shí),Activity集合只能存儲當(dāng)前的Activity,而而不會(huì)時(shí)完整的Activity層級關(guān)系。
- backTo使用public是因?yàn)樵陂_發(fā)時(shí),可能會(huì)出現(xiàn)不只是在Activity中調(diào)用該方法,也可能是在自定義列表適配器中、BroadcastReceiver和Service等其他環(huán)境下調(diào)用。
一般而言,如上就完成了我們返回制定Activity的封裝,做多再加上一個(gè)返回主頁面的方法:
/**
* 關(guān)閉所有Activity(除MainActivity以外)
*/
public void finishActivity() {
for (Activity activity : activities) {
if (activity.getClass().equals(MainActivity.class))
break;
activity.finish();
}
}
之所以加上“activity.getClass().equals(MainActivity.class)”判斷,主要是因?yàn)榍懊嫣砑覣ctivity時(shí)沒有過濾掉主頁面。也可以在onCreate方法中判斷,如果是主頁面就不添加,不過這么一來每次創(chuàng)建一個(gè)A是不是超簡單!沒錯(cuò),之前我也是這么設(shè)計(jì)的。
不過后來的使用呢,總體來說還是沒有發(fā)生什么問題的,但是最為一個(gè)腦洞打開的老年人,就好像前面判斷targetActivity是否存在一樣,總會(huì)過度設(shè)計(jì)一些功能,所以下面的部分大家根據(jù)需要看就好,實(shí)在用不上,當(dāng)前這一小節(jié)也可以跳過,下一節(jié)是getView,可以自行Ctrl+v/?command+v搜索。
(剛買了個(gè)蘋果本,發(fā)現(xiàn)各種快捷鍵不同,還要適應(yīng)一段時(shí)間。另外,蘋果本到手了,自然閑暇時(shí)間也要研究研究IOS開發(fā),屆時(shí)會(huì)同步更新學(xué)習(xí)筆記,有興趣的朋友可以一起學(xué)習(xí)哦)
關(guān)于驗(yàn)證activities中是否存在對應(yīng)Activity的嘗試
- 判斷activities中是否有包含目標(biāo)class對應(yīng)的Activity————需要通過for循環(huán),遍歷每個(gè)Activity并作對比,浪費(fèi)資源;
- backTo傳遞Activity參數(shù)————暫時(shí)無法實(shí)現(xiàn);
- activities存儲每一個(gè)Activity的class————通過class無法調(diào)用對應(yīng)Activity的finish方法。
根據(jù)以上的嘗試,最后無奈之下,只能選擇再添加一個(gè)參數(shù)也就是Map集合,其value為Activity自身,而key則是Activity對應(yīng)的class:
/**
* 當(dāng)前打開Activity存儲List
*/
private static List<Activity> activities = new ArrayList<>();
**
* 調(diào)用backTo方法時(shí),驗(yàn)證該Activity是否已經(jīng)存在
*/
rivate static Map<Class<?>, Activity> activitiesMap = new HashMap<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activities.add(this);
activitiesMap.put(getClass(), this);
...
}
@Override
protected void onDestroy() {
super.onDestroy();
// 移除當(dāng)前的Activity
activities.remove(this);
activitiesMap.remove(getClass());
...
}
/**
* 關(guān)閉所有Activity(除MainActivity以外)
*/
public void finishActivity() {
for (Activity activity : activities) {
if (activity.getClass().equals(MainActivity.class))
break;
activity.finish();
}
}
/**
* 返回歷史界面
*
* @param targetActivity 指定的Activity對應(yīng)的class
*/
public static void backTo(Class<?> targetActivity) {
int size = activities.size();
if (activitiesMap.get(targetActivity) != null)
for (int i = size - 1; i >= 0; i--) {
if (targetActivity.equals(activities.get(i).getClass())) {
break;
} else {
activities.get(i).finish();
}
}
else
Logger.e(activities.get(size - 1).getClass().getSimpleName(), "activity not open for " + targetActivity.getSimpleName());
}
我們只需要取判斷map中class作為key能否渠道對應(yīng)的Activity即可,有的情況下就正常返回,沒有時(shí)則輸出一條log日志即可。看到這里可能會(huì)有人問,如果map這么強(qiáng)大的話,為什么這里不直接使用map,反而要多一個(gè)List集合呢?對此,老頭子我也很無奈啊,誰讓map是無序的呢,如果真的在這里直接使用map集合的話,說不好不該關(guān)掉的Activity關(guān)掉不少,而真正應(yīng)該關(guān)掉的Activity還在原地對著你微笑呢!
getView
從字面理解,很簡單,這就是獲取View,相比看到這個(gè)說法,大家第一反應(yīng)就會(huì)想到findViewById,不錯(cuò),這里就是對于findViewById的封裝。不過關(guān)于這個(gè)部分,我是思考考了很久才決定這篇博客還是寫出來的,至于原因,我們先上代碼:
/**
* 簡化獲取View
*
* @param viewId View的ID
* @param <T> 將View轉(zhuǎn)化為對應(yīng)泛型,簡化強(qiáng)轉(zhuǎn)的步驟
* @return ID對應(yīng)的View
*/
@SuppressWarnings("unchecked")
public <T extends View> T getView(int viewId) {
return (T) findViewById(viewId);
}
/**
* 簡化獲取View
*
* @param view 父view
* @param viewId View的ID
* @param <T> 將View轉(zhuǎn)化為對應(yīng)泛型,簡化強(qiáng)轉(zhuǎn)的步驟
* @return ID對應(yīng)的View
*/
@SuppressWarnings("unchecked")
public <T extends View> T getView(View view, int viewId) {
return (T) view.findViewById(viewId);
}
/**
* 簡化獲取View
*
* @param layoutId 父布局Id
* @param viewId View的ID
* @param <T> 將View轉(zhuǎn)化為對應(yīng)泛型,簡化強(qiáng)轉(zhuǎn)的步驟
* @return ID對應(yīng)的View
*/
@SuppressWarnings("unchecked")
public <T extends View> T getView(int layoutId, int viewId) {
return (T) LayoutInflater.from(context).inflate(layoutId, null).findViewById(viewId);
}
這部分的功能很簡單,就是將findViewById獲取到的View通過泛型傳出來,這樣就可以減少一步強(qiáng)轉(zhuǎn)的操作。而至于為什么這么封裝,其實(shí)很簡單,畢竟大多數(shù)人還是與我一項(xiàng)“標(biāo)榜”自己的一樣————懶!
實(shí)際上,對于初學(xué)者來說,這個(gè)強(qiáng)轉(zhuǎn)的功能還是有必要的,畢竟如果沒有類型的強(qiáng)轉(zhuǎn)的話,初學(xué)者很容易將類型與Id對應(yīng)錯(cuò),倒不是說老鳥不會(huì)出這樣的錯(cuò)誤,只是初學(xué)者一旦這么使用,當(dāng)運(yùn)行的時(shí)候看到那鮮紅的類轉(zhuǎn)換異常絕對會(huì)一臉懵逼欲哭無淚的,而同樣的問題老鳥只會(huì)狠狠拍一下額頭,然后用遠(yuǎn)少于拍額頭的時(shí)間改正。所以說,這個(gè)功能,對于有一定Android開發(fā)經(jīng)營的朋友來說,實(shí)在是個(gè)雞肋,就連Google都發(fā)覺了這個(gè)問題,因此在新發(fā)布的AS 3.0的AppCompatActivity中,已經(jīng)添加了如下處理:
@SuppressWarnings("TypeParameterUnusedInFormals")
@Override
public <T extends View> T findViewById(@IdRes int id) {
return getDelegate().findViewById(id);
}
也就是說,使用AS 3.0的朋友,媽媽再也不用擔(dān)心我們還要多一步View強(qiáng)轉(zhuǎn)了。可是我封裝的后兩個(gè)方法在當(dāng)前版本的AS 3.0中還沒有查找到替代方法,這讓我在這篇博客添加這部分的時(shí)候,負(fù)罪感減少了不少。只說明一點(diǎn),那就是后兩步這里傳遞進(jìn)來的嚴(yán)謹(jǐn)來說實(shí)際上不應(yīng)該是普通的View或id,而是ViewGroup或其id,也就是可以擁有子控件的控件,因?yàn)橹挥心苡凶涌丶目丶覀儾拍芡ㄟ^喊它兒子名字的方式找到那個(gè)砸了自己家玻璃的搗蛋鬼,對于那些做了絕育手術(shù)的貓,我也就只能為它默哀三秒鐘了。
今天的博客就都這里了,當(dāng)然不是說BaseActivity的封裝只有這些內(nèi)容,還有網(wǎng)絡(luò)狀態(tài)監(jiān)聽之類的方法,只不過這篇博客的內(nèi)容是“階段總結(jié)與修改”,前面有些相關(guān)的方法已經(jīng)重復(fù)說明不少了,那些與之前博客中所說相同的內(nèi)容就不多做贅述了,有興趣的朋友可以翻看一下我之前的博客,也算見證一下我個(gè)人的成長吧。