Android面試基礎題總結一

Android四大組件:

activity:

  1. activity的生命周期:activity是context的子類,同時實現了window.callback 和 keyevent.callback.可以處理與窗體用戶交互的事件。activity從創建到銷毀有多種狀態,在這些狀態轉換的時候伴隨有回調方法:onCreate(創建 ),onStart(可見),onResume(可交互),onPause(不可交互),onStop(不可見),onDestory(銷毀),onRestart(重新可見).

    • activity在一創建的時候會執行onCreate(),onStart(),onResume(),在A界面上啟動B界面的之后,A界面會執行onPause(),onStop()方法,如果B界面是一個diaLog,A界面處于可見但不可交互的狀態,會執行onStop()方法,由B界面返回A界面會執行onReStart(),onstart(),onResume()方法,退出A界面會執行onPause(),onStop(),onDestory()方法。
  2. activity的幾種啟動模式:包括:標準模式(standard),singleTop,singleTask,singleInstance。

    • 標準啟動模式是說:默認的啟動模式,可以不用配置,會隨著每個activity的開啟,每次都會創建一個實例對象,可以有多個實例對象,也可以多個相同的activity疊加。在點擊back退出時會依照棧順序依次退出。
    • singleTop是說:可以有多個實例對象,但不可以多個相同activity疊加,如果activity在棧頂,啟動相同的activity,不會創建新的實例,而會調用它的onNewIntent方法。
    • singleTask是說:只有一個實例對象,在同一個應用程序中啟動它時,若該activity不存在,就會在當前的任務棧中創建一個新的實例,若存在,則會把任務棧中所有在其之上的activity全部destory之后再調用其onNewIntent方法。而如果說在其他的應用程序中啟動它,則會新建一個task,并在該task中啟動這個activity,singleTask允許別的activity與其在統一個task中共存,也就是說,如果我在這個singleTask的實例中在啟動新的activity,這個新的activity還是會存在這一個singleTask的實例的任務棧中。
    • singleInstance是說:只有一個實例,并且這個實例只運行在一個task中,在這個task中只有這一個實例,不允許在有其他activity存在。
  3. 如何保存和恢復Activity的狀態數據:

    • activity的狀態通常情況下系統會自動保存,一般來說,在調用onPause()和onStop()方法之后,activity的實例仍然保存在內存中,activity的所有信息和狀態數據都不會丟失,當activity重新回到前臺之后,所有的改變都會保留,
    • 但是當系統內存不足時,調用onPause()和onStop()方法之后的activity可能會被系統銷毀,此時內存中就沒有了這個activity的實例對象了,如果這個activity重新回到前臺,所有的改變都會消失,為了避免該情況的發生,可以覆寫onsaveInstanceState()方法。onsaveInstanceState()方法接收一個bundle類型的參數,可以將狀態數據存儲在bundle中,這樣即使activity銷毀,用戶在次啟動activity,在調用它的onCreate(),上述的bundle對象會作為實參來傳遞給onCreate()方法,然后可以從bundle中獲取到保存的數據,將activity恢復到銷毀前的樣子。需要注意的是調用onsaveInstanceState()方法,要在方法onPause()和onStop()調用之前。
  4. 兩個activity之間跳轉必然會執行那些方法;

    • 兩個activity,從A跳轉至B,當B是一個對話框時或者透明窗體時,A會調用onPause()方法,B會調用onCreate(),onStart(),onResume(),當B覆蓋A時,A會調用onStop()方法。
  5. Android中activity,context,application之間有什么區別;

    • 相同點:context是描述一個應用程序環境的信息,即上下文的意思,該類是一個抽象類(abstract class),Android有提供該抽象類的具體實現類(contextlml),activity和application都是context的子類。
    • 不同點: 維護的生命周期不同。context維護的是當前activity的生命周期,而application維護的是整個項目的生命周期。
    • 在使用context的時候,需要防止內存泄漏,需要注意幾點:
      • 不要讓生命周期長的對象引用activity context,即保證引用activity的對象要與activity本身的生命周期相同;
      • 對于生命周期長的使用application context;
      • 避免使用非靜態內部類,盡量使用靜態類,避免生命周期的問題,注意內部類對外部對象引用時導致的生命周期的變化。
  6. 如何退出activity?如何安全的退出已調用多個activity的application;

    • 通常退出一個activity只需要按返回鍵,代碼中直接調用finish()方法就行,

    • 用數組記錄住打開的每一個activity,在需要退出的時候,遍歷,調用finish()方法關閉每一個activity即可。

    • 發送特定的廣播
      在需要結束應用時,發送一個特定的廣播,每個Activity 收到廣播后,關閉即可。
      //給某個activity 注冊接受接受廣播的意圖
      registerReceiver(receiver, filter)
      //如果過接受到的是關閉activity 的廣播就調用finish()方法把當前的activity finish()掉

    • 遞歸退出。在打開新的Activity時使用startActivityForResult,然后自己添加標志,在onActivityResult()中處理,遞歸關閉。

  7. 兩個activity之間如何傳遞數據;

    • 傳遞的方式有:intent,廣播接收者,contentProvider,static靜態數據(public static 成員變量),file文件存儲,sharedPreferences,sqlite數據庫.

service:

  1. service是在main方法中執行,service中能否執行耗時操作;

    • 默認情況下,如果沒有顯示的是指service所運行的進程,service和activity是運行在當前APP所在進程的主線程(main thread)中,service中不能進行耗時操作(網絡操作,拷貝數據庫,大文件),
    • 特殊情況下,可以在清單文件中進行配置service所執行的進程,讓service在其他進程中執行。
  2. activity怎樣和service綁定,怎樣在activity中啟動對應的service;

    • activity通過bindService(intent service,ServiceConnection conn,int flags)跟service進行綁定,當綁定成功之后,service會將代理對象通過回調的方式傳遞給conn,這樣就可以拿到Service提供的代理對象了。一般情況下, 如果想獲取Service的服務對象那么就需要通過bindService(),比如,音樂播放器,第三方支付。
    • activity還可以通過startService(),通常僅需要開啟一個后臺任務的時候用startService()。
  3. service的生命周期;

    • service有綁定模式和非綁定模式,以及兩種的混合模式,不同的模式生命周期不同;
      • 非綁定模式:當第一次調用startService的時候執行onCreate(),onStartCommand(),當service關閉的時候執行onDestory();
      • 綁定模式:當第一次調用bindService()的時候,執行onCreate(),onBind(),當解除綁定的時候執行onUnbind(),onDestory()。
      • 還需要注意的是service實例只會有一個,也就是說如果當前要啟動的service已經存在了,那就不需用在啟動service了,也就不會在調用onCreate()方法了。
      • 一個service被多個客戶所綁定,只有所有的綁定對象都執行了onBind()方法后該service才會銷毀,但是如果有一個客戶執行了onStart()方法,那么這個時候即使所有的service都執行了onBind()方法,service也不會銷毀。
  4. 什么是IntentService?有什么優點?

    • intentService是service的子類,比起普通的service有了新的功能。普通的service存在兩個問題:service不會啟動一條單獨的線程,service與他所在的應用位于同一個進程中;不能在service中直接處理耗時操作。
    • intentService的特征:會創建獨立的worker線程來處理所有的intent請求;會創建獨立worker線程來處理onHandlerIntent()方法實現的代碼,無需處理多線程問題;所有請求處理完成后,IntentService會自動停止,無需調用stopSelf()方法來停止Service;為service的onBind()方法提供默認的實現,返回null;為service的onStartCommard()方法提供默認實現,將請求intent添加到請求隊列中。
  5. activity,service,intent之間的關系?

    • activity負責用戶界面的顯示和交互,Service負責后臺任務的處理,activity和service之間通過intent傳遞數據,activity和service都是context的子類contextWrapper的子類。
  6. service中可以談吐司嗎?

    • 可以的,但是得有個條件就是得有一個context上下文,由于service是context的子類,因此談吐司是可以的。比如在service中完成任務的下載之后彈一個土司來提醒一下用戶是完全可以的。
  7. service有哪些啟動方法。有什么區別,怎樣停用service?

    • 通過startService()方法,service啟動之后會調用onCreate(),onStart()方法處于運行狀態,stopService的時候調用onDestory()方法停止服務,而如果調用者自己直接退出而沒有調用stopService的方法時,service會一直運行在后臺。
    • 通過bindService()方法,service啟動后回調用onCreate()方法,然后調用onBind()方法,這個時候調用者會和service綁定在一起,如果調用者退出了,service就會調用onUnbind(),onDestory()方法退出。調用者也可以調用unbindService()來停止服務。
    • 需要注意的原則:service的onCreate()方法只會被調用一次,就是無論多少次的startService或者bindService,service只會被創建一次。
    • 如果service在運行期間調用了bindService,這時候在調用stopService,service是不會調用onDestory方法的,service就停止不了了。只有在調用了UnbindService之后,service才會被銷毀。
    • 如果一個service通過startService被start之后,多次調用startService方法的話,這個時候會多次調用onStart方法,多次的調用stopService方法,但是onDestory方法只會被調用一次。
    • 如果一個service通過bindService被start之后,多次調用bindService方法的話,service之后調用一個onBind方法,多次調用unbindService方法會拋異常。

broadcast receiver:

  1. 什么是broadcast receiver,生命周期是什么?

    • broadCast receiver 廣播接收者,分為有序和無序,內部實現機制是通過Android系統的binder機制實現通信的。
    • 無序廣播:完全異步,邏輯上是可以被任何的廣播接收者接收到,效率較高,但是無法一個接受者不能將處理結果傳遞給下一個接受者,并無法終止廣播intent的傳播。
    • 有序廣播:按照被接受者的優先級順序,在被接受者中依次傳播。
  2. 在mainfast和代碼中如何注冊和使用broadcast receiver。

    • 靜態注冊:在mainfast.xml文件中注冊。靜態注冊的廣播,只要應用一直在系統中運行就會一直接收到廣播信息。

        <receiver android:name=".BroadcastReceiver1" >
        <intent-filter>
        <action android:name="android.intent.action.CALL" >
        </action>
        </intent-filter>
        </receiver>
      
    • 動態注冊:在代碼中注冊。動態注冊的的廣播,當注冊的activity或者service銷毀了,就接收不到廣播了。

        receiver = new BroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(CALL_ACTION);
        context.registerReceiver(receiver, intentFilter);
      
  3. broadcastReceiver的生命周期;

    • 廣播接受者的生命周期很短暫,在接收到廣播的時候創建,onReceive()方法結束之后銷毀。
    • 廣播接收者中不要做一些耗時操作,否則會引起ANR,耗時較長的最好放在service中進行。
    • 最好不要再廣播接收者中創建子線程做耗時操作,因為廣播接收者被銷毀之后,進程就變成了空進程,很容易被系統清理掉。

contentProvider :

  1. contentProvider是如何實現數據共享的?

    • contentProvider是應用程序見間共享數據的接口,使用的話需要先自定義一個類繼承ContentProvider,然后覆寫實現query,insert,update,delete四個方法。好需要在清單文件中進行注冊。

        public class PersonContentProvider extends ContentProvider{
        public boolean onCreate(){
            }
            query(Uri, String[], String, String[], String);
            insert(Uri, ContentValues);
            update(Uri, ContentValues, String, String[]);
            delete(Uri, String, String[]);
        }
      
  2. Android中的數據存儲的方式?

    • file文件,sharedPreference,conteneProvider,SQLite數據庫,網絡存儲。
  3. 說出contentProvider,contentResolver, contentObserver之間的關系?

    • contentProvider,內容提供者,用于對外提供數據;
    • contentResolver,內容解析者,用于獲取內容提供者提供的數據;contentResolver.notifyChange(uri)發出消息。
    • contentObserver,內容觀察者,用于監聽內容數據的改變主狀態。contentResolver.registercontentObserver()監聽消息。
  4. contentObserver內容觀察者的作用及特點?

    • contentObserver目的是觀察特定的uri引起的數據庫的變化。繼而做一些相應的處理。
    • 觀察特定的uri的步驟:
      • 創建特定的contentObserver派生類,必須重載父類的構造方法,必須重載onChange()方法去處理回調后的功能實現。
      • 利用context.getContentResolover()獲取contentResolover對象,接著調用registerContentObserver()方法去注冊內容觀察者;
      • 在不需要時,需要手動的調用unregisterContentObserver()去取消注冊。

intent:

  1. intent傳遞數據可以傳遞那些類型數據?

    • 八大基本數據類型和String以及數組形式都可以,還可以傳遞實現了Serializable和Parcelable接口的對象。
  2. 描述intent和intentFliter是什么?

    • Android中通過intent對象來表示一條消息,通過intent可以實現各種系統組件的調用和激活。
    • intentFliter可以理解為一個郵局或者一個信箋的分揀系統。

listview:

  1. listview的優化方式;
    • 復用convertView,優化加載布局,如果沒有緩存就加載布局,如果有緩存就直接使用conventView對象,這樣在滑動listview的時候就不用每次都去調用gitView()方法去加載布局了。

    • 使用自定義靜態類viewHolder,減少fingviewById的次數,convertView為空的時候,viewHolder會將空間里的實例存放在viewHolder中,然后用setTag()的方法將viewHolder對象存放在view中。conventView不為空的時候,用getTag()的方法獲取viewHolder對象。

        public View getView(int position, View convertView, ViewGroup parent) {
           Log.d("MyAdapter", "Position:" + position + "---"
                   + String.valueOf(System.currentTimeMillis()));
           ViewHolder holder;
           if (convertView == null) {
               final LayoutInflater inflater = (LayoutInflater) mContext
                      .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
               convertView = inflater.inflate(R.layout.list_item_icon_text, null);
               holder = new ViewHolder();
               holder.icon = (ImageView) convertView.findViewById(R.id.icon);
               holder.text = (TextView) convertView.findViewById(R.id.text);
               convertView.setTag(holder);
           } else {
               holder = (ViewHolder) convertView.getTag();
           }
           holder.icon.setImageResource(R.drawable.icon);
           holder.text.setText(mData[position]);
           return convertView;
        }
        
        static class ViewHolder {
           ImageView icon; 
           TextView text;
        }
      
    • 異步加載數據,分頁加載數據;

      • listview的分頁加載, 設置listview的滾動監聽器,setOnScrollListener(new OnScrollListener { ... });該監聽器有兩個方法,onScrollStateChanged()--滾動狀態發生改變的時候,onScroll()0--listview被滾動時調用的方法。在滾動狀態發生改變的時候,有三種狀態:

        • 手指按下移動的狀態:SCROLL_STATE_TOUCH_SCROLL :觸摸滑動。
        • 慣性滾動狀態:SCROLL_STATE_FLING : (滑翔 )
        • 靜止狀態:SCROLL_STATE_IDLE : 靜止。
      • 對不同的狀態進行處理:分批加載數據,只關心靜態狀態:關心最后一個可見的條目,如果最后一個可見條目就是適配器里的最后一個,此時就可加載更多的數據,在每次加載的時候, 計算出滾動的數量,當滾動的數量大于等于總數量的時候,可以提示用戶無更多的數據。

  1. listview數據集改變之后,如何更新listview?

    • 使用listview的adapter的notifyDataSetChange()方法,該方法會使listview重新繪制。
  2. listview能否實現多種類型的條目?

    • 可以,listview顯示的每個條目都是通過baseAdapter的gitView(int position,View convertView,ViewGroup parent)來展示的,理論上可以讓每個條目都是不同類型的view。
    • 另外,adapter還提供了getViewTypeCount()和getItemViewType(int position)兩個方法,在getView方法中可以根據不同的viewtype加載不同的布局文件。
  3. listview如何跳轉到指定位置?

    • 可以通過lv.setSelection(listView.getPosition)方法。
  4. listview如何優化圖片?圖片錯亂的問題是如何產生的;

    • 圖片處理的方法有以下幾種:

      • 不要直接拿路徑去循環,BitmapFactory.decodeFile,使用Options保存圖片大小,不要加載圖片到內存中去。
      • 對圖片一定要邊界壓縮,尤其是大圖,而如果圖片是后臺服務器處理好的就不用了。
      • 在listview中取圖片的時候不要直接拿路徑去取,而是使用lruCache對圖片做緩存處理;
      • 在getView中做圖片轉換的時候,產生的中間變量一定要釋放。
    • 圖片錯亂的原因分析: 圖片錯亂的本質是由于在listview的時候使用了緩存ConvertView導致的,假設一種場景,一個listview一屏只能顯示十條item,那么在拉出第11條item的時候,這條item其實是復用的第一條item,也就是說第一條item從服務端下載的圖片,并最重要顯示的時候,其實該item已經不再當前顯示的區域內了,此時顯示的結果可能在第11條item上輸出圖像,這就導致了圖片錯亂的問題。解決的方案就是通過給圖片設置tag來防止圖片錯亂。在getView的時候,給viewHolder類中的imageView設置一個Tag,這個tag設置的是圖片的url地址,然后在異步加載圖片完成回調的方法中,使用findviewWithTag(String url)來找到listview中position對應的imageview。然后給imageview設置圖片即可。前提需要預設一張圖片。

         //給imageView設置一個tag。
         holder.img.setTag(imgUrl);  
         // 預設一個圖片  
         holder.img.setImageResource(R.drawable.ic_launcher);  
         if (imgUrl != null && !imgUrl.equals("")) {  
             Bitmap bitmap = imageLoader.loadImage(holder.img, imgUrl,  
                     new ImageDownloadedCallBack() {  
      
                        @Override  
                         public void onImageDownloaded(ImageView imageView,  
                                 Bitmap bitmap) {  
                             // 通過 tag 來防止圖片錯位  
                             if (imageView.getTag() != null  
                                     && imageView.getTag().equals(imgUrl)) {  
                                 imageView.setImageBitmap(bitmap);  
                            }  
                        }  
                     });  
             if (bitmap != null) {  
                 holder.img.setImageBitmap(bitmap);  
             }  
         }  
      
  5. scrollView中如何嵌套listview;

    • 通常情況下,在scrollView 重視不嵌套listview的,但是面試官要是問到這種問題的時候,回答是可以的,在scrollview 中添加一個listview會導致listview控件顯示不全,通常只會顯示一條,這是由于兩個控件的滑動沖突導致的,所以:
      • 需要通過listview的item數量去計算listview的顯示高度,從而使其完整顯示;
      •   lv = (ListView) findViewById(R.id.lv);
          adapter = new MyAdapter();
          lv.setAdapter(adapter);
          setListViewHeightBasedOnChildren(lv);
          ----------------------------------------------------
          public void setListViewHeightBasedOnChildren(ListView listView) {
          ListAdapter listAdapter = listView.getAdapter();
          if (listAdapter == null) {
          return;
          }
          int totalHeight = 0;
          for (int i = 0; i < listAdapter.getCount(); i++) {
          View listItem = listAdapter.getView(i, null, listView);
          listItem.measure(0, 0);
          totalHeight += listItem.getMeasuredHeight();
          }
          ViewGroup.LayoutParams params = listView.getLayoutParams();
          params.height = totalHeight + (listView.getDividerHeight() *
          (listAdapter.getCount() - 1));
          params.height += 5; //如果沒有這個聲明,listview就只有一點。
          
          listView.setLayoutParams(params);
          }
          
          //而現階段最好的方法就是自定義listview,重寫OnMeasure( )方法,使其完整顯示。
          
          public class ScrollViewWithListView extends ListView {
          public ScrollViewWithListView(android.content.Context context,
          android.util.AttributeSet attrs) {
          super(context, attrs);
          }
          /**
          * Integer.MAX_VALUE >> 2,如果不設置,系統默認設置是顯示兩條
          */
          public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
          MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec);
           }
          }
        
  6. 如何刷新listview中item的單個數據,不刷新整個listview的數據?

    • 修改單個item的數據,然后調用adapter的notifyDataSetChanged()方法進行刷新。或者直接用handler去更新,在adapter中創建一個handler,值發生改變的時候,handler就send一個message,更新ui。

recyclerView:

  1. 使用recycleView的好處;

    • recycleView是Android 5.0 materials design 中的組件之一,recycleView封裝了viewHolder的回收復用機制,也就是說recycleView標準化了viewHolder,編寫Adapter面向的是viewHolder而不再是view了,復用的邏輯被封裝了,寫起來更方便了。recycleView提供了一種插拔式的體驗,高度的解耦,異常的靈活,針對一個Item的顯示RecylerView專門抽取出了相應的類,來控制Item的顯示,使其的擴展性非常強。例如:你想控制橫向或者縱向滑動列表效果可以通過LinearLayoutManager這個類來進行控制(與GridView效果對應的是GridLayoutManager,與瀑布流對應的還有StaggeredGridLayoutManager等),也就是說RecylerView不再拘泥于ListView的線性展示方式,它也可以實現GridView的效果等多種效果。你想控制Item的分隔線,可以通過繼承RecylerView的ItemDecoration這個類,然后針對自己的業務需求去抒寫代碼。
      可以控制Item增刪的動畫,可以通過ItemAnimator這個類進行控制,當然針對增刪的動畫,RecylerView有其自己默認的實現。
  2. recycleView的使用方法:

      recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
            LinearLayoutManager layoutManager = new LinearLayoutManager(this );
            //設置布局管理器
            recyclerView.setLayoutManager(layoutManager);
            //設置為垂直布局,這也是默認的
            layoutManager.setOrientation(OrientationHelper. VERTICAL);
            //設置Adapter
            recyclerView.setAdapter( recycleAdapter);
            //設置分隔線
            recyclerView.addItemDecoration(new DividerGridItemDecoration(this ));
            //設置增加或刪除條目的動畫
            recyclerView.setItemAnimator( new DefaultItemAnimator());
    
  3. recylerView的Adapter的寫法,需要實現三個方法:

    • onCreateViewHolder():這個方法主要生成為每個Item inflater出一個View,但是該方法返回的是一個ViewHolder。該方法把View直接封裝在ViewHolder中,然后我們面向的是ViewHolder這個實例,當然這個ViewHolder需要我們自己去編寫。直接省去了當初的convertView.setTag(holder)和convertView.getTag()這些繁瑣的步驟。
    • onBindViewHolder():這個方法主要用于適配渲染數據到View中。方法提供給你了一個viewHolder,而不是原來的convertView。
    • getItemCount():這個方法就類似于BaseAdapter的getCount方法了,即總共有多少個條目。
  4. 給RecyclerView的Item添加點擊事件:

    • 由于recylerView沒有提供類似于listview的setOnItemClickListener()的方法來處理item的點擊事件,因此只能模擬類似的方法, 使用的是在創建itemView的時候添加監聽,就是在創建view的時候添加點擊事件,然后在Adapter對對象中添加監聽回調. 具體的做法是:首先自定義接口onRecylerViewItemClickListener,定義onItemClick()方法,在給方法中有兩個參數,view和position,在給holder傳入onRecylerViewItemClickListener參數,讓holder實現View.OnClickListener,并在onClick方法中調用onRecylerViewItemClickListener.onItemClick()方法,通過傳入的position來判斷item的位置,從而實現每個item的點擊事件.
  5. 給RecyclerView的Item添加下拉刷新:

    • 通過SwipeRefreshLayout這個組件,去實現列表下拉刷新功能,通過設置下拉刷新的監聽事件setOnRefreshListener()重寫OnRefresh()方法,而設置上拉加載更多可以通過設置滑動事件監聽來實現setOnScrollListener()重寫onScrollStateChanged()方法.通過設置swipeRefreshView.setRefreshing為true來實現刷新.

socket通信與網絡編程(TCP/UDP協議,http協議)

  1. 什么是網絡編程:

    • 網絡編程是指兩臺設備之間實現數據傳遞的過程,也可以說是使用套接字完成不同進程之間的網絡通訊的編程。要了解網絡編程,需要先了解網絡通訊,網絡通訊分HTTP通訊和socket網絡通訊,說到這需要先了解一下網絡通訊的層級,網絡通訊的層級一共有四層:最低層鏈路層,這里主要是硬件的接口,然后是網絡層,這里用我們比較熟悉的IP協議,在然后是傳輸層,這里有TCP協議和UDP協議,最后就是應用層,HTTP協議(超文本傳輸協議)就在這一層,這里需要注意的是,HTTP是一種協議,而socket是一個接口。
  2. 傳輸層兩大協議:TCP/UDP協議:

    • UDP協議是一種用戶數據報協議,是面向無連接的,數據傳輸不可靠的一種點對多點的通訊,也就是說UDP在傳輸數據前是不與對方建立連接的,對于接收到的數據也是不發送確認信號的,發送數據的一方也不會知道數據是否發送成功,也就無法再重新發送了。我們經常使用的“ping”命令來檢測兩臺設備主機之間的TCP/IP通信是否正常,而這個“ping”就是 使用UDP協議,通過向對方主機發送UDP數據包,然后對方確認收到數據包,如果對方將數據包到達的纖細及時的返回回來,就說明兩臺設備主機之間的通訊是通的。
    • TCP協議是一種傳輸控制協議,它是面向有連接的,數據傳輸可靠的一種通訊方式,它是通過三次握手來實現面向有連接的,而這三次握手指的是:
  1. 首先客戶端發送一個空的數據報包給服務端,并且將客戶端置為發送狀態;
  2. 接著服務端接收到這這個空的數據報包,會相應客戶端一個確認包,并將服務端置為接收狀態;
    3)客戶端接收到服務端發送回來的響應,然后再向服務端發送一個確認包,一旦此包發送完畢,那么服務端就與客戶端之間建立了長連接,并且雙方都處于確認狀態,而建立的這個長連接在理論上如果單方不主動去停止這個連接,這個連接就會一直存在,只要連接存在,服務器就可以和客戶端近行數據的互傳。
  1. 什么是socket通信:

    • 說起socket,得要先知道套接字,套接字是TCP/IP網絡通信的基本操作單元,主要包括三大要素:IP,協議,端口。在說socket,socket其實就是一堆套接字,它在客戶端叫clientSocket,在服務端叫serviceSocket,socket其實就是方便TCP和UDP編程的一個接口,應用層和傳輸層通過socket接口,區分來自不同的應用進程和網絡連接的通信,實現數據傳輸的并發服務。(應用層在通過傳輸層傳輸的時候,傳輸層的TCP會同時遇到為多個應用進程提供并發服務的問題,多個TCP連接或多個應用進程可能需要同一個TCP連接,為了區別不同應用進程的連接,許多計算機為應用進程提供了套接字接口)
    • socket建立連接:socket是一個接口,它是可以指定傳輸層協議的,也就是說當他在指定TCP協議的時候建立的socket連接就是一個TCP連接,需要通過三次握手才能進行連接。從廣義上講:socket連接可以這樣講:
      • 服務器監聽:說的是服務器套接字并不指定客戶端套接字,它處于一個實時監聽網絡狀態,等待客戶端的請求,連接。
      • 客戶端發送請求:客戶端套接字在請求中聲明套接字的描述和服務端的ip和端口號,然后向服務端套接字發送請求。
      • 連接確認:服務端套接字接收到客戶端套接字發送來的請求后,想客戶端套接字發送一個確認響應,并在這個響應中添加服務器套接字的描述,一旦客戶端確認了這個描述,那么雙方就正式的建立了連接,而測試服務器處于一個監聽狀態,等待著其他客戶端套接字發送來的請求。
  1. socket接口是如何利用代碼實現TCP連接和UDP連接的;

    • 代碼實現TCP連接:首先在客戶端創建socket對象,然后創建inputStream封裝要傳輸的數據,然后在socket中通過getOutputStream獲取輸出流,然后通過寫出io流的形式將數據寫入到服務器當中去。在服務器中創建serviceSocket對象,然后通過serviceSocket對象中的accept方法獲取socket對象,最后在socket對象中通過getInputStream方法獲取數據。
    • 代碼實現UDP連接: 首先在客戶端創建DatagramSocket對象,然后創建DatagramPacket對象(他其實就是報包),這個對象創建的時候會需要傳入四個參數,
      DatagramPacket p = new DatagramPacket(messageByte, msg_length, url, server_port);
      第一個參數為傳遞的數據data(不過是個字節數組,而且不能超過64k),第二個參數是數據的長度,第三個參數是網絡地址(可以通過inetAddress.getByName這個方法傳入一個ip就可以獲得網絡地址了),第四個參數是端口號。 然后socket對象.send(packet對象)發送報包就可以了。服務器端創建DatagramSocket對象,創建兩個參數的DatagramPacket的空報包對象(只是創建一個字節數組),然后調用socket對象.receive(packet)來接受數據,最后調用packet.getData即可.
  2. HTTP通訊:

    • http協議:超文本傳輸協議,手機常用協議之一,是基于TCP協議之上的應用層協議。http1.0的時候是一個請求一個連接,請求結束后就會斷開連接。http1.1的時候是已連接對應多個請求,多個請求可以重接執行,不用等一個請求結束在進行下一個請求,而http2.0同樣是一個連接對應多個請求,并且在應用層和傳輸層增加了一個二進制的分幀層,這些幀對應邏輯流中的消息,并行的在同一個TCP連接上進行雙向交流消息。
  3. socket和http的區別;

    • 形象的說http他就像一個轎車,提供了封裝或者顯示數據的具體形式,而socket是發動機,提供了網絡通訊的能力,http他是一個協議,是基于TCP協議的,Tcp協議是基于ip協議的,而socket提供了針對TCP和UDP編程的接口。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,242評論 25 708
  • (一)Android面試題(一)Activity、Intent Android四大組件分別是哪些?各自有什么作用和...
    Itachi001閱讀 4,480評論 4 95
  • 整理一些常見的Android面試題(針對于2~3年開發經驗中所遇到的問題) synchronized鎖靜態方法和非...
    appzy閱讀 2,355評論 4 18
  • 這件事情是我錯了 您說的這些話 確實是對我的耳提面命 我也知道你您很擔心我 可是 我還是很難受 這是否是您對我的不...
    一六零六零六閱讀 243評論 0 0
  • “道”是以老子、莊子為代表的道家思想派別的核心。道家崇尚自然,主張恬淡無為、頤養天年,其思想中的“精、氣、神”等與...
    Archita閱讀 518評論 0 0