這些有些來源於網站、有些來源於本身的思考。可能有些問題網上有、可能有些問題對應的答案也有,有可能有些問題講的不對,能指正的但願你們不吝指教。java
Activityandroid
什麼是Activity面試
四大組件之一,一個和用戶交的互界面就是一個activity,是全部 View 的容器算法
Activity 生命週期sql
生命週期描述的是一個類 從建立(new出來)到死亡(垃圾回收)的過程當中會執行的方法.數據庫
在這個過程當中會針對不一樣的生命階段會調用不一樣的方法緩存
Activity從建立到銷燬有多種狀態,從一種狀態到另外一種狀態時會激發相應的回調方法,這些回調方法包括:安全
其實這些方法都是兩兩對應的,onCreate建立與onDestroy銷燬;onStart可見與onStop不可見;onResume可編輯(即焦點)與onPause;服務器
還有一個onRestart方法了,在Activity被onStop後,可是沒有被onDestroy,在再次啓動此Activity時就調用onRestart(而再也不調用onCreate)方法;若是被onDestroy了,則是調用onCreate方法。微信
兩個Activity之間跳轉時必然會執行的是哪幾個方法。
通常狀況好比說有兩個activity,分別叫A,B ,當在A裏面激活B組件的時候, A 會調用 onPause()方法,而後B 調用onCreate() ,onStart(), OnResume() ,這個時候B覆蓋了窗體, A會調用onStop()方法. 若是B呢 是個透明的,或者是對話框的樣式, 就不會調用onStop()方法。
所以,咱們在兩個activities中傳遞數據,或者共享資源時(如數據庫鏈接),須要在前一個activity的onPause()方法而不是onStop()方法中進行
橫豎屏切換時候Activity的生命週期。
這個生命週期跟清單文件裏的配置有關係
一、不設置Activity的android:configChanges時,切屏會從新調用各個生命週期,默認首先銷燬當前activity,而後從新加載
二、設置Activity的android:configChanges="orientation|keyboardHidden|screenSize"時,切屏不會從新調用各個生命週期,只會執行onConfigurationChanged方法,遊戲開發中, 屏幕的朝向都是寫死的.
如何將一個Activity設置成窗口的樣式。
能夠自定義一個activity的樣式
android:theme="@android:style/Theme.Dialog"
你後臺的Activity被系統 回收怎麼辦?若是後臺的Activity因爲某緣由被系統回收了,如何在被系統回收以前保存當前狀態?
除了在棧頂的activity,其餘的activity都有可能在內存不足的時候被系統回收,一個activity越處於棧底,被回收的可能性越大.若是有多個後臺進程,在選擇殺死的目標時,採用最近最少使用算法(LRU)。
Activity中提供了一個 onSaveInstanceState()回調方法,這個方法會保證必定在活動被回收以前調用, 能夠經過這個方法來解決活動被回收時臨時數據得不到保存的問題。onSaveInstanceState()方法會攜帶一個 Bundle類型的參數,Bundle提供了一系列的方法用於保存數據,好比可使用 putString()方法保存字符串,使用 putInt()方法保存整型數據。每一個保存方法須要傳入兩個參數,第一個參數是鍵,用於後面從 Bundle中取值,第二個參數是真正要保存的內容。在 MainActivity中添加以下代碼就能夠將臨時數據進行保存:
protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); String tempData = "Something you just typed"; outState.putString("data_key", tempData); }
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState != null) { String tempData = savedInstanceState.getString("data_key"); }
也能夠經過onRestoreInstanceState來存儲和恢復數據,區別是不須要判斷空了,onRestoreInstanceState調用必定是有值的
Activity的 onSaveInstanceState() 和 onRestoreInstanceState()並非生命週期方法,它們不一樣於 onCreate()、onPause()等生命週期方法,它們並不必定會被觸發。當應用遇到意外狀況(如:內存不足、用戶直接按Home鍵)由系統銷燬一個Activity,onSaveInstanceState() 會被調用。可是當用戶主動去銷燬一個Activity時,例如在應用中按返回鍵,onSaveInstanceState()就不會被調用。除非該activity是被用戶主動銷燬的,一般onSaveInstanceState()只適合用於保存一些臨時性的狀態,而onPause()適合用於數據的持久化保存。
系統不知道你按下HOME後要運行多少其餘的程序,天然也不知道activity A是否會被銷燬,所以系統都會調用onSaveInstanceState(),讓用戶有機會保存某些非永久性的數據。如下幾種狀況的分析都遵循該原則
如何退出Activity?
退出activity 直接調用 finish () 方法
用戶點擊back鍵 就是退出一個activity ,退出activity 會執行 onDestroy()方法 。
一、拋異常強制退出:
該方法經過拋異常,使程序Force Close。不推薦使用
驗證能夠,可是,須要解決的問題是,如何使程序結束掉,而不彈出Force Close的窗口。
安全結束進程 android.os.Process.killProcess(android.os.Process.myPid());
二、記錄打開的Activity:
每打開一個Activity,就用集合記錄下來。在須要退出時,關閉每個Activity便可。
能夠寫在Application裏,直接getApplication.list.add,在須要退出時遍歷集合裏的Activity,finish掉
也能夠定義一個baseactivity裏面進行操做,記得通常不用的話最後都須要把list=null
三、發送特定廣播:
//在baseactivity裏註冊廣播
registerReceiver(receiver, filter)
//想退出的時候就在onRecriver方法裏finish()。
四、能夠經過 intent的flag 來實現.. intent.setFlag(FLAG_ACTIVITY_CLEAR_TOP)激活一個新的activity,而後在新的activity的oncreate方法裏面就能夠finish掉.
講一講你對activity的理解
把上面的幾點用本身的心得寫出來
兩個Activity之間怎麼傳遞數據?
//把數據封裝至intent對象中
startActivity(intent);
怎麼讓在啓動一個Activity是就啓動一個service?
在activity的onCreate()方法裏面 startService();
如何返回數據
基本流程:
獨的任務棧) ,不能被摧毀(執行不到 finish 方法) ,父 Activity 中的 onActivityResult 方法將不會執行;
請描述一下Intent 和 Intent Filter。
Android 中經過 Intent 對象來表示一條消息,一個 Intent 對象不只包含有這個消息的目的地,還能夠包含消息的內容,這比如一封 Email,其中不只應該包含收件地址,還能夠包含具體的內容。對於一個 Intent 對象,消息「目的地」是必須的,而內容則是可選項。
經過Intent 能夠實現各類系統組件的調用與激活.
Intent filter:是傳遞的信息,這些信息不是必須的,有:
Action: 動做 view
Data: 數據uri uri
Category : 而外的附加信息
<intent-filter > <action android:name="com.itheima.second"/> <data android:scheme="asd" android:mimeType="aa/bb"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> Intent intent = new Intent("com.example.activitytest.ACTION_START");
PendingIntent和Intent區別
它們均可以去指明某一個「意圖」,均可以用於啓動活動、啓動服務以及發送廣播等。不一樣的是,Intent更加傾向於去當即執行某個動做,而 PendingIntent更加傾向於在某個合適的時機去執行某個動做。因此,也能夠把 PendingIntent簡單地理解爲延遲執行的 Intent。
PendingIntent的用法一樣很簡單,它主要提供了幾個靜態方法用於獲取 PendingIntent的實例,能夠根據需求來選擇是使用 getActivity()方法、getBroadcast()方法、仍是 getService()方法。
每8小時開啓廣播
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE); int anHour = 8 * 60 * 60 * 1000; // 這是8小時的毫秒數 long triggerAtTime = SystemClock.elapsedRealtime() + anHour; Intent i = new Intent(this, AutoUpdateReceiver.class); PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0); manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
Intent傳遞數據和Bundle傳遞數據是一回事,
Intent傳遞時內部仍是調用了Bundle。
如下爲源碼:
public Intent putExtra(String name, boolean value) { if (mExtras == null) { mExtras = new Bundle(); } mExtras.putBoolean(name, value); return this; }
啓動一個Activity有哪幾種方法
startActivity
startActivityforresult
launcher的activity
widget
同一個程序,但不一樣的Activity是否能夠放在不一樣的Task任務棧中?
啓動模式裏有個Singleinstance,能夠運行在另外的單獨的任務棧裏面。用這個模式啓動的activity,在內存中只有一份,這樣就不會重複的開啓。
也能夠在激活一個新的activity時候, 給intent設置flag,Intent的flag添加FLAG_ACTIVITY_NEW_TASK,這個被激活的activity就會在新的task棧裏面
Android中Task任務棧的分配。
1)任務棧的概念
問:一個手機裏面有多少個任務棧?
答:通常狀況下,有多少個應用正在運行,就對應開啓多少個任務棧;每開啓一個應用程序就會建立一個與之對應的任務棧;
棧:後進先出,最早進棧,就會最後出棧。Activity的啓動模式就是修改任務棧的排列狀況
2)任務棧的做用:
它是存放 Activity 的引用的,Activity不一樣的啓動模式,對應不一樣的任務棧的存放;
可經過 getTaskId()來獲取任務棧的 ID,若是前面的任務棧已經清空,新開的任務棧 ID+1,是自動增加的;
首先來看下Task的定義,Google是這樣定義Task的:Task其實是一個Activity棧,一般用戶感覺的一個Application就是一個Task。從這個定義來看,Task跟Service或者其餘Components是沒有任何聯繫的,它只是針對Activity而言的。
Activity的啓動模式
Android下的進程
進程是被系統建立的,當內存不足的時候,又會被系統回收
內存管理:Android 系統在運行多個進程時,若是系統資源不足,會強制結束一些進程,優先選擇哪一個進程來結束是有優先級的。
會按照如下順序殺死(進程級別):
①、空: 進程中沒有任何組件(無組件啓動,作進程緩存使用,恢復速度快),任務棧清空,意味着程序退出了,但進程留着,這個就是空進程,容易被系統回收;
②、後臺:進程中只有中止狀態(onStop)的 Activity;
③、服務:進程中有正在運行的服務;
④、可見:進程中有一個暫停狀態(onPause)的 Activity;
⑤、前臺:進程中正在運行一個 Activity;
Activity 在退出的時候進程不會銷燬, 會保留一個空進程方便之後啓動. 但在內存不足時進程會被銷燬;
Activity 中不要在 Activity 作耗時的操做, 由於 Activity 切換到後臺以後(Activity 中止了), 內存不足時, 也容易被銷毀;
Service
什麼是Service以及描述下它的生命週期。Service有哪些啓動方法,有什麼區別,怎樣停用Service?
在Service的生命週期中,被回調的方法比Activity少一些,只有onCreate, onStartCommand, onDestroy,onBind和onUnbind。
一般有兩種方式啓動一個Service,他們對Service生命週期的影響是不同的。
1 經過startService
Service會經歷 onCreate 到onStartCommand,而後處於運行狀態,stopService的時候調用onDestroy方法。
若是是調用者本身直接退出而沒有調用stopService的話,Service會一直在後臺運行。
2 經過bindService
Service會運行onCreate,而後是調用onBind, 這個時候調用者和Service綁定在一塊兒。調用者退出了,Srevice就會調用onUnbind->onDestroyed方法。所謂綁定在一塊兒就共存亡了。調用者也能夠經過調用unbindService方法來中止服務,這時候Srevice就會調用onUnbind->onDestroyed方法。
3.當調用了startService()方法後,又去調用 stopService()方法,這時服務中的 onDestroy()方法就會執行,表示服務已經銷燬了。相似地,當調用了 bindService()方法後,又去調用unbindService()方法,onDestroy()方法也會執行,這兩種狀況都很好理解。可是須要注意,咱們是徹底有可能對一個服務既調用了startService()方法,又調用了bindService()方法的,這種狀況下該如何才能讓服務銷燬掉呢?根據Android系統的機制,一個服務只要被啓動或者被綁定了以後,就會一直處於運行狀態,必需要讓以上兩種條件同時不知足,服務才能被銷燬。因此,這種狀況下要同時調用stopService()和unbindService()方法,onDestroy()方法纔會執行這樣就把服務的生命週期完整地走了一遍。
start –> bind -> unbind -> stop 常用服務長期後臺運行,又能夠調用服務中的方法
service如何殺不死?
1.onStartCommand方法,返回START_STICKY(粘性)當service因內存不足被kill,當內存又有的時候,service又被從新建立
2.設置優先級,在服務裏的ondestory裏發送廣播 在廣播裏再次開啓這個服務,雙進程守護
service是否在main thread中執行, service裏面是否能執行耗時的操做?
默認狀況,若是沒有顯示的指定service所運行的進程, Service和Activity是運行在當前app所在進程的main thread(UI主線程)裏面
service裏面不能執行耗時的操做(網絡請求,拷貝數據庫,大文件 ),須要在子線程中執行 new Thread(){}.start();
service裏面能夠彈土司嗎
service裏面彈toast須要添加到主線程裏執行
@Override public void onCreate(){ handler = new Handler(Looper.getMainLooper()); System.out.println("service started"); handler.post(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), "Test",Toast.LENGTH_SHORT).show(); }); }
Activity怎麼和service綁定,怎麼在activity中啓動本身對應的service?
startService() 一旦被建立 調用着無關,無法使用service裏面的方法
bindService () 把service 與調用者綁定 ,若是調用者被銷燬, service會銷燬,可使用service 裏面的方法
方法一:
方法二
經過BroadCast(廣播)的形式
當咱們的進度發生變化的時候咱們發送一條廣播,而後在Activity的註冊廣播接收器,接收到廣播以後更新視圖
什麼是IntentService?有何優勢?
普通的service ,默認運行在ui main 主線程,Sdk給咱們提供的方便的,帶有異步處理的service類
OnHandleIntent() 處理耗時的操做,不須要開啓子線程,這個方法已經在子線程中運行了
Intentservice若未執行完成上一次的任務,將不會新開一個線程,是等待以前的任務完成後,再執行新的任務,等任務完成後再次調用stopService()
startForeground(id, notification)
擁有service的進程具備較高的優先級。當內存不足時,擁有service的進程具備較高的優先級。
1. 若是service正在調用onCreate, onStartCommand或者onDestory方法,那麼用於當前service的進程至關於前臺進程以免被killed。
2. 若是當前service已經被啓動(start),擁有它的進程則比那些用戶可見的進程優先級低一些,可是比那些不可見的進程更重要,這就意味着service通常不會被killed.
3. 若是客戶端已經鏈接到service (bindService),那麼擁有Service的進程則擁有最高的優先級,能夠認爲service是可見的。
4. 若是service可使用startForeground(int, Notification)方法來將service設置爲前臺狀態,那麼系統就認爲是對用戶可見的,並不會在內存不足時killed。
何時使用Service?
若是有其餘的應用組件做爲Service,Activity等運行在相同的進程中,那麼將會增長該進程的重要性。
1.Service的特色可讓他在後臺一直運行,能夠在service裏面建立線程去完成耗時的操做.
2.Broadcast receiver捕獲到一個事件以後,能夠起一個service來完成一個耗時的操做.
廣播
請描述一下Broadcast Receiver。
Android中:系統在運行過程當中,會產生會多事件,那麼某些事件產生時,好比:電量改變、收發短信、撥打電話、屏幕解鎖、開機,系統會發送廣播,只要應用程序接收到這條廣播,就知道系統發生了相應的事件,從而執行相應的代碼。使用廣播接收者,就能夠收聽廣播
廣播分兩種:有序廣播、無序廣播
無序廣播:無序廣播不可中斷,不能互相傳遞數據;
有序廣播:一個接一個的傳遞,廣播可中斷,經過調用 abortBroadcast()方法;接收者之間能夠傳遞數據(intent);
無序廣播(標準廣播)
有序廣播
<intent-filter android:priority="100" > <action android:name="com.example.broadcasttest.MY_BROADCAST"/> </intent-filter>
如何註冊廣播
public class MainActivity extends Activity { private IntentFilter intentFilter; private NetworkChangeReceiver networkChangeReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); intentFilter = new IntentFilter(); intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); networkChangeReceiver = new NetworkChangeReceiver(); registerReceiver(networkChangeReceiver, intentFilter); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(networkChangeReceiver); } class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "network changes",Toast.LENGTH_SHORT).show(); } } }
四大組件其中比較特殊的是廣播接收者,能夠不在清單文件中配置,能夠經過代碼進行註冊。其餘組件所有在清單文件中註冊
Intent intent = new Intent("my-sensitive-event"); intent.putExtra("event", "this is a test event"); LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
廣播的生命週期
a. 廣播接收者的生命週期很是短暫的,在接收到廣播的時候建立,onReceive()方法結束以後銷燬;
b. 廣播接收者中不要作一些耗時的工做,不然會彈出 Application No Response錯誤對話框;
c. 最好也不要在廣播接收者中建立子線程作耗時的工做,由於廣播接收者被銷燬後進程就成爲了空進程,很容易被系統殺掉;
d. 耗時的較長的工做最好放在服務中完成;
內容提供者
請介紹下ContentProvider是如何實現數據共享的。
是四大組件之一,內容提供者的做用:把私有數據暴露給其餘應用,一般,是把私有數據庫的數據暴露給其餘應用
在清單文件中定義內容提供者的標籤,注意必需要有authorities屬性,這是內容提供者的主機名,功能相似地址
<provider android:name="com.itheima.contentprovider.PersonProvider" android:authorities="com.itheima.person" android:exported="true" ></provider>
把本身的數據經過uri的形式共享出去,android 系統下不一樣程序,數據默認是不能共享訪問
須要去實現一個類去繼承ContentProvider
爲何要用ContentProvider?它和sql的實現上有什麼差異?
屏蔽數據存儲的細節,對用戶透明,用戶只須要關心操做數據的uri就能夠了
不一樣app之間共享,操做數據
Sql也有增刪改查的方法.
可是contentprovider 還能夠去增刪改查本地文件. xml文件的讀取,更改,網絡數據讀取更改
請介紹下Android的數據存儲方式
1.文件儲存,在內部文件和SD卡
getCacheDir(),在data/data/包名/cache
getFilesDir(),在data/data/包名/files
SD卡:首先通過File file = new File(Environment.getExternalStorageDirectory(), "info.txt"),而後經過io存儲
2.SharedPreference
3.SQLite數據庫:
當應用程序須要處理的數據量比較大時,爲了更加合理地存儲、管理、查詢數據,每每使用關係數據庫來存儲數據。Android系統的不少用戶數據,如聯繫人信息,通話記錄,短信息等,都是存儲在SQLite數據庫當中的,因此利用操做SQLite數據庫的API能夠一樣方便的訪問和修改這些數據。
4.ContentProvider:
主要用於在不一樣的應用程序之間實現數據共享的功能,不一樣於sharepreference和文件存儲中的兩種全局可讀寫操做模式,內容提供其能夠選擇只對哪一部分數據進行共享,從而保證咱們程序中的隱私數據不會有泄漏的風險
Fragment
簡單說說Fragment?
用途:在一個Activity裏切換界面,切換界面時只切換Fragment裏面的內容
生命週期方法跟Activity一致,能夠理解把其爲就是一個Activity,與Activity同存亡,Activity的XX方法調用,Fragment的XX方法就調用
他們是怎麼進行傳遞數據的?
活動傳遞給Fragment:爲了方便碎片和活動之間進行通訊, FragmentManager提供了一個相似於findViewById()的方法,專門用於從佈局文件中獲取碎片的實例,前提是本身在佈局文件中定義fragment這個標籤,代碼以下所示:
RightFragment rightFragment = (RightFragment) getFragmentManager() .findFragmentById(R.id.right_fragment);
調用 FragmentManager的 findFragmentById()方法,能夠在活動中獲得相應碎片的實例,而後就能輕鬆地調用碎片裏的方法了。還有findViewByTag,在replace 的時候設置tag
或者在fragment裏聲明接口,而後activity得到fragment對象調用接口裏的方法
fragment數據傳遞給活動,直接getActivity就能夠調用活動裏的方法了
activity給fragment傳遞數據通常不經過fragment的構造方法來傳遞,會經過setArguments來傳遞,由於當橫豎屏會調用fragment的空參構造函數,數據丟失。
fragment和fragment數據傳遞
首先在一個fragment能夠獲得與它相關聯的活動,而後再經過這個活動去獲取另一個fragment的實例,這樣也就實現了不一樣fragment之間的通訊功能
FragmentManager , add 和 replace 有什麼區別?
Fragment和view的區別
Fragment能夠有效的對 view進行管理(增刪和替換)並且結構更加清晰,有模塊化的實現思想。
用view 不少邏輯代碼可能都須要寫在Activity裏,若是view不少, 耦合度會很高。用Fragment則能夠各自管理,起了解耦的做用。
通常軟件簡單的話直接view,複雜的用Fragment。
viewpager是一個滑動切換的控件,Fragment是一個輕量級的Activity,這個Fragment能夠放到這個Viewpager裏面去運行。
例如QQ或微信那樣,能夠來回切換不一樣的選項卡,即切換了不一樣的Fragment。一般Viewpager 會放fargment或者view
Fragment和Activity的區別
由於如今的手機屏幕都比較大了,Activity會把內容拉的很長,用Fragment的話能夠左側是列表,右側是內容。在一個Activity裏切換界面,切換界面時只切換Fragment裏面的內容。Fragment一般用來做爲一個activity界面的一部分。
請介紹下Android中經常使用的五種佈局。
FrameLayout(幀佈局),LinearLayout (線性佈局),AbsoluteLayout(絕對佈局),RelativeLayout(相對佈局),TableLayout(表格佈局)
TextView 、ImageView ,Button,ImageButton他們之間的聯繫和區別
ImageView 控件負責顯示圖片,其圖片來源既能夠是資源文件的id,也能夠是Drawable對象或 Bitmap 對象,還能夠是 內容提供者(Content Provider)的Uri.
ImageButton 控件 繼承自 ImageView。與Button相同之處:都用於響應按鈕的點擊事件
不一樣之處:ImageButton只能顯示圖片;Button用於顯示文字
屏幕適配
RelativeLayout和FrameLayout的區別
Padding和Margin有什麼區別?
Padding 是控件內容的距離margin是控件和控件間的距離
Listview如何顯示不一樣條目?
第一種:在getview方法里根據position 進行判斷,好比,position等於0是,顯示標題,不然顯示數據,固然相應的setOnItemClickListener也要去判斷
第二種:根據listview裏的getItemViewType,getViewTypeCount方法顯示不一樣條目
/** 根據位置 判斷當前條目是什麼類型 */ @Override public int getItemViewType(int position) { //20 if (position == datas.size()) { // 當前是最後一個條目 return MORE_ITEM; } return getInnerItemViewType(position); // 若是不是最後一個條目 返回默認類型 } private int getInnerItemViewType(int position) { return DEFAULT_ITEM; } /** 當前ListView 有幾種不一樣的條目類型 */ @Override public int getViewTypeCount() { return super.getViewTypeCount() + 1; // 2 有兩種不一樣的類型 }
ScrowView 使用的注意
在不一樣的屏幕上顯示內容不一樣的狀況,其實這個問題咱們每每是用滾動視圖來解決的,也就是 ScrowView,
須要注意的是 ScrowView 中使用 layout_weight 是無效的,既然使用 ScrowView 了,就把它裏面的控件的大小都設成固定的吧。
Android UI中的View如何刷新
在主線程中 拿到view調用Invalide()方法,在子線程裏面能夠經過postInvalide()方法;
invalidate();//主線程,刷新當前視圖 致使 執行onDraw執行
postInvalidate();//子線程
什麼是ANR(異步加載) 如何避免它?
android在主線程是不能加載網絡數據或圖片、數據庫查詢、複雜業務邏輯處理以及費時任務操做,由於Android的UI操做並非線程安全的,而且全部涉及UI的操做必須在UI線程中完成。Android應用在5s內無響應的話會致使ANR(Application Not Response),這就要求開發者必須遵循兩條法則:一、不能阻塞UI線程,二、確保只在UI線程中訪問Android UI工具包。
Activity 5秒 broadcast10秒,服務20秒,耗時的操做在主thread裏面完成
解決辦法:Thread + Handler + Message ,Thread + Handler + post,AsyncTask,intentservice
runOnUiThread(Runnable)在子線程中直接使用該方法,能夠更新UI
實現側邊欄、和指示器效果、頁面滑動有幾種方式
側邊欄:自定義、slidingmenu、DrawerLayout 、SlidingDrawer
指示器效果:自定義、viewpager裏面的PagerTabStrip、ActionBar Tab標籤、viewpagerindicate、FragmentTabHost、TabActivity、radiobutton
頁面滑動:自定義、viewpager、手勢識別器,其實就是onTouchEvent提供的簡單工具類,onTouchEvent將觸摸事件委託給了手勢識別器
Gradle中buildToolsVersion和TargetSdkVersion的區別是什麼
compileSdkVersion, minSdkVersion 和 targetSdkVersion 的做用:他們分別控制可使用哪些 API ,要求的 API 級別是什麼,以及應用的兼容模式。TargetSdkVersion 設爲23那麼是按6.0設置的(運行時權限),小於23是按6.0之前的方式(安裝時默認得到權限,且用戶沒法在安裝App以後取消權限)
進程間怎麼通訊
binder是安卓中的一個類,它實現了IBinder接口,是安卓中跨進程通訊的方式。當綁定服務的時候會返回一個binder對象,而後經過他進行多進程間的通訊。
其實進程間通訊就是爲了實現數據共享。一個程序不一樣組件在不一樣進程也叫多進程,和倆個應用沒有本質區別。使用process屬性能夠實現多進程,可是會帶來不少麻煩,主要緣由是共享數據會失敗,弊端有:靜態和單利失效,同步失效,sharedprefer可靠性減低等問題
Intent,Binder(AIDL),sharedpre、Messenger
使用多進程顯而易見的好處就是分擔主進程的內存壓力。咱們的應用越作越大,內存愈來愈多,將一些獨立的組件放到不一樣的進程,它就不佔用主進程的內存空間了。固然還有其餘好處,有心人會發現Android後臺進程裏有不少應用是多個進程的,由於它們要常駐後臺,特別是即時通信或者社交應用,不過如今多進程已經被用爛了。典型用法是在啓動一個不可見的輕量級私有進程,在後臺收發消息,或者作一些耗時的事情,或者開機啓動這個進程,而後作監聽等。還有就是防止主進程被殺守護進程,守護進程和主進程之間相互監視,有一方被殺就從新啓動它。
假設手機本地須要緩存數據,如何保證和服務器的數據統一?
好比有個網絡更新的功能,activity能夠每隔半小時開啓service去訪問服務器,獲取最新的數據。
在緩存文件裏面加入時間戳,根據實際狀況在必定的時間差內再次訪問網絡數據、判斷URL
在緩存的第一行寫一個上當前時間,讀的時候判斷是否是過時,根據需求看須要多久跟新
分頁怎麼作的?
分頁根據服務器接口參數決定每次加載多少,getviewtype,getitemview
分批處理 解決的是時間等待的問題,不能解決內存佔用的問題。
要想解決內存佔用問題,能夠採用分頁方式
什麼Context
Android工程環境中像Activity、Service、BroadcastReceiver等系統組件,而這些組件並非像一個普通的Java對象new一下就能建立實例的了,而是要有它們各自的上下文環境,這就是Context。能夠這樣講,Context是維持Android程序中各組件可以正常工做的一個核心功能類。
Context功能不少,能夠彈出Toast、啓動Activity、啓動Service、發送廣播、操做數據庫等等等等都須要用到Context。
Context一共有Application、Activity和Service三種類型:Context數量 = Activity數量 + Service數量 + 1 。1表明着Application的數量,由於一個應用程序中能夠有多個Activity和多個Service,可是隻能有一個Application。
Android程序與Java程序的區別?
Android程序用android sdk開發,java程序用javasdk開發.
Android SDK引用了大部分的Java SDK,少數部分被Android SDK拋棄,好比說界面部分,java.awt swing package除了java.awt.font被引用外,其餘都被拋棄,在Android平臺開發中不能使用。 Android sdk 添加工具jar httpclient , pull opengl
Android中的動畫有哪幾類,它們的特色和區別是什麼?
屬性動畫:動畫的對象除了傳統的View對象,還能夠是Object對象,動畫結束後,Object對象的屬性值被實實在在的改變了
Android工程的目錄結構
src:項目的java代碼
assets:資源文件夾,存放視頻或者音樂等較大的資源文件
bin:存放應用打包編譯後的文件
res:資源文件夾,在這個文件夾中的全部資源,都會有資源id,讀取時經過資源id就能夠讀取
資源id不能出現中文
coverview原理:
這個參數用於將以前加載好的佈局進行緩存,以便以後能夠進行重用,在 getView()方法中進行了判斷,若是 convertView爲空,則使用
LayoutInflater去加載佈局,若是不爲空則直接對 convertView進行重用
android的啓動流程
當程序啓動Linux內核後,會加載各類驅動和數據結構,當有了驅動之後,開始啓動Android系統同時會加載用戶級別的第一個進程init(system\core\init.c),加載init.rc文件,會啓動一個Zygote進程,此進程是Android系統的一個母進程,用來啓動Android的其餘服務進程,而後接着在裏面啓動各類硬件服務和activity。Android系統啓動完成,打開了Luncher應用的Home界面。
Logcat
1. Log.v()
這個方法用於打印那些最爲瑣碎的,意義最小的日誌信息。對應級別 verbose,是Android日誌裏面級別最低的一種。
2. Log.d()
這個方法用於打印一些調試信息, 這些信息對你調試程序和分析問題應該是有幫助的。對應級別 debug,比 verbose高一級。
3. Log.i()
這個方法用於打印一些比較重要的數據,這些數據應該是你很是想看到的,能夠幫你分析用戶行爲的那種。對應級別 info,比 debug高一級。
4. Log.w()
這個方法用於打印一些警告信息,提示程序在這個地方可能會有潛在的風險,最好去修復一下這些出現警告的地方。對應級別 warn,比 info高一級。
5. Log.e()
這個方法用於打印程序中的錯誤信息,好比程序進入到了 catch語句當中。當有錯誤信息打印出來的時候,通常都表明你的程序出現嚴重問題了,必須儘快修復。對應級別 error,比 warn高一級.
推送
全部須要客戶端被動接收信息的功能模塊,均可以用推送實現,好比A想給B發消息,A調服務器接口,服務器只是存數據,它調推送的接口,推送去去找B。推送用的是xmpp協議, 是一種基於TCP/IP的協議, 這種協議更適合消息發送
- socket 套接字, 發送和接收網絡請求
- 長鏈接 keep-alive, 服務器基於長鏈接找到設備,發送消息
- 心跳包 , 客戶端會定時(30秒一次)向服務器發送一段極短的數據,做爲心跳包, 服務器定時收到心跳,證實客戶端或者,纔會發消息.不然將消息保存起來,等客戶端活了以後(從新鏈接),從新發送.
因爲篇幅緣由,附倆篇優化和自定義控件常見的面試題,但願對你們有所幫助: