1.Token
首先Token是一個怎麼樣的東西,Token存在的意義又在哪裡?學過php或是其他web開發的人都知道一個東西叫session和cookie,這些東西可以在伺服器或是本地儲存一些東西,比如說登入狀態,當使用者登入後可以通過session或是cookie在本地儲存一段時間的登入狀態,在這段時間內,使用者再度登入的時候就不用再輸入使用者名稱和密碼了,但是過了一段時間後,使用者需要再次進行身份認證,這樣一來的話,一方面節省了很多操作的步驟提升了操作體驗,同時也節省了很多伺服器請求,提高了伺服器效能,同時也保證了一定的安全性。
那麼這個功能如何在android中實現呢?很可惜的是在android中並沒有直接提供類似session或cookie的東西,這個時候就是通過Token來完成。Token的存在更像是一個令牌,比如說當我們需要實現具有使用者許可權的操作時,每一次操作都需要向伺服器傳送請求,讓伺服器完成在資料庫中進行使用者名稱和密碼,這些顯然對於伺服器的效能是很不利的。當然有人也會說我們可以在一次請求成功後將類似於user_id的東西儲存在本地,以後每次請求的時候用user_id進行操作,這樣不是就降低了伺服器的負擔,但是這樣的話存在一個問題,就是user_id一旦儲存在本地的時候,不是太有可能會自動回收掉,這樣一來的話就會導致一個問題,就是app無論何時開啟都是驗證通過的狀態,這樣一來安全性降低。而Token就是解決這樣一個問題的東西:
Token的定義:Token是服務端生成的一串字串,以作客戶端進行請求的一個令牌,當第一次登入後,伺服器生成一個Token便將此Token返回給客戶端,以後客戶端只需帶上這個Token前來請求資料即可,無需再次帶上使用者名稱和密碼。
2.Throwable:所有已實現的介面
3.key-value 鍵值對 和4繫結講解
- key 需要存的值的編號 Token
- value 需要存放的資料 dhjwejrdgwjefhjqtwjkawlfi8a34
4.CacheUtil快取工具類
CacheUtil中的存取方法
具體使用方法--LoginActivity
- 在 “登陸”按鈕的點選事件中傳入
【注意⚠️】
如果 “類.方法”的時候,方法出不來,那就說明,該方法還沒有被定義為靜態類,還不可以被呼叫。那就需要返回工具類中,將該方法改為靜態類的
CatheKey.TOKEN -- RetrofitFactory--自定義網路攔截器--獲取本地快取的token
- getInstance()--外部獲取例項物件
- 在 TaskGoApplication.java檔案中
- CatheKey.java
5.物件導向
原網址:https://www.cnblogs.com/dotgua/p/6354151.html?utm_source=itdadao&utm_medium=referral
1.extends與implements
- 一個子類只能擁有一個父類->類的繼承是單一繼承
- extends只能繼承一個類
- implements實現多繼承特性,繼承多個介面
- 介面與介面之間採用逗號分隔
2. super與this
- super:實現對父類成員的訪問,用來引用當前物件的父類
- this: 指向自己的引用
class Animal {
void eat() {
System.out.println("animal : eat");
}
}
class Dog extends Animal {
void eat() {
System.out.println("dog : eat");
}
void eatTest() {
this.eat(); // this 呼叫自己的方法
super.eat(); // super 呼叫父類方法
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Dog d = new Dog();
d.eatTest();
}
}
複製程式碼
輸出結果:
animal : eat
dog : eat
animal : eat
複製程式碼
3.final和static
- final
- 將類定義為不可繼承的,即:最終類
- 或用於修飾方法,表明該方法不能被子類重寫
- 變數加final就變成常量,不可被改變
【注】: 1.被final定義的類和這個類裡面的變數是兩回事,final定義類的時候,對類裡面的變數沒有任何影響,呼叫final類的方法對變數也沒有任何影響 2.被宣告為final類的方法自動的宣告為final,但例項變數並不是final
- static修飾成員變數 + static關鍵字可以修飾成員變數和方法,來讓它們變成類的所屬,而不是物件的所屬(物件是類的例項),解釋?
public class Person {
String name;
Int grades;
static int class;
}
例項化 20個Person物件,那就有了40個不同的 name 和 grades
但是 全全部部只有一個 class
複製程式碼
- static修飾成員方法
- "類名.方法名"呼叫該靜態方法
如果在一個類中,某方法不是靜態方法(非static修飾),那就不可以通過"類.方法"進行呼叫
複製程式碼
- static修飾靜態塊
- 建立物件時,static修飾的成員會首先被初始化
- static修飾的成員變數首先被初始化,隨後是普通成員,最後呼叫類的構造方法完成初始化
- 建立物件時,static修飾的成員會首先被初始化
4. 重寫與過載
- Overloading
- 方法過載是一個類中定義了多個方法名相同,而他們的引數的數量不同或數量相同而型別和次序不同,則稱為方法的過載
- Overriding
- 方法重寫是在子類存在方法與父類的方法的名字相同,而且引數的個數與型別一樣,返回值也一樣的方法,就稱為重寫
- 方法過載是一個類的多型性表現,而方法重寫是子類與父類的一種多型性表現
5.多型和虛方法
安卓多型運用--自定義圖形:http://blog.csdn.net/qq_32985981/article/details/50173503
6.封裝--對資料的隱藏
- 控制那些是自己所私有,哪些可以被共享使用
- 外部使用者只需要關心該類的功能和物件,不需要關心具體的實現過程和資料
7.Path 和Query
- 有問號的使用Query
- 只有 {...} 的使用Path
8.為了快取新使用者的Token
是想註冊的介面後 呼叫 登入介面
因為Token的儲存是在登入的介面上
9.執行緒問題
- 由於等使用者註冊後直接進入主介面,不需要再次進進行登入介面的相關操作,但是Token只能在登入的時候進行本地快取,所以⚠️⚠️,我們就可以在註冊介面 再一次 呼叫登入的介面
坑:兩個介面的呼叫,不能同時進行,不然開啟就是兩個執行緒同時進行,導致 一邊Toast出來“此使用者不存在”,一邊 又直接進入了主介面
廖雪峰執行緒章節
1. 多執行緒
- 多執行緒:讓任務交替執行
- 一個程式可以包含一個火多個執行緒
- 多程式穩定性比多執行緒穩定性高
- 一個程式的出問題,不影響其他程式
- 一個執行緒出問題,其他執行緒也會死
2.建立新執行緒
- 程式本身無法控制執行緒的先後順序
- 必須使用 start() 方法才能啟動新執行緒
- Thread.sleep()可以把當前執行緒暫停一段時間
8.Bundle
- 一種存放字串等型別資料的map型別的容器類
- 通過存放資料鍵(key)獲取對應的各種型別的值(value)
- 主要作用於Activity之間的資料傳遞
9.JAVA介面
1.介面與類的區別
- 介面不能例項化物件
- 介面沒有構造方法
- 介面中所有的方法必須是抽象方法
- 介面不能包含成員變數,除了static和final變數
- 介面不是被類繼承的,而是要被類實現的
- 介面支援多繼承
2.介面特性
- 介面中的方法會被隱式的指定為public abstract
- 介面中的變數也會被隱式的指定為public static final 變數
- 介面中的方法是不能在介面中實現的,只能由實現介面的類來實現介面中的方法
3.抽象類與介面
- 一個類只能繼承一個抽象類,但是一個類能實現多個介面
- 抽象類中的成員變數可以是各種型別的,而介面中的成員變只能是public static final型別的
- 抽象類中的方法可以有方法體,就能實現方法的具體功能,但是介面中的方法不行
4.當類實現介面的時候,來要實現介面中所有的方法,否則,類必須宣告為抽象的類
5.一個介面能繼承另一個介面,介面的繼承使用extends關鍵字,自介面繼承父介面
10.注意事項
- 被繼承的類稱為超類,派生類稱為子類
- 包名所有字母小寫
- com.runoob
- 類名每個單詞首寫字母大寫,其他小寫
- toString()
- 變數和方法:第一個字母小寫,從第二個單詞開始首字母大寫
- meditPassWord
- 常量:所有字母大寫,每個單詞之間用 _ 連線
- GAME_COLOR="RED"
11.區域性變數、例項變數、類變數
類變數:獨立於方法之外的變數,用static修飾
成員變數:獨立於方法之外的變數,不過沒有static修飾
區域性變數:類的方法中的變數
複製程式碼
1.區域性變數
- 宣告在方法、構造方法或者語句塊中
- 在方法、構造方法、與巨快被執行的時候建立,當執行完成後,變數將會被銷燬
- 訪問修飾符不能用於區域性變數
- 區域性變數值在宣告他的方法、構造方法、語句塊中可見
- 區域性變數是在棧上進行分配的
- 區域性變數沒有預設值,所以區域性變數被宣告後,必須經過初始化,才可以使用【⚠️必須初始化】
【補充】
- 成員變數在堆內,區域性變數在棧內
- 訪問修飾符
- public
- private
- default
- protected
2.成員變數--例項變數--沒有被static修飾的變數
- 宣告在一個類中,但在方法、構造方法、語句塊之外
- 當一個物件被例項化後,每個例項變數的值就跟著確定了
- 例項變數在物件建立的時候建立,在物件被銷燬的時候銷燬
- 例項變數的值應該至少被一個方法、構造方法、語句塊引用,是的外部能夠通過這些方法獲取例項變數資訊
- 例項變數可以宣告在使用前或者使用後
- 訪問修飾符可以修飾例項變數
- 例項變數對於類中的方法、構造方法、語句塊是可見的。
- 一般情況下,應該把例項變數設為私有
- 通過訪問修飾符可以使例項變數對子類可見
- 例項變數具有預設值
- int - 0 ; bool - false ; 引用型別變數 - null
- 變數的值可以在宣告時指定,也可以在構造方法中指定
- 例項變數可以直接通過變數名訪問。
3.類變數-靜態變數-static
- 類中以static關鍵字宣告,但必須在方法、構造方法、語句塊之外
- 無論一個類建立了多少個物件,類只擁有類變數的一份拷貝
- 靜態變數在程式開始時建立,在程式結束時銷燬
- 預設直通例項變數相似。
【補充】--final與static
- final -- 常數
- final修飾的屬性跟具體物件有關,在執行期初始化的final屬性,不同物件可以有不同的值
- final修飾的方法表示該方法在子類中不能被重寫,final修飾的類表示該類不能被不能被繼承
- final初始化後不能被改變,初始化的過程可以在編譯期(類載入的時候)、執行期
- static -- 靜態
- static初始化後仍可以改變
- 用static修飾的程式碼表示靜態程式碼塊,當Java虛擬機器(JVM)載入類的時候就會呼叫這個方法
- static修飾的屬性所有物件都只有一個值
- static強調 它們 只有一個
- static修飾的屬性、方法、程式碼段跟該類的具體物件無關,不建立物件也能呼叫static的屬性、方法、程式碼段
- static與 this/super 勢不兩立,因為 this/super與具體物件有關
- static不可修飾區域性變數
12.break,continue,return
continue只是在一次迴圈中不繼續向下進行,繼續i++;而break是直接結束了本次剩下的全部i++,直接進入外部迴圈的j++中,而return是直接跳出了全全部不的迴圈
13.Java修飾符
private
public class logger{
privite String secret;
public String getSecret(){
return this.secret;
}
public void setSecret(String secret){
this.secret=secret;
}
}
複製程式碼
- 因為logger類中的secret為私有變數,所以其他的類不能直接得到和設定該變數的值
獲得 和 改變 私有變數的方法
定義的兩個public方法:
- getSecret()--返回secret的值
- setSecret(String secret)--設定secret的值
【補充】
- 基類就是父類,Object類是所有類的父類,父類繼承父類,繼承並重寫父類的方法和非私有變數成員
父類中宣告為private的方法,不能夠被繼承
14.拷貝
static關鍵字用來宣告獨立於物件的靜態變數,無論一個類例項化多少物件,它的靜態變數只有一份拷貝
區域性變數(類方法中的變數)是不能被宣告為static變數的
15.將底部按鈕均分位置
android:layout_weight="1"
複製程式碼
16.src與background
- background--分割線view設定顏色
- src--圖片的背景
17.設定點選底部按鈕文字變色
在drawable中,重新編寫 selector的XML檔案
18.FragmrntUtil
public class FragmentUtil {
/**
* 新增Fragment
*/
public static void addFragment(BaseActivity context, int viewId, Fragment fragment, @Nullable String tag) {
context.getSupportFragmentManager()
.beginTransaction()
.add(viewId, fragment, tag)
.commit();
}
/**
* 替換Fragment
*/
public static void replaceFragment(BaseActivity context, int viewId, Fragment fragment, @Nullable String tag) {
context.getSupportFragmentManager()
.beginTransaction()
.replace(viewId, fragment, tag)
.commit();
}
/**
* 隱藏Fragment
*/
public static void hideFragment(BaseActivity context, Fragment fragment) {
context.getSupportFragmentManager()
.beginTransaction()
.hide(fragment)
.commit();
}
/**
* 展示Fragment
*/
public static void showFragment(BaseActivity context, Fragment fragment) {
context.getSupportFragmentManager()
.beginTransaction()
.show(fragment)
.commit();
}
}
複製程式碼
- 新增Fragment
- 替換Fragment
- 隱藏Fragment
- 展示Fragment
每次點選底部按鈕的時候,需要先將全部的Fragment進行隱藏
/**
* 隱藏所有fragment
*/
private void hideAllFragment() {
if (mHomeFragment != null) {
FragmentUtil.hideFragment(this, mHomeFragment);
}
if (mMessageFragment != null) {
FragmentUtil.hideFragment(this, mMessageFragment);
}
if (mMineFragment != null) {
FragmentUtil.hideFragment(this, mMineFragment);
}
}
複製程式碼
19.給背景設定透明度--#XXXXXXe5
android:background="#1F9DD5e5"
複製程式碼
20.底部按鈕被覆蓋事件
原因分析:Relativelayout佈局中,需要新增一條重要的屬性--above
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/frame_content"
android:layout_above="@id/view_divider"
>
</FrameLayout>
<View
android:id="@+id/view_divider"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_above="@id/ly_bottom_menu"
android:background="@color/colorPrimary"
/>
複製程式碼
由於不是Linealayout,沒有vertical的orientation,所以需要自己手動排佈局,利用above等屬性
21.報錯--空指標異常!判空!判空!判空!
一定需要有if-else 的判空操作
@OnClick(R.id.ly_menu_home)
public void onLyMenuHomeClicked() {
changeHomeMenuStatus();
hideAllFragment();
if(mHomeFragment==null){
mHomeFragment=new HomeFragment();
FragmentUtil.addFragment(this,R.id.frame_content,mHomeFragment,null);
}
else{
FragmentUtil.showFragment(this,mHomeFragment);
}
}
複製程式碼
22.FrameLayout與Fragment
23.align相對佈局問題
- android:layout_alignLeft="@id/xxx"
- 將控制元件的左邊緣和給定ID控制元件的左邊緣對齊
- android:layout_alignTop="@id/xxx"
- 將控制元件的上邊緣和給定ID控制元件的上邊緣對齊
- android:layout_below="@id/xxx"
- 將控制元件置於給定ID控制元件之下
- android:layout_toRightOf="@id/xxx"
- android:layout_toRightOf="@id/xxx"
24.ViewFlipper
25.Fragment中獲取上下文Context一般用getActivity
應該將HomeFragment.this替換為getActivity()
getContext和getActivityhe和MainActivity.this和this
- this--表示當前物件,一般而言,在哪個類中呼叫,就是指向該物件
- MainActivity.this--表示MainActivity物件,一般用在內部類中指示外面的this,如果在內部類中直接用this,指示的是內部類本身。
- getContext()--這是View類中提供的方法,在繼承了View的類中才可以呼叫,反悔的時候當前View執行在那個Activity的Context中
- getActivity()--獲得Fragment所依附的Activity物件
- 但需要注意:這個方法當Fragment生命週期結束並銷燬時getActivity()返回的是null,所以在使用時要注意判斷null或者捕獲空指標異常。
Activity繼承Context
26.Bind自動生成Flipper的時候,需要提前將專案了中的檔名更改
報錯報錯還是報錯:
原因是:xml檔案中還沒有更改過,所以自動生成的還是ViewFlipper
由於我們自己寫了自定義的FlipperPage,需要在xml的檔案中使用它
於是我們更改為這樣:
回到HomeFragment檔案中對layout進行generate,就自動Bind了
27.聯合主鍵
先排前面再排後面
28.20180326旁聽安卓課--詳情見筆記
29.不同類-重寫,同一類-過載
子類繼承父類就叫做新的一類,就叫做不同類
30.糾正:setXXX 是過載的體現
多型的三大特性:過載、重寫、介面
物件導向的三大特性:繼承、多型、封裝
31.兩個startActivity並不是報錯,更不是空指標異常,這是錯誤的❌
兩個startActivity最多就是,點選一次性進入新的Activity,回退的時候需要點選兩次後退按鈕而已
32.私有變數的獲取
除了get方法,還可以快取到本地,用的時候取出來就行了
33.介面與abstract類
- 抽象類中的方法都是abstract的,但abstract類中的方法可以多種多樣
- 實現介面要實現類中的所有方法,但是abstract中的方法不需要全部實現
34.@Override--ctrl+O 萬能啊
35.Error:關於ActionBar的問題--already has an action bar
借鑑:http://www.cnblogs.com/hh9601/p/6404728.html
java.lang.IllegalStateException:
This Activity already has an action bar supplied by the window decor. Do not request Window.
FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme t
複製程式碼
問題原因:當在activity中呼叫了setSupportActionBar(toolbar);
回到我的專案了檔案中發現,這裡確實出現了兩個Bar同時存在的情形
回到AndroidManifest.xml 對應的Activity標籤的android:theme中
進一步,到style中深究
於是我們換成NoActionBar
回看xml檔案--成功
ok 我很喜歡
36.Toolbar取代ActionBar
借鑑網址:https://blog.csdn.net/zwlove5280/article/details/52771998
關鍵幾個步驟:
1.在 Activity 中,用 Toolbar 取代 ActionBar(demo中將這一步封裝在了BaseToolbarActivity中)
2.具體使用方法
37.Fork-Github
有一個叫做Joe的程式猿寫了一個遊戲程式,而你可能要去改進它。並且Joe將他的程式碼放在了GitHub倉庫上。下面是你要做的事情:
https://linux.cn/article-4292-1-rss.html
38.SwipeRefreshLayout
https://github.com/PingerOne/SwipeRefreshDemo
【注意】
- 在這個佈局裡面只能包含一個子控制元件,而且是可以滑動的(因為要達到重新整理的目的),如:RecycleView、ListView
- 主要方法?
39.太機智了--BaseModel一個,利用過載,實現多個範型T都可以呼叫
40.Android Device Monitor--檢視佈局
41. .show很重要,不然Toast無限顯現
在fragment中使用Toast.makeText()
Toast.makeText(getActivity(),"此功能暫時無法使用",Toast.LENGTH_SHORT).show();
複製程式碼
42.abstract
無法實現一個抽象類,但是可以例項化一個抽象類的子類
43.如果一個抽象類沒有欄位,所有方法全部都是抽象方法,就可以把抽象類改寫為介面
抽象類什麼都可以做,為什麼還要介面呢
一個類可以實現多個介面,但是隻能繼承一個類
44.內部類--在一個類中的類
1.成員內部類
class heaijia{....}
? heaijia 這就是名字 !!有名字的類
2.靜態內部類
3.區域性內部類
4.匿名內部類--special--crazy
今天,我遇到了 OnClickListener()居然是以匿名內部類的形式實現的,我驚了
45.Error:ArrayAdapter requires the resource ID to be a TextView
參考:https://blog.csdn.net/zsr0526/article/details/53224064
解決辦法: 將R.layout.XXX這個佈局檔案XXX的根節點改成TextView
根結點
46.Error :Fragment獲取上下文報錯
Fragment不是上下文類,所以不能直接採用this,而是利用getActivity().getApplicationContext()
借鑑:https://stackoverflow.com/questions/35816602/argument-this-doesn%C2%B4t-work-required-android-content-context
47. Error:Adapter adapter
經我測試發現,將RecyclerView換成ListView就沒有報錯了,具體的原因還不知道是為什麼
48.Error:點選button就閃退,ListView無法顯示,並且在logcat中沒有明顯的藍色報錯資訊
layout檔案中的包含關係出了問題,導致recyclerView無法顯示
49.ListView
借鑑:https://www.cnblogs.com/chenyuwei/p/4581700.html