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