每一個總結都是個人遇到或者看資料時發現的點,說的比較簡單。其中一些基礎的知識還需讀者去自行了解,這裏的每一條總結可能都會隨着版本的更新而無效,大家瞭解即可,每一篇總結25條。
1.
不能在onPause中做過多複雜的操作,因爲必須onPause執行完成以後新Activity才能Resume。
2.
onSaveInstanceState是在Activity被異常終止的情況下才會調用,正常情況下是不會調用的。它的調用時機是onStop之前,與onPause沒有先後順序關係。它會把存貯的Bundle數據傳給onRestoreInstanceState和onCreate兩個方法,而onRestoreInstanceState方法則會在onStart之後調用。系統會自動給我們保存一些當前Activity的視圖結構,比如文本框中的文字等。
3.
和Activity一樣,View也有onSaveInstanceState和onRestoreInstanceState兩個方法。
4.
通過修改AndroidManifest.xml文件裏Activity的configChanges可以避免某些情況下系統重建Activity,比如旋轉屏幕等,但是它會調用onConfigurationChanged的方法。
5.啓動模式的特殊點
模式 | 備註 |
---|---|
standard 標準模式 | 誰啓動了具有該模式的Activity,該Activity就在誰的棧裏。當ApplicationContext啓動該模式的Activity時需要指定FLAG_ACTIVITY_NEW_TASK標記,這時候這個Activity是以singleTask的模式啓動的 |
singleTop 棧頂複用模式 | 啓動該模式的Activity在棧頂時雖然不會被重新創建,但是會調用它的onNewIntent方法 |
singleTask 棧內複用模式 | 啓動該模式的Activity在棧內時不會被重新創建,和singleTop一樣,會調用它的onNewIntent方法。重點:當棧內的Activity爲ABCD時,在當前棧啓動該模式的Activity B時B之上的Activity會全部出棧,棧內只剩下AB |
singleInstance 單實例模式 | 這個模式只需說明一個使用情況就可以瞭解,比如開發一個任務提醒的App,需要到某個時間彈出一個Activity來提醒用戶。用戶那個時間點在瀏覽微信,使用這個模式,彈出Activity之後用戶點返回就會重新退回剛剛微信的界面,如果是標準模式則會進入你的App,顯然是不符合邏輯的 |
6.設置啓動模式的兩個方法和區別
方法 | 區別 |
---|---|
AndroidManifest | 優先級低,無法爲Activity設置FLAG_ACTIVITY_CLAER_TOP(銷燬目標Activity和它之上的所有Activity,重新創建目標Activity) |
intent.addFlags | 優先級高,無法爲Activity指定singleInstance模式 |
7.build.gradle
外層的build.gradle
buildscript {
repositories {
jcenter()
//這個是代碼託管庫,用於託管代碼
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
//這裏是gradle的引用,版本號爲2.3.3,這是用來構建安卓項目的,
//當然了,Java、C++它也可以構建
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
內層(APP下)的build.gradle
//這裏有兩個plugin可選
//1.com.android.application 2.com.android.library
//1.可以直接運行 2.只能依附於別的引用程序模塊運行
apply plugin: 'com.android.application'
android {
compileSdkVersion 27 //這個是項目的sdk版本號
buildToolsVersion "28.0.2" //這個是構建項目的工具的版本
defaultConfig {
applicationId "pjk.it.bjfu.buildgradle" //項目的包的名稱
minSdkVersion 24 //最低兼容的安卓版本號
targetSdkVersion 27 //你的程序在哪個版本上進行開發的,
//所有的功能在此版本上應該都是兼容的
versionCode 1 //項目的版本號
versionName "pjk_1.0" //項目的版本號對應的版本名
//以上兩個屬性非常重要,是應用商店判斷應用有更新的重要依據
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
//用於測試的工具
}
buildTypes {
release {
minifyEnabled false
//是否對項目的代碼進行混淆 true是 false否
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//混淆用的文件
}
//通常會有debug和release兩個閉包,顧名思義,是用來測試和線上發佈的不同配置
}
}
//依賴庫,大致有本地依賴(jar包)、遠程依賴、和庫依賴
//compile fileTree本地依賴、compile遠程依賴、compile project(':helper')庫依賴
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support.constraint:constraint-layout:1.0.2'
//遠程依賴在gradle的時候如果本地沒有緩存,就會鏈接互聯網下載,所以編譯的時候需要網速好
testCompile 'junit:junit:4.12'
//測試用例的依賴
}
8、使用setAgruments從Activity向Fragment發送信息
使用方法
Activity中:
Fragment fragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putString("something_key", "something_value");
fragment.setArguments(bundle);
Fragment中:
onCreateView{
Bundle bundle = getArguments();
String something = bundle.getString("something_key");
}
這樣就在創建的時候將activity中的數據傳遞給fragment了,是不是很簡單。
9、日誌的查看
日誌名稱 | 對應級別 | 重要程度 | 備註說明 |
---|---|---|---|
Log.v() | verbose | ★ | 意義比較小的日誌,一般不用 |
Log.d() | debug | ★★ | 打印調試的信息,調試用這個 |
Log.i() | info | ★★★ | 打印一些數據,比如請求的數據,用戶輸入的數據等 |
Log.w() | warm | ★★★★ | 打印警告信息,最好修復一下帶有warm的信息 |
Log.e() | error | ★★★★★ | 錯誤信息,程序遇到這樣的bug會崩潰,必須修復 |
如下圖所示,就算你不打印日誌,也會出現運行時的日誌的,你選擇重要程度低的日誌時,會自動顯示它和它重要程度以上的日誌信息,例如你的程序崩潰了,你就選擇Error就行,先解決重要的bug。
10、Context在Android中的作用
什麼是Context
Context在Android中,可以認爲是當前對象在程序中所處的一個環境,一個與系統交互的過程。
Context到底是什麼呢?一個Activity就是一個Context,一個Service也是一個Context。Android程序員把“場景”抽象爲Context類,他們認爲用戶和操作系統的每一次交互都是一個場景。可以認爲是一個展示View控件和各種服務的平臺或者鏡頭。
獲得Context的方法
一般用以下兩種方法來獲取Context
getApplication()方法只有在Activity和Service中才能調用的到。
如果在一些其它的場景,比如BroadcastReceiver中也想獲得Application的實例,這時就可以藉助getApplicationContext()方法了。
11、修飾符的注意點
修飾符 | 當前類 | 同一包內 | 子孫類(同一包) | 子孫類(不同包) | 其他包 |
---|---|---|---|---|---|
public | Y | Y | Y | Y | Y |
protected | Y | Y | Y | Y/N | N |
default | Y | Y | Y | N | N |
private | Y | N | N | N | N |
子類與基類在同一包中:被聲明爲 protected 的變量、方法和構造器能被同一個包中的任何其他類訪問;
子類與基類不在同一包中:那麼在子類中,子類實例可以訪問其從基類繼承而來的 protected 方法,而不能訪問基類實例的protected方法。
protected 訪問修飾符可以修飾類及其方法和成員變量,但是接口及接口的成員變量和成員方法不能聲明爲 protected。
請注意以下方法繼承的規則:
-
父類中聲明爲 public 的方法在子類中也必須爲 public。
-
父類中聲明爲 protected 的方法在子類中要麼聲明爲 protected,要麼聲明爲 public,不能聲明爲 private。
-
父類中聲明爲 private 的方法,不能夠被繼承。
12.啓動Service的不同週期
使用startService()
使用bindService()
同時使用startService()和bindService()
13、RecycleView下拉刷新
嵌套SwipeRefreshLayout
文件相關:
XML文件
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.v4.widget.SwipeRefreshLayout>
Activity文件:
swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swipeRefreshLayout);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(true);
//TODO
}
});
這樣就在下拉的時候就可以執行相關語句刷新RecyclerView