Android 經(jīng)典總結(jié)案例一
目錄介紹:
1.完美解決onActivityResult提前執(zhí)行調(diào)用的一系列問題
1.1 出現(xiàn)的問題
1.2 解決方案
1.3 相關(guān)原理說明
1.4 知識拓展
2.EditText調(diào)用軟鍵盤搜索的setOnKeyListener方法事件執(zhí)行兩次
2.1 出現(xiàn)的問題
2.2 解決方案
2.3 相關(guān)原理說明
2.4 知識拓展
3.關(guān)于64k方法書限制的原理和解決方案探討
3.1 先看看報錯
3.2 64k****產(chǎn)生原因?
3.3 如何解決64k的問題
3.4 優(yōu)化Multidex的開發(fā)和構(gòu)建
好消息
- 博客筆記大匯總【16年3月到至今】,包括Java基礎(chǔ)及深入知識點(diǎn),Android技術(shù)博客,Python學(xué)習(xí)筆記等等,還包括平時開發(fā)中遇到的bug匯總,當(dāng)然也在工作之余收集了大量的面試題,長期更新維護(hù)并且修正,持續(xù)完善……開源的文件是markdown格式的!同時也開源了生活博客,從12年起,積累共計47篇[近20萬字],轉(zhuǎn)載請注明出處,謝謝!
- 鏈接地址:https://github.com/yangchong211/YCBlogs
- 如果覺得好,可以star一下,謝謝!當(dāng)然也歡迎提出建議,萬事起于忽微,量變引起質(zhì)變!
1.完美解決onActivityResult提前執(zhí)行調(diào)用的一系列問題
這是原本要啟動的MainActivity
int requestCode = 200;
Intent intent = new Intent(this,SecondActivity.class);
startActivityForResult(intent,requestCode);
SecondActivity回傳攜帶的數(shù)據(jù)
Intent mIntent = new Intent();
mIntent.putExtra("addr_id", retData.get(position));
// 設(shè)置結(jié)果,并進(jìn)行傳送
setResult(resultCode, mIntent);
finish()
清單文件manifest.xml配置
<activity android:name=".activity.SecondActivity" android:launchMode="singleTask"/>
1.1.問題:代碼沒有任何問題,onActivityResult方法一直回調(diào)不過來數(shù)據(jù),debug調(diào)試以后才發(fā)現(xiàn)onActivityResult方法在開啟另外一個activity的時候提前執(zhí)行了
1.2.解決方案: 發(fā)現(xiàn)manifest.xml配置AddressActivity的啟動模式是singleTask,就抱著試試看的態(tài)度,把他改成了標(biāo)準(zhǔn)啟動模式,然后突然回傳數(shù)據(jù)
1.3.原理說明:
如圖:假設(shè)當(dāng)前的應(yīng)用程序存在兩個棧:其中一個直接顯示在屏幕上負(fù)責(zé)與用戶完成交互,叫BackStack;另一個是隱藏在后臺的background task,且位于該棧頂?shù)腁ctivity Y的啟動模式被設(shè)置為singleTask。
參考官方文檔可知:

在上圖中,存在著前兩個棧,其中直接顯示在屏幕上與用戶交互的Back Stack,及另一個隱藏在后臺的Background Task,該棧棧頂?shù)腁ctivity Y其launchMode為singleTask。
如果在Activity 2中調(diào)用BackgroundTask中已經(jīng)啟動過的Activity Y,則Background Task內(nèi)占據(jù)屏幕并且該Task下所有的棧都會保留當(dāng)前的棧位置及順序push進(jìn)Back Task形成新的結(jié)構(gòu),順序由上至下為Activity Y→Activity X→Activity 2→Activity 1。
在Activity Y界面按返回鍵,則ActivityY出棧,Activity X占據(jù)屏幕!注意,由Activity2調(diào)用的Activity Y,但返回鍵后,回退顯示的是Activity X!所以即使在Activity Y執(zhí)行setResult(),Activity 2也是無法接收到的。換回文章開頭的問題,即在JumpActivity處啟動LoginActivity(已經(jīng)被設(shè)置singleTask了),則LoginActivity的setResult()結(jié)果有可能不會傳給JumpActivity。
繼續(xù)按返回鍵,則才回到Activity 2。
由于這種現(xiàn)象的存在,所以android系統(tǒng)處于某種保護(hù)機(jī)制,發(fā)現(xiàn)將要跳轉(zhuǎn)的Activity的啟動模式是singleTask時,若需要執(zhí)行onActivityResult()函數(shù)則立即執(zhí)行。這樣就好理解多了。
1.4.知識延伸:
singleTop模式,可用來解決棧頂多個重復(fù)相同的Activity的問題。
singleTask模式和后面的singleInstance模式都是只創(chuàng)建一個實例的。
當(dāng)intent到來,需要創(chuàng)建singleTask模式Activity的時候,系統(tǒng)會檢查棧里面是否已經(jīng)有該Activity的實例。如果有直接將intent發(fā)送給它。
singleInstance模式解決了這個問題(繞了這么半天才說到正題)。讓這個模式下的Activity單獨(dú)在一個task棧中。這個棧只有一個Activity。導(dǎo)游應(yīng)用和google地圖應(yīng)用發(fā)送的intent都由這個Activity接收和展示。
2.EditText調(diào)用軟鍵盤搜索的setOnKeyListener方法事件執(zhí)行兩次
etProjectName.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
// 先隱藏鍵盤
((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(PublishProjectActivity.this.getCurrentFocus()
.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
//進(jìn)行搜索操作的方法,在該方法中可以加入mEditSearchUser的非空判斷
**search(); //執(zhí)行兩次,想一想為什么?**
return true;
}
return false;
}
});
2.1.問題:點(diǎn)擊后事件執(zhí)行兩次
2.2.原理分析:
setOnKeyListener之所以執(zhí)行兩次就是因為down和up占用了
2.3.解決方案:
第一種方案
etProjectName.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
**//發(fā)現(xiàn)執(zhí)行了兩次因為onkey事件包含了down和up事件,所以只需要加入其中一個即可。**
** //這個是個取巧的辦法**
** if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN)** {
// 先隱藏鍵盤
((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(PublishProjectActivity.this.getCurrentFocus()
.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
//進(jìn)行搜索操作的方法,在該方法中可以加入mEditSearchUser的非空判斷
search(); //執(zhí)行兩次,想一想為什么?
return true;
}
return false;
}
});
第二種方案
et.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event){
//判斷是否是“放大鏡”鍵【簡稱搜索鍵】
if(actionId == EditorInfo.IME_ACTION_SEARCH){
//隱藏軟鍵盤
//對應(yīng)邏輯操作
return true;
}
return false;
}
});
需要注意的是 setOnEditorActionListener這個方法,并不是在我們點(diǎn)擊EditText的時候觸發(fā),也不是在我們對EditText進(jìn)行編輯時觸發(fā),而是在我們編輯完之后點(diǎn)擊軟鍵盤上的各種鍵才會觸發(fā)
2.4.知識延伸:
修改Editview屬性:Android:imeOptions="actionSearch" 在該Editview獲得焦點(diǎn)的時候?qū)ⅰ盎剀嚒辨I改為“搜索”
android:singleLine="true" 不然回車【搜索】會換行
可以隨自己的需求更改軟鍵盤右下角的顯示樣式,例如:搜索,下一步,Q(搜索圖標(biāo))
actionNone : 按下后光標(biāo)到下一行(回車)
actionGo : 按下后搜索(Go)
actionSearch : 放大鏡【搜索】
actionSend : Send 按下后發(fā)送
actionNext : Next 下一步
actionDone : Done,確定/完成,隱藏軟鍵盤(包括不是最后一個文本輸入框的情況也會隱藏)
使用方法:在xml里面寫布局時直接加給EditTxt的imeOptions屬性,例如:
項目開發(fā)中涉及到按鍵事件處理:
**“dispatchKeyEvent” “onKeyDown ”“onKeyLisenter” 簡單理解**
接受按鍵優(yōu)先級:
**dispatchKeyEvent > Activity的onKeyDown > view的onKeyLisenter**
其中按鍵處理事件return true ;表示已消耗此事件,不再繼續(xù)傳遞;
3.關(guān)于64k方法書限制的原理和解決方案探討
3.1 先看看報錯,截圖如下
[圖片上傳中。。。(2)]
3.2 產(chǎn)生原因?
Android APK文件本質(zhì)上是一個壓縮文件,它包含的classes.dex文件是Dalvik字節(jié)碼文件,這個dex文件中存放的就是編譯后的Java代碼。Dalvik可執(zhí)行文件規(guī)范限制了單個.dex文件最多引用的方法數(shù)是65536個。Android官方的叫法是64k,也就是1024x64=65536個Java方法。
其中包含第三方庫,App應(yīng)用,以及Framework及自身的方法。
3.3 如何解決64k的問題
google為了規(guī)避上述問題,推出了MultiDex解決方案解決方法數(shù)超限問題。
A:首先需要配置build.gradle文件【注意是項目下的build文件】
添加代碼如下所示:
android {
compileSdkVersion 21
buildToolsVersion "21.1.0" //必須使用21或之后的版本
defaultConfig {
minSdkVersion 14
targetSdkVersion 21
// Enabling multidex support.
**multiDexEnabled true**
}
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
B:配置Application
如果用戶沒有重寫Application,只需修改Manifest文件中的內(nèi)容:
<application
android:name="android.support.multidex.MultiDexApplication">
</application>
如果用戶繼承變重寫了Application,可以將繼承的Application換成MultiDexApplication。 或者重寫attachBaseContext() 方法
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this); //這個方法是在onCreate之前執(zhí)行的
}
特別注意,如果沒有實現(xiàn)這部分代碼,運(yùn)行時會出現(xiàn)NoClassDefFoundError的錯誤,尤其是在依賴三方函數(shù)庫時。
3.4 優(yōu)化Multidex的開發(fā)和構(gòu)建
這塊看書后還是不太懂,
后續(xù):
平時喜歡寫寫文章,筆記。別人建議我把筆記,以前寫的東西整理,然后寫成博客,所以我會陸續(xù)整理文章,只發(fā)自己寫的東西,敬請期待:
知乎:https://www.zhihu.com/people/yang-chong-69-24/pins/posts
領(lǐng)英:https://www.linkedin.com/in/chong-yang-049216146/
簡書:http://www.itdecent.cn/u/b7b2c6ed9284
csdn:http://my.csdn.net/m0_37700275
網(wǎng)易博客:http://yangchong211.blog.163.com/
新浪博客:http://blog.sina.com.cn/786041010yc
github:https://github.com/yangchong211
喜馬拉雅聽書:http://www.ximalaya.com/zhubo/71989305/
脈脈:yc930211
開源中國:https://my.oschina.net/zbj1618/blog