Android面試基礎(chǔ)題總結(jié)一

Android四大組件:

activity:

  1. activity的生命周期:activity是context的子類,同時實(shí)現(xiàn)了window.callback 和 keyevent.callback.可以處理與窗體用戶交互的事件云矫。activity從創(chuàng)建到銷毀有多種狀態(tài)舵匾,在這些狀態(tài)轉(zhuǎn)換的時候伴隨有回調(diào)方法:onCreate(創(chuàng)建 )轻黑,onStart(可見)氯迂,onResume(可交互),onPause(不可交互)冯事,onStop(不可見)宿接,onDestory(銷毀)赘淮,onRestart(重新可見).

    • activity在一創(chuàng)建的時候會執(zhí)行onCreate(),onStart()睦霎,onResume()梢卸,在A界面上啟動B界面的之后,A界面會執(zhí)行onPause(),onStop()方法副女,如果B界面是一個diaLog蛤高,A界面處于可見但不可交互的狀態(tài),會執(zhí)行onStop()方法,由B界面返回A界面會執(zhí)行onReStart()襟齿,onstart(),onResume()方法姻锁,退出A界面會執(zhí)行onPause()枕赵,onStop()猜欺,onDestory()方法。
  2. activity的幾種啟動模式:包括:標(biāo)準(zhǔn)模式(standard)拷窜,singleTop开皿,singleTask,singleInstance篮昧。

    • 標(biāo)準(zhǔn)啟動模式是說:默認(rèn)的啟動模式赋荆,可以不用配置,會隨著每個activity的開啟懊昨,每次都會創(chuàng)建一個實(shí)例對象窄潭,可以有多個實(shí)例對象,也可以多個相同的activity疊加酵颁。在點(diǎn)擊back退出時會依照棧順序依次退出嫉你。
    • singleTop是說:可以有多個實(shí)例對象,但不可以多個相同activity疊加躏惋,如果activity在棧頂幽污,啟動相同的activity,不會創(chuàng)建新的實(shí)例簿姨,而會調(diào)用它的onNewIntent方法距误。
    • singleTask是說:只有一個實(shí)例對象,在同一個應(yīng)用程序中啟動它時扁位,若該activity不存在准潭,就會在當(dāng)前的任務(wù)棧中創(chuàng)建一個新的實(shí)例,若存在域仇,則會把任務(wù)棧中所有在其之上的activity全部destory之后再調(diào)用其onNewIntent方法刑然。而如果說在其他的應(yīng)用程序中啟動它,則會新建一個task殉簸,并在該task中啟動這個activity闰集,singleTask允許別的activity與其在統(tǒng)一個task中共存,也就是說般卑,如果我在這個singleTask的實(shí)例中在啟動新的activity武鲁,這個新的activity還是會存在這一個singleTask的實(shí)例的任務(wù)棧中。
    • singleInstance是說:只有一個實(shí)例蝠检,并且這個實(shí)例只運(yùn)行在一個task中沐鼠,在這個task中只有這一個實(shí)例,不允許在有其他activity存在理卑。
  3. 如何保存和恢復(fù)Activity的狀態(tài)數(shù)據(jù):

    • activity的狀態(tài)通常情況下系統(tǒng)會自動保存蛔翅,一般來說,在調(diào)用onPause()和onStop()方法之后倾芝,activity的實(shí)例仍然保存在內(nèi)存中憔涉,activity的所有信息和狀態(tài)數(shù)據(jù)都不會丟失订框,當(dāng)activity重新回到前臺之后,所有的改變都會保留兜叨,
    • 但是當(dāng)系統(tǒng)內(nèi)存不足時穿扳,調(diào)用onPause()和onStop()方法之后的activity可能會被系統(tǒng)銷毀,此時內(nèi)存中就沒有了這個activity的實(shí)例對象了国旷,如果這個activity重新回到前臺矛物,所有的改變都會消失,為了避免該情況的發(fā)生跪但,可以覆寫onsaveInstanceState()方法履羞。onsaveInstanceState()方法接收一個bundle類型的參數(shù),可以將狀態(tài)數(shù)據(jù)存儲在bundle中屡久,這樣即使activity銷毀忆首,用戶在次啟動activity,在調(diào)用它的onCreate(),上述的bundle對象會作為實(shí)參來傳遞給onCreate()方法涂身,然后可以從bundle中獲取到保存的數(shù)據(jù)雄卷,將activity恢復(fù)到銷毀前的樣子。需要注意的是調(diào)用onsaveInstanceState()方法蛤售,要在方法onPause()和onStop()調(diào)用之前丁鹉。
  4. 兩個activity之間跳轉(zhuǎn)必然會執(zhí)行那些方法;

    • 兩個activity悴能,從A跳轉(zhuǎn)至B揣钦,當(dāng)B是一個對話框時或者透明窗體時,A會調(diào)用onPause()方法漠酿,B會調(diào)用onCreate()冯凹,onStart(),onResume(),當(dāng)B覆蓋A時炒嘲,A會調(diào)用onStop()方法宇姚。
  5. Android中activity,context夫凸,application之間有什么區(qū)別浑劳;

    • 相同點(diǎn):context是描述一個應(yīng)用程序環(huán)境的信息,即上下文的意思夭拌,該類是一個抽象類(abstract class)魔熏,Android有提供該抽象類的具體實(shí)現(xiàn)類(contextlml)衷咽,activity和application都是context的子類。
    • 不同點(diǎn): 維護(hù)的生命周期不同蒜绽。context維護(hù)的是當(dāng)前activity的生命周期镶骗,而application維護(hù)的是整個項(xiàng)目的生命周期。
    • 在使用context的時候躲雅,需要防止內(nèi)存泄漏鼎姊,需要注意幾點(diǎn):
      • 不要讓生命周期長的對象引用activity context,即保證引用activity的對象要與activity本身的生命周期相同吏夯;
      • 對于生命周期長的使用application context此蜈;
      • 避免使用非靜態(tài)內(nèi)部類即横,盡量使用靜態(tài)類噪生,避免生命周期的問題,注意內(nèi)部類對外部對象引用時導(dǎo)致的生命周期的變化东囚。
  6. 如何退出activity跺嗽?如何安全的退出已調(diào)用多個activity的application;

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

    • 用數(shù)組記錄住打開的每一個activity,在需要退出的時候份帐,遍歷璃吧,調(diào)用finish()方法關(guān)閉每一個activity即可。

    • 發(fā)送特定的廣播
      在需要結(jié)束應(yīng)用時废境,發(fā)送一個特定的廣播畜挨,每個Activity 收到廣播后,關(guān)閉即可噩凹。
      //給某個activity 注冊接受接受廣播的意圖
      registerReceiver(receiver, filter)
      //如果過接受到的是關(guān)閉activity 的廣播就調(diào)用finish()方法把當(dāng)前的activity finish()掉

    • 遞歸退出巴元。在打開新的Activity時使用startActivityForResult,然后自己添加標(biāo)志,在onActivityResult()中處理驮宴,遞歸關(guān)閉逮刨。

  7. 兩個activity之間如何傳遞數(shù)據(jù);

    • 傳遞的方式有:intent堵泽,廣播接收者修己,contentProvider,static靜態(tài)數(shù)據(jù)(public static 成員變量)迎罗,file文件存儲睬愤,sharedPreferences,sqlite數(shù)據(jù)庫.

service:

  1. service是在main方法中執(zhí)行佳谦,service中能否執(zhí)行耗時操作戴涝;

    • 默認(rèn)情況下,如果沒有顯示的是指service所運(yùn)行的進(jìn)程,service和activity是運(yùn)行在當(dāng)前APP所在進(jìn)程的主線程(main thread)中啥刻,service中不能進(jìn)行耗時操作(網(wǎng)絡(luò)操作奸鸯,拷貝數(shù)據(jù)庫,大文件)可帽,
    • 特殊情況下娄涩,可以在清單文件中進(jìn)行配置service所執(zhí)行的進(jìn)程,讓service在其他進(jìn)程中執(zhí)行映跟。
  2. activity怎樣和service綁定蓄拣,怎樣在activity中啟動對應(yīng)的service;

    • activity通過bindService(intent service努隙,ServiceConnection conn球恤,int flags)跟service進(jìn)行綁定,當(dāng)綁定成功之后荸镊,service會將代理對象通過回調(diào)的方式傳遞給conn,這樣就可以拿到Service提供的代理對象了咽斧。一般情況下, 如果想獲取Service的服務(wù)對象那么就需要通過bindService()躬存,比如张惹,音樂播放器,第三方支付岭洲。
    • activity還可以通過startService()宛逗,通常僅需要開啟一個后臺任務(wù)的時候用startService()。
  3. service的生命周期盾剩;

    • service有綁定模式和非綁定模式雷激,以及兩種的混合模式,不同的模式生命周期不同彪腔;
      • 非綁定模式:當(dāng)?shù)谝淮握{(diào)用startService的時候執(zhí)行onCreate()侥锦,onStartCommand(),當(dāng)service關(guān)閉的時候執(zhí)行onDestory()德挣;
      • 綁定模式:當(dāng)?shù)谝淮握{(diào)用bindService()的時候恭垦,執(zhí)行onCreate(),onBind()格嗅,當(dāng)解除綁定的時候執(zhí)行onUnbind()番挺,onDestory()。
      • 還需要注意的是service實(shí)例只會有一個屯掖,也就是說如果當(dāng)前要啟動的service已經(jīng)存在了玄柏,那就不需用在啟動service了,也就不會在調(diào)用onCreate()方法了贴铜。
      • 一個service被多個客戶所綁定粪摘,只有所有的綁定對象都執(zhí)行了onBind()方法后該service才會銷毀瀑晒,但是如果有一個客戶執(zhí)行了onStart()方法,那么這個時候即使所有的service都執(zhí)行了onBind()方法徘意,service也不會銷毀苔悦。
  4. 什么是IntentService?有什么優(yōu)點(diǎn)?

    • intentService是service的子類椎咧,比起普通的service有了新的功能玖详。普通的service存在兩個問題:service不會啟動一條單獨(dú)的線程,service與他所在的應(yīng)用位于同一個進(jìn)程中勤讽;不能在service中直接處理耗時操作蟋座。
    • intentService的特征:會創(chuàng)建獨(dú)立的worker線程來處理所有的intent請求;會創(chuàng)建獨(dú)立worker線程來處理onHandlerIntent()方法實(shí)現(xiàn)的代碼脚牍,無需處理多線程問題向臀;所有請求處理完成后,IntentService會自動停止莫矗,無需調(diào)用stopSelf()方法來停止Service飒硅;為service的onBind()方法提供默認(rèn)的實(shí)現(xiàn),返回null作谚;為service的onStartCommard()方法提供默認(rèn)實(shí)現(xiàn),將請求intent添加到請求隊(duì)列中庵芭。
  5. activity妹懒,service,intent之間的關(guān)系双吆?

    • activity負(fù)責(zé)用戶界面的顯示和交互眨唬,Service負(fù)責(zé)后臺任務(wù)的處理,activity和service之間通過intent傳遞數(shù)據(jù)好乐,activity和service都是context的子類contextWrapper的子類匾竿。
  6. service中可以談吐司嗎?

    • 可以的蔚万,但是得有個條件就是得有一個context上下文岭妖,由于service是context的子類,因此談吐司是可以的反璃。比如在service中完成任務(wù)的下載之后彈一個土司來提醒一下用戶是完全可以的昵慌。
  7. service有哪些啟動方法。有什么區(qū)別淮蜈,怎樣停用service斋攀?

    • 通過startService()方法,service啟動之后會調(diào)用onCreate(),onStart()方法處于運(yùn)行狀態(tài),stopService的時候調(diào)用onDestory()方法停止服務(wù)梧田,而如果調(diào)用者自己直接退出而沒有調(diào)用stopService的方法時淳蔼,service會一直運(yùn)行在后臺侧蘸。
    • 通過bindService()方法,service啟動后回調(diào)用onCreate()方法鹉梨,然后調(diào)用onBind()方法闺魏,這個時候調(diào)用者會和service綁定在一起,如果調(diào)用者退出了俯画,service就會調(diào)用onUnbind()析桥,onDestory()方法退出。調(diào)用者也可以調(diào)用unbindService()來停止服務(wù)艰垂。
    • 需要注意的原則:service的onCreate()方法只會被調(diào)用一次泡仗,就是無論多少次的startService或者bindService,service只會被創(chuàng)建一次猜憎。
    • 如果service在運(yùn)行期間調(diào)用了bindService娩怎,這時候在調(diào)用stopService,service是不會調(diào)用onDestory方法的胰柑,service就停止不了了截亦。只有在調(diào)用了UnbindService之后,service才會被銷毀柬讨。
    • 如果一個service通過startService被start之后崩瓤,多次調(diào)用startService方法的話,這個時候會多次調(diào)用onStart方法踩官,多次的調(diào)用stopService方法却桶,但是onDestory方法只會被調(diào)用一次。
    • 如果一個service通過bindService被start之后蔗牡,多次調(diào)用bindService方法的話颖系,service之后調(diào)用一個onBind方法,多次調(diào)用unbindService方法會拋異常辩越。

broadcast receiver:

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

    • broadCast receiver 廣播接收者黔攒,分為有序和無序趁啸,內(nèi)部實(shí)現(xiàn)機(jī)制是通過Android系統(tǒng)的binder機(jī)制實(shí)現(xiàn)通信的。
    • 無序廣播:完全異步亏钩,邏輯上是可以被任何的廣播接收者接收到莲绰,效率較高,但是無法一個接受者不能將處理結(jié)果傳遞給下一個接受者姑丑,并無法終止廣播intent的傳播蛤签。
    • 有序廣播:按照被接受者的優(yōu)先級順序,在被接受者中依次傳播栅哀。
  2. 在mainfast和代碼中如何注冊和使用broadcast receiver震肮。

    • 靜態(tài)注冊:在mainfast.xml文件中注冊称龙。靜態(tài)注冊的廣播,只要應(yīng)用一直在系統(tǒng)中運(yùn)行就會一直接收到廣播信息戳晌。

        <receiver android:name=".BroadcastReceiver1" >
        <intent-filter>
        <action android:name="android.intent.action.CALL" >
        </action>
        </intent-filter>
        </receiver>
      
    • 動態(tài)注冊:在代碼中注冊鲫尊。動態(tài)注冊的的廣播,當(dāng)注冊的activity或者service銷毀了沦偎,就接收不到廣播了疫向。

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

    • 廣播接受者的生命周期很短暫豪嚎,在接收到廣播的時候創(chuàng)建搔驼,onReceive()方法結(jié)束之后銷毀。
    • 廣播接收者中不要做一些耗時操作侈询,否則會引起ANR舌涨,耗時較長的最好放在service中進(jìn)行。
    • 最好不要再廣播接收者中創(chuàng)建子線程做耗時操作扔字,因?yàn)閺V播接收者被銷毀之后囊嘉,進(jìn)程就變成了空進(jìn)程,很容易被系統(tǒng)清理掉革为。

contentProvider :

  1. contentProvider是如何實(shí)現(xiàn)數(shù)據(jù)共享的扭粱?

    • contentProvider是應(yīng)用程序見間共享數(shù)據(jù)的接口,使用的話需要先自定義一個類繼承ContentProvider篷角,然后覆寫實(shí)現(xiàn)query焊刹,insert,update恳蹲,delete四個方法。好需要在清單文件中進(jìn)行注冊俩滥。

        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中的數(shù)據(jù)存儲的方式嘉蕾?

    • file文件,sharedPreference霜旧,conteneProvider,SQLite數(shù)據(jù)庫错忱,網(wǎng)絡(luò)存儲。
  3. 說出contentProvider挂据,contentResolver以清, contentObserver之間的關(guān)系?

    • contentProvider崎逃,內(nèi)容提供者掷倔,用于對外提供數(shù)據(jù);
    • contentResolver个绍,內(nèi)容解析者勒葱,用于獲取內(nèi)容提供者提供的數(shù)據(jù)浪汪;contentResolver.notifyChange(uri)發(fā)出消息。
    • contentObserver凛虽,內(nèi)容觀察者死遭,用于監(jiān)聽內(nèi)容數(shù)據(jù)的改變主狀態(tài)。contentResolver.registercontentObserver()監(jiān)聽消息凯旋。
  4. contentObserver內(nèi)容觀察者的作用及特點(diǎn)呀潭?

    • contentObserver目的是觀察特定的uri引起的數(shù)據(jù)庫的變化。繼而做一些相應(yīng)的處理至非。
    • 觀察特定的uri的步驟:
      • 創(chuàng)建特定的contentObserver派生類钠署,必須重載父類的構(gòu)造方法,必須重載onChange()方法去處理回調(diào)后的功能實(shí)現(xiàn)睡蟋。
      • 利用context.getContentResolover()獲取contentResolover對象踏幻,接著調(diào)用registerContentObserver()方法去注冊內(nèi)容觀察者;
      • 在不需要時戳杀,需要手動的調(diào)用unregisterContentObserver()去取消注冊该面。

intent:

  1. intent傳遞數(shù)據(jù)可以傳遞那些類型數(shù)據(jù)?

    • 八大基本數(shù)據(jù)類型和String以及數(shù)組形式都可以,還可以傳遞實(shí)現(xiàn)了Serializable和Parcelable接口的對象信卡。
  2. 描述intent和intentFliter是什么隔缀?

    • Android中通過intent對象來表示一條消息,通過intent可以實(shí)現(xiàn)各種系統(tǒng)組件的調(diào)用和激活傍菇。
    • intentFliter可以理解為一個郵局或者一個信箋的分揀系統(tǒng)猾瘸。

listview:

  1. listview的優(yōu)化方式;
    • 復(fù)用convertView,優(yōu)化加載布局丢习,如果沒有緩存就加載布局牵触,如果有緩存就直接使用conventView對象,這樣在滑動listview的時候就不用每次都去調(diào)用gitView()方法去加載布局了咐低。

    • 使用自定義靜態(tài)類viewHolder揽思,減少fingviewById的次數(shù),convertView為空的時候见擦,viewHolder會將空間里的實(shí)例存放在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;
        }
      
    • 異步加載數(shù)據(jù),分頁加載數(shù)據(jù)酒来;

      • listview的分頁加載卢未, 設(shè)置listview的滾動監(jiān)聽器,setOnScrollListener(new OnScrollListener { ... })役首;該監(jiān)聽器有兩個方法尝丐,onScrollStateChanged()--滾動狀態(tài)發(fā)生改變的時候显拜,onScroll()0--listview被滾動時調(diào)用的方法。在滾動狀態(tài)發(fā)生改變的時候爹袁,有三種狀態(tài):

        • 手指按下移動的狀態(tài):SCROLL_STATE_TOUCH_SCROLL :觸摸滑動远荠。
        • 慣性滾動狀態(tài):SCROLL_STATE_FLING : (滑翔 )
        • 靜止?fàn)顟B(tài):SCROLL_STATE_IDLE : 靜止。
      • 對不同的狀態(tài)進(jìn)行處理:分批加載數(shù)據(jù)失息,只關(guān)心靜態(tài)狀態(tài):關(guān)心最后一個可見的條目譬淳,如果最后一個可見條目就是適配器里的最后一個,此時就可加載更多的數(shù)據(jù)盹兢,在每次加載的時候邻梆, 計(jì)算出滾動的數(shù)量,當(dāng)滾動的數(shù)量大于等于總數(shù)量的時候绎秒,可以提示用戶無更多的數(shù)據(jù)浦妄。

  1. listview數(shù)據(jù)集改變之后,如何更新listview见芹?

    • 使用listview的adapter的notifyDataSetChange()方法剂娄,該方法會使listview重新繪制。
  2. listview能否實(shí)現(xiàn)多種類型的條目玄呛?

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

    • 可以通過lv.setSelection(listView.getPosition)方法。
  4. listview如何優(yōu)化圖片淹魄?圖片錯亂的問題是如何產(chǎn)生的诗轻;

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

      • 不要直接拿路徑去循環(huán),BitmapFactory.decodeFile,使用Options保存圖片大小揭北,不要加載圖片到內(nèi)存中去。
      • 對圖片一定要邊界壓縮吏颖,尤其是大圖搔体,而如果圖片是后臺服務(wù)器處理好的就不用了。
      • 在listview中取圖片的時候不要直接拿路徑去取半醉,而是使用lruCache對圖片做緩存處理疚俱;
      • 在getView中做圖片轉(zhuǎn)換的時候,產(chǎn)生的中間變量一定要釋放缩多。
    • 圖片錯亂的原因分析: 圖片錯亂的本質(zhì)是由于在listview的時候使用了緩存ConvertView導(dǎo)致的呆奕,假設(shè)一種場景养晋,一個listview一屏只能顯示十條item,那么在拉出第11條item的時候梁钾,這條item其實(shí)是復(fù)用的第一條item绳泉,也就是說第一條item從服務(wù)端下載的圖片,并最重要顯示的時候姆泻,其實(shí)該item已經(jīng)不再當(dāng)前顯示的區(qū)域內(nèi)了零酪,此時顯示的結(jié)果可能在第11條item上輸出圖像,這就導(dǎo)致了圖片錯亂的問題拇勃。解決的方案就是通過給圖片設(shè)置tag來防止圖片錯亂四苇。在getView的時候,給viewHolder類中的imageView設(shè)置一個Tag,這個tag設(shè)置的是圖片的url地址方咆,然后在異步加載圖片完成回調(diào)的方法中月腋,使用findviewWithTag(String url)來找到listview中position對應(yīng)的imageview。然后給imageview設(shè)置圖片即可瓣赂。前提需要預(yù)設(shè)一張圖片榆骚。

         //給imageView設(shè)置一個tag。
         holder.img.setTag(imgUrl);  
         // 預(yù)設(shè)一個圖片  
         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會導(dǎo)致listview控件顯示不全,通常只會顯示一條方面,這是由于兩個控件的滑動沖突導(dǎo)致的放钦,所以:
      • 需要通過listview的item數(shù)量去計(jì)算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就只有一點(diǎn)。
          
          listView.setLayoutParams(params);
          }
          
          //而現(xiàn)階段最好的方法就是自定義listview横腿,重寫OnMeasure( )方法颓屑,使其完整顯示。
          
          public class ScrollViewWithListView extends ListView {
          public ScrollViewWithListView(android.content.Context context,
          android.util.AttributeSet attrs) {
          super(context, attrs);
          }
          /**
          * Integer.MAX_VALUE >> 2,如果不設(shè)置耿焊,系統(tǒng)默認(rèn)設(shè)置是顯示兩條
          */
          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的單個數(shù)據(jù)揪惦,不刷新整個listview的數(shù)據(jù)?

    • 修改單個item的數(shù)據(jù)罗侯,然后調(diào)用adapter的notifyDataSetChanged()方法進(jìn)行刷新器腋。或者直接用handler去更新,在adapter中創(chuàng)建一個handler纫塌,值發(fā)生改變的時候诊县,handler就send一個message,更新ui措左。

recyclerView:

  1. 使用recycleView的好處依痊;

    • recycleView是Android 5.0 materials design 中的組件之一,recycleView封裝了viewHolder的回收復(fù)用機(jī)制媳荒,也就是說recycleView標(biāo)準(zhǔn)化了viewHolder抗悍,編寫Adapter面向的是viewHolder而不再是view了,復(fù)用的邏輯被封裝了钳枕,寫起來更方便了缴渊。recycleView提供了一種插拔式的體驗(yàn),高度的解耦鱼炒,異常的靈活衔沼,針對一個Item的顯示RecylerView專門抽取出了相應(yīng)的類,來控制Item的顯示昔瞧,使其的擴(kuò)展性非常強(qiáng)指蚁。例如:你想控制橫向或者縱向滑動列表效果可以通過LinearLayoutManager這個類來進(jìn)行控制(與GridView效果對應(yīng)的是GridLayoutManager,與瀑布流對應(yīng)的還有StaggeredGridLayoutManager等),也就是說RecylerView不再拘泥于ListView的線性展示方式自晰,它也可以實(shí)現(xiàn)GridView的效果等多種效果凝化。你想控制Item的分隔線,可以通過繼承RecylerView的ItemDecoration這個類酬荞,然后針對自己的業(yè)務(wù)需求去抒寫代碼搓劫。
      可以控制Item增刪的動畫,可以通過ItemAnimator這個類進(jìn)行控制混巧,當(dāng)然針對增刪的動畫枪向,RecylerView有其自己默認(rèn)的實(shí)現(xiàn)。
  2. recycleView的使用方法:

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

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

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

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

socket通信與網(wǎng)絡(luò)編程(TCP/UDP協(xié)議被辑,http協(xié)議)

  1. 什么是網(wǎng)絡(luò)編程:

    • 網(wǎng)絡(luò)編程是指兩臺設(shè)備之間實(shí)現(xiàn)數(shù)據(jù)傳遞的過程燎悍,也可以說是使用套接字完成不同進(jìn)程之間的網(wǎng)絡(luò)通訊的編程。要了解網(wǎng)絡(luò)編程盼理,需要先了解網(wǎng)絡(luò)通訊谈山,網(wǎng)絡(luò)通訊分HTTP通訊和socket網(wǎng)絡(luò)通訊,說到這需要先了解一下網(wǎng)絡(luò)通訊的層級宏怔,網(wǎng)絡(luò)通訊的層級一共有四層:最低層鏈路層奏路,這里主要是硬件的接口,然后是網(wǎng)絡(luò)層臊诊,這里用我們比較熟悉的IP協(xié)議鸽粉,在然后是傳輸層,這里有TCP協(xié)議和UDP協(xié)議抓艳,最后就是應(yīng)用層触机,HTTP協(xié)議(超文本傳輸協(xié)議)就在這一層,這里需要注意的是玷或,HTTP是一種協(xié)議儡首,而socket是一個接口。
  2. 傳輸層兩大協(xié)議:TCP/UDP協(xié)議:

    • UDP協(xié)議是一種用戶數(shù)據(jù)報(bào)協(xié)議偏友,是面向無連接的蔬胯,數(shù)據(jù)傳輸不可靠的一種點(diǎn)對多點(diǎn)的通訊,也就是說UDP在傳輸數(shù)據(jù)前是不與對方建立連接的位他,對于接收到的數(shù)據(jù)也是不發(fā)送確認(rèn)信號的氛濒,發(fā)送數(shù)據(jù)的一方也不會知道數(shù)據(jù)是否發(fā)送成功棱诱,也就無法再重新發(fā)送了泼橘。我們經(jīng)常使用的“ping”命令來檢測兩臺設(shè)備主機(jī)之間的TCP/IP通信是否正常,而這個“ping”就是 使用UDP協(xié)議迈勋,通過向?qū)Ψ街鳈C(jī)發(fā)送UDP數(shù)據(jù)包炬灭,然后對方確認(rèn)收到數(shù)據(jù)包,如果對方將數(shù)據(jù)包到達(dá)的纖細(xì)及時的返回回來靡菇,就說明兩臺設(shè)備主機(jī)之間的通訊是通的重归。
    • TCP協(xié)議是一種傳輸控制協(xié)議,它是面向有連接的厦凤,數(shù)據(jù)傳輸可靠的一種通訊方式鼻吮,它是通過三次握手來實(shí)現(xiàn)面向有連接的,而這三次握手指的是:
  1. 首先客戶端發(fā)送一個空的數(shù)據(jù)報(bào)包給服務(wù)端较鼓,并且將客戶端置為發(fā)送狀態(tài)椎木;
  2. 接著服務(wù)端接收到這這個空的數(shù)據(jù)報(bào)包违柏,會相應(yīng)客戶端一個確認(rèn)包,并將服務(wù)端置為接收狀態(tài)香椎;
    3)客戶端接收到服務(wù)端發(fā)送回來的響應(yīng)漱竖,然后再向服務(wù)端發(fā)送一個確認(rèn)包,一旦此包發(fā)送完畢畜伐,那么服務(wù)端就與客戶端之間建立了長連接馍惹,并且雙方都處于確認(rèn)狀態(tài),而建立的這個長連接在理論上如果單方不主動去停止這個連接玛界,這個連接就會一直存在万矾,只要連接存在,服務(wù)器就可以和客戶端近行數(shù)據(jù)的互傳慎框。
  1. 什么是socket通信:

    • 說起socket良狈,得要先知道套接字,套接字是TCP/IP網(wǎng)絡(luò)通信的基本操作單元鲤脏,主要包括三大要素:IP们颜,協(xié)議,端口猎醇。在說socket窥突,socket其實(shí)就是一堆套接字,它在客戶端叫clientSocket硫嘶,在服務(wù)端叫serviceSocket,socket其實(shí)就是方便TCP和UDP編程的一個接口阻问,應(yīng)用層和傳輸層通過socket接口,區(qū)分來自不同的應(yīng)用進(jìn)程和網(wǎng)絡(luò)連接的通信沦疾,實(shí)現(xiàn)數(shù)據(jù)傳輸?shù)牟l(fā)服務(wù)称近。(應(yīng)用層在通過傳輸層傳輸?shù)臅r候,傳輸層的TCP會同時遇到為多個應(yīng)用進(jìn)程提供并發(fā)服務(wù)的問題哮塞,多個TCP連接或多個應(yīng)用進(jìn)程可能需要同一個TCP連接刨秆,為了區(qū)別不同應(yīng)用進(jìn)程的連接,許多計(jì)算機(jī)為應(yīng)用進(jìn)程提供了套接字接口)
    • socket建立連接:socket是一個接口忆畅,它是可以指定傳輸層協(xié)議的衡未,也就是說當(dāng)他在指定TCP協(xié)議的時候建立的socket連接就是一個TCP連接,需要通過三次握手才能進(jìn)行連接家凯。從廣義上講:socket連接可以這樣講:
      • 服務(wù)器監(jiān)聽:說的是服務(wù)器套接字并不指定客戶端套接字缓醋,它處于一個實(shí)時監(jiān)聽網(wǎng)絡(luò)狀態(tài),等待客戶端的請求绊诲,連接送粱。
      • 客戶端發(fā)送請求:客戶端套接字在請求中聲明套接字的描述和服務(wù)端的ip和端口號,然后向服務(wù)端套接字發(fā)送請求掂之。
      • 連接確認(rèn):服務(wù)端套接字接收到客戶端套接字發(fā)送來的請求后抗俄,想客戶端套接字發(fā)送一個確認(rèn)響應(yīng)脆丁,并在這個響應(yīng)中添加服務(wù)器套接字的描述,一旦客戶端確認(rèn)了這個描述橄镜,那么雙方就正式的建立了連接偎快,而測試服務(wù)器處于一個監(jiān)聽狀態(tài),等待著其他客戶端套接字發(fā)送來的請求洽胶。
  1. socket接口是如何利用代碼實(shí)現(xiàn)TCP連接和UDP連接的;

    • 代碼實(shí)現(xiàn)TCP連接:首先在客戶端創(chuàng)建socket對象裆馒,然后創(chuàng)建inputStream封裝要傳輸?shù)臄?shù)據(jù)姊氓,然后在socket中通過getOutputStream獲取輸出流,然后通過寫出io流的形式將數(shù)據(jù)寫入到服務(wù)器當(dāng)中去喷好。在服務(wù)器中創(chuàng)建serviceSocket對象翔横,然后通過serviceSocket對象中的accept方法獲取socket對象,最后在socket對象中通過getInputStream方法獲取數(shù)據(jù)梗搅。
    • 代碼實(shí)現(xiàn)UDP連接: 首先在客戶端創(chuàng)建DatagramSocket對象,然后創(chuàng)建DatagramPacket對象(他其實(shí)就是報(bào)包),這個對象創(chuàng)建的時候會需要傳入四個參數(shù),
      DatagramPacket p = new DatagramPacket(messageByte, msg_length, url, server_port);
      第一個參數(shù)為傳遞的數(shù)據(jù)data(不過是個字節(jié)數(shù)組,而且不能超過64k),第二個參數(shù)是數(shù)據(jù)的長度,第三個參數(shù)是網(wǎng)絡(luò)地址(可以通過inetAddress.getByName這個方法傳入一個ip就可以獲得網(wǎng)絡(luò)地址了),第四個參數(shù)是端口號禾唁。 然后socket對象.send(packet對象)發(fā)送報(bào)包就可以了。服務(wù)器端創(chuàng)建DatagramSocket對象,創(chuàng)建兩個參數(shù)的DatagramPacket的空報(bào)包對象(只是創(chuàng)建一個字節(jié)數(shù)組),然后調(diào)用socket對象.receive(packet)來接受數(shù)據(jù),最后調(diào)用packet.getData即可.
  2. HTTP通訊:

    • http協(xié)議:超文本傳輸協(xié)議无切,手機(jī)常用協(xié)議之一荡短,是基于TCP協(xié)議之上的應(yīng)用層協(xié)議。http1.0的時候是一個請求一個連接哆键,請求結(jié)束后就會斷開連接掘托。http1.1的時候是已連接對應(yīng)多個請求,多個請求可以重接執(zhí)行籍嘹,不用等一個請求結(jié)束在進(jìn)行下一個請求闪盔,而http2.0同樣是一個連接對應(yīng)多個請求,并且在應(yīng)用層和傳輸層增加了一個二進(jìn)制的分幀層辱士,這些幀對應(yīng)邏輯流中的消息泪掀,并行的在同一個TCP連接上進(jìn)行雙向交流消息。
  3. socket和http的區(qū)別;

    • 形象的說http他就像一個轎車,提供了封裝或者顯示數(shù)據(jù)的具體形式,而socket是發(fā)動機(jī),提供了網(wǎng)絡(luò)通訊的能力,http他是一個協(xié)議,是基于TCP協(xié)議的,Tcp協(xié)議是基于ip協(xié)議的,而socket提供了針對TCP和UDP編程的接口颂碘。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末异赫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子凭涂,更是在濱河造成了極大的恐慌祝辣,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件切油,死亡現(xiàn)場離奇詭異蝙斜,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)澎胡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門剥纷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來隅俘,“玉大人典蜕,你說我怎么就攤上這事⊥溆瑁” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵个曙,是天一觀的道長锈嫩。 經(jīng)常有香客問我,道長垦搬,這世上最難降的妖魔是什么呼寸? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮猴贰,結(jié)果婚禮上对雪,老公的妹妹穿的比我還像新娘。我一直安慰自己米绕,他們只是感情好瑟捣,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著栅干,像睡著了一般迈套。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上非驮,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天交汤,我揣著相機(jī)與錄音,去河邊找鬼劫笙。 笑死芙扎,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的填大。 我是一名探鬼主播戒洼,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼允华!你這毒婦竟也來了圈浇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤靴寂,失蹤者是張志新(化名)和其女友劉穎磷蜀,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體百炬,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡褐隆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了剖踊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片庶弃。...
    茶點(diǎn)故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡衫贬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出歇攻,到底是詐尸還是另有隱情固惯,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布缴守,位于F島的核電站葬毫,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏屡穗。R本人自食惡果不足惜供常,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸡捐。 院中可真熱鬧,春花似錦麻裁、人聲如沸箍镜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽色迂。三九已至,卻和暖如春手销,著一層夾襖步出監(jiān)牢的瞬間歇僧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工锋拖, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留诈悍,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓兽埃,卻偏偏與公主長得像侥钳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子柄错,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,517評論 25 707
  • (一)Android面試題(一)Activity舷夺、Intent Android四大組件分別是哪些?各自有什么作用和...
    Itachi001閱讀 4,427評論 4 95
  • 整理一些常見的Android面試題(針對于2~3年開發(fā)經(jīng)驗(yàn)中所遇到的問題) synchronized鎖靜態(tài)方法和非...
    appzy閱讀 2,271評論 4 18
  • 這件事情是我錯了 您說的這些話 確實(shí)是對我的耳提面命 我也知道你您很擔(dān)心我 可是 我還是很難受 這是否是您對我的不...
    一六零六零六閱讀 230評論 0 0
  • “道”是以老子售貌、莊子為代表的道家思想派別的核心给猾。道家崇尚自然,主張?zhí)竦瓱o為颂跨、頤養(yǎng)天年敢伸,其思想中的“精、氣毫捣、神”等與...
    Archita閱讀 484評論 0 0