2020大厂面试集合,GitHub,百度,flutter下拉加载
由于Fragment的生命周期與Activity的生命周期有著牽扯,所以把兩者的圖放到一起作為對(duì)比理解。
[圖片上傳失敗…(image-a13b49-1601037655916)]
接下來(lái)就不同情況下的Fragment生命周期做一簡(jiǎn)單介紹:
Fragment在Activity中replace
新替換的Activity:onAttach() —> onCreate() —> onCreatView() —> onViewCreated —> onActivityCreated() —> onStart —>onResume()
被替換的Activity:onPause() —> onStop() —> onDestoryView() —> onDestory() —> onDetach()
Fragment在Activity中replace,并addToBackStack
新替換的Fragment(沒(méi)有在BackStack中):onAttach?> onCreate >?onCreateView >?onViewCreated >?onActivityCreated >?onStart >?onResume
新替換的Fragment(已經(jīng)在BackStack中):onCreateView > onViewCreated > onActivityCreated > onStart > onResume
被替換的Fragment:onPause > onStop > onDestroyView
Fragment在ViewPager中切換
我們稱(chēng)切換前的的Fragment稱(chēng)為PreviousFragment,簡(jiǎn)稱(chēng)PF;切換后的Fragment稱(chēng)為NextFragment,簡(jiǎn)稱(chēng)NF;其他Fragment稱(chēng)為OtherFragment,簡(jiǎn)稱(chēng)OF。
(在ViewPager中setUserVisibleHint能反映出Fragment是否被切換到后臺(tái)或前臺(tái),所以在這里也當(dāng)作生命周期)
- 如果相關(guān)的Fragment沒(méi)有被加載過(guò):
NF: setUserVisibleHint(false)【用戶(hù)不可見(jiàn)】 > onAttach > onCreate > setUserVisibleHint(true)【用戶(hù)可見(jiàn)】 > onCreateView > onViewCreated > onActivityCreated > onStart > onResume
OF跟NF相鄰: setUserVisibleHint(false) > onAttach > onCreate > onCreateView > onViewCreated > onActivityCreated > onStart > onResume
- 如果相關(guān)的Fragment已經(jīng)被加載過(guò):
NF跟PF相鄰? :setUserVisibleHint(true)
NF跟PF不相鄰:setUserVisibleHint(true)?> onCreateView > onViewCreated > onActivityCreated > onStart > onResume
PF跟NF相鄰? :setUserVisibleHint(false)
PF跟NF不相鄰:setUserVisibleHint(false) > onPause > onStop > onDestroyView
OF跟PF相鄰:onPause > onStop > onDestroyView
OF跟NF相鄰:onCreateView > onViewCreated > onActivityCreated > onStart > onResume
OF夾在PF和NF中間:不調(diào)用任何生命周期方法
NF跟PF相鄰? :setUserVisibleHint(true)
NF跟PF不相鄰:setUserVisibleHint(true)?> onCreateView > onViewCreated > onActivityCreated > onStart > onResume
PF跟NF相鄰? :setUserVisibleHint(false)
PF跟NF不相鄰:setUserVisibleHint(false) > onPause > onStop > onDestroyView
OF跟PF相鄰:onPause > onStop > onDestroyView
OF跟NF相鄰:onCreateView > onViewCreated > onActivityCreated > onStart > onResume
OF夾在PF和NF中間:不調(diào)用任何生命周期方法
- 如果重寫(xiě)了FragmentPagerAdapter的DestroyItem方法,并且相關(guān)的Fragment已經(jīng)加載過(guò):
相互切換時(shí)只會(huì)調(diào)用setUserVisibleHint
Fragment進(jìn)入了運(yùn)行狀態(tài):
Fragment在進(jìn)入運(yùn)行狀態(tài)時(shí),以下四個(gè)生命周期會(huì)隨它所屬的Activity一起被調(diào)用:
onPause() —> onStop() —> onStart() —> onResume()
關(guān)于Fragment的onActivityResult方法:
使用Fragment的startActivity方法時(shí),FragmentActivity的onActivityResult方法會(huì)回調(diào)相應(yīng)的Fragment的onActivityResult方法,所以在重寫(xiě)FragmentActivity的onActivityResult方法時(shí),注意調(diào)用super.onActivityResult。
8、?如何實(shí)現(xiàn)Fragment的滑動(dòng)?
將Fragment與viewpager綁定,通過(guò)viewpager中的touch事件,會(huì)進(jìn)行move事件的滑動(dòng)處理。
Fragment布局
Fragment代碼:
public class FragmentOne extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_one, container, false); }}
public class FragmentTwo extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_Two, container, false); }}
viewpager布局:
xmlns:tools=“http://schemas.android.com/tools” android:layout_width=“match_parent” android:layout_height=“match_parent” tools:context=“com.example.spreadtrumshitaoli.fragmentscroll.MainActivity”> <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_height=“match_parent” android:layout_width=“match_parent”/> </android.support.constraint.ConstraintLayout>
MainActivity代碼:
public class MainActivity extends AppCompatActivity { private FragmentOne fragmentOne; private FragmentTwo fragmentTwo; private ViewPager viewPager; private ArrayList mFragmentList = new ArrayList (); private FragmentPagerAdapter fragmentPagerAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } private void init() { viewPager = (ViewPager) findViewById(R.id.view_pager); fragmentOne = new FragmentOne(); fragmentTwo = new FragmentTwo(); mFragmentList.add(fragmentOne); mFragmentList.add(fragmentTwo); //將adapter和fragment綁定在一起。 fragmentPagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int i) { return mFragmentList != null ? mFragmentList.get(i) : null; } @Override public int getCount() { return mFragmentList != null ? mFragmentList.size() : 0; } }; viewPager.setAdapter(fragmentPagerAdapter); viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int i, float v, int i1) { } @Override public void onPageSelected(int i) { //TODO: } @Override public void onPageScrollStateChanged(int i) { } }); } }
在這段代碼中,我們
首先f(wàn)ragment以及viewpager都實(shí)例化;
再將fragment添加到泛型arraylist里;
最后將帶有fragment的arraylist和adapter綁定。
9、fragment之間傳遞數(shù)據(jù)的方式?
方法一:
-
1、在MainFragment中設(shè)置一個(gè)setData()方法,在方法中設(shè)置更改按鈕名稱(chēng);
-
//MainFragment.java文件中
-
public void setData(String string) {
-
bt_main.setText(string);
-
}
-
2、在MenuFragment中的ListView條目點(diǎn)擊事件中通過(guò)標(biāo)簽獲取到MainFragment,并調(diào)用對(duì)應(yīng)的setData()方法,將數(shù)據(jù)設(shè)置進(jìn)去,從而達(dá)到數(shù)據(jù)傳遞的目的。
-
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-
@Override
-
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-
MainFragment mainFragment =
-
(MainFragment) getActivity()
-
.getSupportFragmentManager()
-
.findFragmentByTag("mainFragment");
-
mainFragment.setData(mDatas.get(position));
-
}
-
});
只需上面區(qū)區(qū)兩步即可達(dá)到數(shù)據(jù)傳遞的目的。
方法二:
采取接口回調(diào)的方式進(jìn)行數(shù)據(jù)傳遞。
-
step1: 在Menuragment中創(chuàng)建一個(gè)接口以及接口對(duì)應(yīng)的set方法:
-
//MenuFragment.java文件中
-
public interface OnDataTransmissionListener {
-
public void dataTransmission(String data);
-
}
-
public void setOnDataTransmissionListener(OnDataTransmissionListener mListener) {
-
this.mListener = mListener;
-
}
-
step2: 在MenuFragment中的ListView條目點(diǎn)擊事件中進(jìn)行接口進(jìn)行接口回調(diào)
-
//MenuFragment.java文件中
-
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-
@Override
-
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-
/**
-
* 方法二:采取接口回調(diào)的方式進(jìn)行數(shù)據(jù)傳遞
-
*/
-
if (mListener != null) {
-
mListener.dataTransmission(mDatas.get(position));
-
}
-
}
-
});
-
step3: 在MainActivity中根據(jù)menuFragment獲取到接口的set方法,在這個(gè)方法中進(jìn)行進(jìn)行數(shù)據(jù)傳遞,具體如下:
-
//在MainActivity.java中
-
menuFragment.setOnDataTransmissionListener(new MenuFragment.OnDataTransmissionListener() {
-
@Override
-
public void dataTransmission(String data) {
-
mainFragment.setData(data); //注:對(duì)應(yīng)的mainFragment此時(shí)應(yīng)該要用final進(jìn)行修飾
-
}
-
});
通過(guò)上面的三步也可以輕松做到Fragment數(shù)據(jù)之間的傳遞。
方法三:
使用三方開(kāi)源框架:EventBus
那么問(wèn)題來(lái)了:EventBus是個(gè)啥東西???
簡(jiǎn)單來(lái)說(shuō),EventBus是一款針對(duì)Android優(yōu)化的發(fā)布/訂閱(publish/subscribe)事件總線(xiàn)。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,線(xiàn)程之間傳遞消息。簡(jiǎn)化了應(yīng)用程序內(nèi)各組件間、組件與后臺(tái)線(xiàn)程間的通信。優(yōu)點(diǎn)是開(kāi)銷(xiāo)小,代碼更優(yōu)雅,以及將發(fā)送者和接收者解耦。比如請(qǐng)求網(wǎng)絡(luò),等網(wǎng)絡(luò)返回時(shí)通過(guò)Handler或Broadcast通知UI,兩個(gè)Fragment之間需要通過(guò)Listener通信,這些需求都可以通過(guò)EventBus實(shí)現(xiàn)。
下面我們就用EventBus來(lái)實(shí)現(xiàn)以下Fragment之間的數(shù)據(jù)傳遞:
- step1:引入EventBus
- step2:注冊(cè)事件接收者
這里MainFragment是要接收MenuFragment發(fā)送來(lái)的數(shù)據(jù),所以我們?cè)贛ainFragment中的onCreateView()方法中進(jìn)行注冊(cè):
-
step3:發(fā)送事件
注:發(fā)送事件之前其實(shí)還有一步定義事件類(lèi)型,這里我們傳遞的數(shù)據(jù)只有一個(gè)類(lèi)型,所以這一步取消了。
MenuFragment發(fā)送數(shù)據(jù)給MainFragment,所以我們?cè)贛enuFragment中將要傳遞的數(shù)據(jù)進(jìn)行發(fā)送事件操作: -
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-
@Override
-
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-
EventBus.getDefault().post(mDatas.get(position));
-
}
-
});
-
step4:接收消息并處理
在MainFragment中我們接收來(lái)自MenuFragment傳遞過(guò)來(lái)的數(shù)據(jù),并進(jìn)行對(duì)應(yīng)的處理(注:EventBus 3.0版本這一步必須要寫(xiě)注解@Subscribe (與2.4版本有所區(qū)別)): -
@Subscribe
-
public void onEvent(String data) {
-
bt_main.setText(data);
-
}
通過(guò)上面這一步即可完成數(shù)據(jù)之間的傳遞,需要注意的是在銷(xiāo)毀的時(shí)候我們要注銷(xiāo)事件接收。
-
step5:注銷(xiāo)事件接收
-
//MainFragment.java中
-
@Override
-
public void onDestroy() {
-
super.onDestroy();
-
EventBus.getDefault().unregister(this);
-
}
以上五步完成了Fragment之間的數(shù)據(jù)傳遞,看似比上面兩個(gè)方法要復(fù)雜的多,但當(dāng)我們涉及到復(fù)雜的Fragment之間數(shù)據(jù)傳遞(例如Fragment中嵌套多層Fragment)時(shí),就會(huì)體會(huì)到EventBus的爽快之處~~~這里不進(jìn)行贅述了。
10、Activity 怎么和Service 綁定?
這需要實(shí)現(xiàn)service中的onBind()函數(shù)以返回service實(shí)例給activity
1、創(chuàng)建service類(lèi)和activity類(lèi)。
2、在service類(lèi)中定義一個(gè)內(nèi)部類(lèi)繼承自Binder()類(lèi):
public?class?MyBinder?extends?Binder{
public?Service1?getService(){
return?Service1.this;
}
} ?
實(shí)例化onBind()方法:
private final IBinder binder = new MyyBinder();
@Override
public IBinder onBind(Intent intent){
Log.i(LOG,“onBind…”);
return binder;
}
3、在activity中完成綁定
Intent intent = new Intent(Activity1.this,Activity2.class);
bindService(intent,conn,Context.BIND_AUTO_CREATE);
- bindService的第二個(gè)參數(shù)是一個(gè)ServiceConnection類(lèi)型的參數(shù)。service和其他組件之間的連接都表示為一個(gè)ServiceConnection,要想將service和其他組件進(jìn)行綁定,就需要實(shí)現(xiàn)一個(gè)新的ServiceConnection。
public?ServiceConnection?conn=?new?ServiceConnection()?{
@Override
public?void?onServiceDisconnected(ComponentName?name)?{
//當(dāng)連接意外斷開(kāi)時(shí)調(diào)用
Log.i(LOG,?“onServiceDisconnected>>>>>>>>”);
myservice?=?null;
}
@Override
public?void?onServiceConnected(ComponentName?name,?IBinder?service)?{
//當(dāng)建立連接時(shí)調(diào)用
Log.i(LOG,?“onServiceConnected>>>>>>>>”);
myservice?=?((Service1.MyBinder)service).getService();
}
};
- bindService的第三個(gè)參數(shù)是一個(gè)flag。
可以使用的flag有:
BIND_AUTO_CREATE:綁定完成后就啟動(dòng)目標(biāo)service
BIND_DEBUG_UNBIND:這只在debug時(shí)使用,跟unbind有關(guān)。
BIND_NOT_FOREGROUND:確保被綁定的service永遠(yuǎn)不會(huì)有運(yùn)行于前臺(tái)的優(yōu)先級(jí),因?yàn)槟J(rèn)情況下,綁定一個(gè)service會(huì)提高它的優(yōu)先級(jí)
BIND_ABOVE_CLIENT:確保客戶(hù)端處于前臺(tái)時(shí),綁定的service也變
《Android學(xué)習(xí)筆記總結(jié)+最新移動(dòng)架構(gòu)視頻+大廠(chǎng)安卓面試真題+項(xiàng)目實(shí)戰(zhàn)源碼講義》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整內(nèi)容開(kāi)源分享
為前臺(tái)進(jìn)程
BIND_ALLOW_OOM_MANAGEMENT:允許系統(tǒng)在低內(nèi)存等狀態(tài)下刪除該service(這是自己對(duì)源碼中注釋的理解)
BIND_WAIVE_PRIORITY:綁定service時(shí)不改變其優(yōu)先級(jí)
BIND_ADJUST_WITH_ACTIVITY:系統(tǒng)根據(jù)service所綁定的activity的重要程度來(lái)調(diào)整這個(gè)service的優(yōu)先級(jí)。
11、service生命周期?
1.??? 被啟動(dòng)的服務(wù)(startService())的生命周期。
???????????? 如果一個(gè)Service被某個(gè)Activity 調(diào)用Context.startService() 方法啟動(dòng),那么不管是否有Activity使用bindService()綁定或unbindService()解除綁定到該Service,該Service都在后臺(tái)運(yùn)行。如果一個(gè)Service被多次執(zhí)行startService(),它的onCreate()方法只會(huì)調(diào)用一次,也就是說(shuō)該Service只會(huì)創(chuàng)建一個(gè)實(shí)例,而它的onStartCommand()將會(huì)被調(diào)用多次(對(duì)應(yīng)調(diào)用startService()的次數(shù))。該Service將會(huì)一直在后臺(tái)運(yùn)行,直到被調(diào)用stopService(),或自身的stopSelf方法。當(dāng)然如果系統(tǒng)資源不足,系統(tǒng)也可能結(jié)束服務(wù)。
2.??? 被綁定的服務(wù)(bindService())的生命周期。
???????????? 如果一個(gè)Service被調(diào)用?Context.bindService ()方法綁定啟動(dòng),不管調(diào)用bindService()調(diào)用幾次,onCreate()方法都只會(huì)調(diào)用一次,而onStartCommand()方法始終不會(huì)被調(diào)用,這時(shí)會(huì)調(diào)用onBind()方法。當(dāng)連接建立之后,Service將會(huì)一直運(yùn)行,除非調(diào)用Context.unbindService() 斷開(kāi)連接或者之前調(diào)用bindService() 的 Context 不存在了(如該Activity被finish),系統(tǒng)將會(huì)自動(dòng)停止Service,對(duì)應(yīng)onDestroy()將被調(diào)用。
3.??? 被啟動(dòng)又被綁定的服務(wù)的生命周期。
?????????????如果一個(gè)Service又被啟動(dòng)又被綁定,則該Service將會(huì)一直在后臺(tái)運(yùn)行。調(diào)用unbindService()將不會(huì)停止Service,而必須調(diào)用stopService()或Service的stopSelf()方法來(lái)停止服務(wù)。
4.?? 當(dāng)服務(wù)被停止時(shí)清除服務(wù)。
??????????? 當(dāng)一個(gè)Service被終止時(shí),Service的onDestroy()方法將會(huì)被調(diào)用,在這里應(yīng)當(dāng)做一些清除工作,如停止在Service中創(chuàng)建并運(yùn)行的線(xiàn)程等。
12、 activity和service的綁定方式以及怎么在Activity 中啟動(dòng)自己對(duì)應(yīng)的Service?
1、activity能進(jìn)行綁定得益于Serviece的接口。為了支持Service的綁定,實(shí)現(xiàn)onBind方法。
2、Service和Activity的連接可以用ServiceConnection來(lái)實(shí)現(xiàn)。需要實(shí)現(xiàn)一個(gè)新的ServiceConnection,重現(xiàn)onServiceConnected和OnServiceDisconnected方法,一旦連接建立,就能得到Service實(shí)例的引用。
3、執(zhí)行綁定,調(diào)用bindService方法,傳入一個(gè)選擇了要綁定的Service的Intent(顯示或隱式)和一個(gè)你實(shí)現(xiàn)了的ServiceConnection的實(shí)例
13、Service的啟動(dòng)方式?
采用**Context.startService()**方法啟動(dòng)服務(wù),在服務(wù)未被創(chuàng)建時(shí),系統(tǒng)會(huì)先調(diào)用服務(wù)的onCreate()方法,接著調(diào)用onStart()方法。如果調(diào)用startService()方法前服務(wù)已經(jīng)被創(chuàng)建,多次調(diào)用startService()方法并不會(huì)導(dǎo)致多次創(chuàng)建服務(wù),但會(huì)導(dǎo)致多次調(diào)用onStart()方法。采用startService()方法啟動(dòng)的服務(wù),只能調(diào)用Context.stopService()方法結(jié)束服務(wù),服務(wù)結(jié)束時(shí)會(huì)調(diào)用onDestroy()方法。
采用**Context.bindService()**方法啟動(dòng)服務(wù),在服務(wù)未被創(chuàng)建時(shí),系統(tǒng)會(huì)先調(diào)用服務(wù)的 onCreate()方法,接著調(diào)用onBind()方法。這個(gè)時(shí)候調(diào)用者和服務(wù)綁定在一起,調(diào)用者退出了,系統(tǒng)就會(huì)先調(diào)用服務(wù)的onUnbind()方 法,接著調(diào)用onDestroy()方法。如果調(diào)用bindService()方法前服務(wù)已經(jīng)被綁定,多次調(diào)用bindService()方法并不會(huì)導(dǎo)致 多次創(chuàng)建服務(wù)及綁定(也就是說(shuō)onCreate()和onBind()方法并不會(huì)被多次調(diào)用)。如果調(diào)用者希望與正在綁定的服務(wù)解除綁定,可以調(diào)用 unbindService()方法,調(diào)用該方法也會(huì)導(dǎo)致系統(tǒng)調(diào)用服務(wù)的onUnbind()–>onDestroy()方法。
14、談?wù)凜ontentProvider、ContentResolver、ContentObserver之間的關(guān)系?
ContentProvider:
-
四大組件的內(nèi)容提供者,主要用于對(duì)外提供數(shù)據(jù)
-
實(shí)現(xiàn)各個(gè)應(yīng)用程序之間的(跨應(yīng)用)數(shù)據(jù)共享,比如聯(lián)系人應(yīng)用中就使用了ContentProvider,你在自己的應(yīng)用中可以讀取和修改聯(lián)系人的數(shù)據(jù),不過(guò)需要獲得相應(yīng)的權(quán)限。其實(shí)它也只是一個(gè)中間人,真正的數(shù)據(jù)源是文件或者SQLite等
-
一個(gè)應(yīng)用實(shí)現(xiàn)ContentProvider來(lái)提供內(nèi)容給別的應(yīng)用來(lái)操作,通過(guò)ContentResolver來(lái)操作別的應(yīng)用數(shù)據(jù),當(dāng)然在自己的應(yīng)用中也可以
ContentResolver:
-
內(nèi)容解析者,用于獲取內(nèi)容提供者提供的數(shù)據(jù)
-
ContentResolver.notifyChange(uri)發(fā)出消息
ContentObserver:
-
內(nèi)容監(jiān)聽(tīng)器,可以監(jiān)聽(tīng)數(shù)據(jù)的改變狀態(tài)
-
目的是觀察(捕捉)特定Uri引起的數(shù)據(jù)庫(kù)的變化,繼而做一些相應(yīng)的處理,它類(lèi)似于數(shù)據(jù)庫(kù)技術(shù)中的觸發(fā)器(Trigger),當(dāng)ContentObserver所觀察的Uri發(fā)生變化時(shí),便會(huì)觸發(fā)它。觸發(fā)器分為表觸發(fā)器、行觸發(fā)器,相應(yīng)地ContentObsever也分為表ContentObserver、行ContentObserver,當(dāng)然這是與它所監(jiān)聽(tīng)的Uri MIME Type有關(guān)的
-
ContentResolver.registerContentObserver()監(jiān)聽(tīng)消息
15、廣播的分類(lèi)?
分為有序廣播和無(wú)序廣播兩類(lèi)。
- 無(wú)序廣播發(fā)送代碼:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void click(View v){ //啟動(dòng)界面 startActivity //發(fā)送廣播 sendBroadcast Intent intent = new Intent(); intent.setAction(“com.itheima.cctv.action.NEWS”); intent.putExtra(“data”, “我是一個(gè)無(wú)須的廣播”); sendBroadcast(intent); }}
- 無(wú)序廣播的監(jiān)聽(tīng)代碼:
public class CctvReceiver extends BroadcastReceiver { private static final String TAG = “CctvReceiver”; @Override public void onReceive(Context context, Intent intent) { String data = intent.getStringExtra(“data”); Log.d(TAG, “data===”+data); } }
- 有序廣播發(fā)送:
有序接收:
public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.d(“vivi”, “我是恩恩主席的內(nèi)線(xiàn),我收到的指令是:”+getResultData()); } }
啟動(dòng)模式:
1、standard:標(biāo)準(zhǔn)化啟動(dòng)模式
每啟動(dòng)一個(gè)Activity,都會(huì)重新創(chuàng)建Activity的新的實(shí)例,將其放在棧的頂部。不需要考慮這個(gè)實(shí)例是否已經(jīng)存在。
每一次啟動(dòng),它的onCreate()、onStart()、onResume()方法都會(huì)被依次調(diào)用。
2、singleTop:棧頂復(fù)用模式
當(dāng)前棧中已經(jīng)有該Activity實(shí)例,并且該實(shí)例位于棧頂時(shí),會(huì)去調(diào)用onNewIntent()方法。
當(dāng)前棧中已有該Activity的實(shí)例但是該實(shí)例不在棧頂時(shí),依然會(huì)去創(chuàng)建Activity。
當(dāng)前棧中不存在該Activity實(shí)例時(shí),會(huì)去新創(chuàng)建一個(gè)該Activity。
應(yīng)用場(chǎng)景:IM對(duì)話(huà)框、新聞客戶(hù)端推送。
3、singleTask:棧內(nèi)復(fù)用模式
它主要檢測(cè)【尋找,通過(guò)taskAffinity】整個(gè)棧中是否已經(jīng)存在當(dāng)前想要啟動(dòng)的Activity,存在的話(huà)直接將該Activity置于棧頂,之前位于該Activity上面的Activity將被銷(xiāo)毀,同時(shí)調(diào)用onNewIntent()方法,而不存在的話(huà)進(jìn)行創(chuàng)建。
應(yīng)用場(chǎng)景:應(yīng)用主界面。
4、singleInstance:
一個(gè)人獨(dú)享一個(gè)任務(wù)棧。當(dāng)該Activity啟動(dòng)時(shí),系統(tǒng)會(huì)創(chuàng)建一個(gè)新的任務(wù)棧,同時(shí)將Activity放到這個(gè)新的任務(wù)棧當(dāng)中,有別的應(yīng)用來(lái)啟動(dòng)該Activity時(shí),由于棧內(nèi)復(fù)用的特性,不會(huì)再去創(chuàng)建相應(yīng)Activity任務(wù)棧,而是這兩個(gè)應(yīng)用獨(dú)享一個(gè)Activity實(shí)例。
例如:應(yīng)用A中現(xiàn)有兩個(gè)Activity E、Activity F,為standard啟動(dòng)模式,應(yīng)用B中有一個(gè)Activity G,但其啟動(dòng)模式是singleInstance。應(yīng)用A想用應(yīng)用B任務(wù)棧當(dāng)中的Activity G,盡管在不同的應(yīng)用下,但是應(yīng)用A仍然會(huì)直接復(fù)用Activity G。
特性:
1、以SingleInstance模式啟動(dòng)的Activity具有全局唯一性【全局唯一性即指在整個(gè)系統(tǒng)當(dāng)中只會(huì)存在一個(gè)這樣的實(shí)例】;
2、如果在啟動(dòng)這樣一個(gè)Activity時(shí),【整個(gè)系統(tǒng)都是單例的】,已經(jīng)存在了一個(gè)實(shí)例;
3、以SingleInstance模式啟動(dòng)的Activity具有獨(dú)占性。
應(yīng)用場(chǎng)景:呼叫來(lái)電。
問(wèn)題:onNewIntent()調(diào)用時(shí)機(jī)?
- singleTop:如果新Activity已經(jīng)位于任務(wù)棧的棧頂,就不會(huì)重新創(chuàng)建,并回調(diào)?onNewIntent(intent)?方法。
- singleTask:只要該Activity在一個(gè)任務(wù)棧中存在,都不會(huì)重新創(chuàng)建,并回調(diào)?onNewIntent(intent)?方法。
網(wǎng)絡(luò)協(xié)議:
協(xié)議:【協(xié)議指計(jì)算機(jī)通信網(wǎng)絡(luò)中兩臺(tái)計(jì)算機(jī)之間進(jìn)行通信所必須共同遵守的規(guī)定或規(guī)則】
HTTP協(xié)議
基本概念:【超文本傳輸協(xié)議】允許將HTML(超文本標(biāo)記語(yǔ)言)文檔從Web服務(wù)器傳送到客戶(hù)端的瀏覽器。HTTP協(xié)議是 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 基于TCP/IP通信協(xié)議來(lái)傳輸數(shù)據(jù)的,可以從服務(wù)器端獲取圖片等數(shù)據(jù)資源。
URI:【uniform resource identifier】統(tǒng)一的資源標(biāo)識(shí)符,用來(lái)唯一的標(biāo)識(shí)一個(gè)資源。強(qiáng)調(diào)資源!!!
組成部分:
1)訪(fǎng)問(wèn)資源的命名機(jī)制;file
2)存放資源的主機(jī)名;
總結(jié)
以上是生活随笔為你收集整理的2020大厂面试集合,GitHub,百度,flutter下拉加载的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ubuntu中vim编辑模式退格键无法删
- 下一篇: 干货!基于元消歧的偏多标记学习