Android面試中常問的問題

1.在android中,請簡述jni的調用過程。
1)安裝和下載Cygwin,下載 Android NDK
2)在ndk項目中JNI接口的設計
3)使用C/C++實現本地方法
4)JNI生成動態鏈接庫.so文件
5)將動態鏈接庫複製到java工程,在java工程中調用,運行java工程即可
2. 簡述Android應用程序結構有哪些?
  Linux Kernel(Linux內核)、Libraries(系統運行庫或者是c/c++核心庫)、Application  Framework(開發框架包)、Applications  (核心應用程序)
3.請繼承SQLiteOpenHelper實現:
1)創建一個版本爲1的“diaryOpenHelper.db”的數據庫,
2)同時創建一個 “diary” 表(包含一個_id主鍵並自增長,topic字符型100長度, content字符型1000長度)    
3)在數據庫版本變化時請刪除diary表,並重新創建出diary表。
public class DBHelper extends SQLiteOpenHelper{
 
public final static String DATABASENAME ="diaryOpenHelper.db";
public final static int DATABASEVERSION =1;
 
//創建數據庫
public DBHelper(Context context,Stringname,CursorFactory factory,int version)
{
super(context, name, factory,version);
}
//創建表等機構性文件
public void onCreate(SQLiteDatabase db)
{
String sql ="create tablediary"+
"("+
"_idinteger primary key autoincrement,"+
"topicvarchar(100),"+
"contentvarchar(1000)"+
")";
db.execSQL(sql);
}
//若數據庫版本有更新,則調用此方法
public void onUpgrade(SQLiteDatabasedb,int oldVersion,int newVersion)
{
String sql = "drop table if exists diary";
db.execSQL(sql);
this.onCreate(db);
}
}
4.頁面上現有控件progressBar,請用書寫線程以10秒的的時間完成其進度顯示工作。
public class ProgressBarStu extends Activity {
 
private ProgressBar progressBar = null;
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progressbar);
//從這到下是關鍵
progressBar = (ProgressBar)findViewById(R.id.progressBar);
Thread thread = new Thread(newRunnable() {
@Override
public void run() {
int progressBarMax =progressBar.getMax();
try {
while(progressBarMax!=progressBar.getProgress())
{
int stepProgress = progressBarMax/10;
int currentprogress = progressBar.getProgress();
progressBar.setProgress(currentprogress+stepProgress);
Thread.sleep(1000);
}
} catch(InterruptedException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
});
thread.start();
 
}
}
5. 如果後臺的Activity由於某原因被系統回收了,如何在被系統回收之前保存當前狀態?      onSaveInstanceState()
      當你的程序中某一個Activity A在運行時,主動或被動地運行另一個新的Activity B,這個時候A會執行onSaveInstanceState()。B完成以後又會來找A,這個時候就有兩種情況:一是A被回收,二是A沒有被回收,被回收的A就要重新調用onCreate()方法,不同於直接啓動的是這回onCreate()裏是帶上了參數savedInstanceState;而沒被收回的就直接執行onResume(),跳過onCreate()了。 
6.  如何將一個Activity設置成窗口的樣式。      
在AndroidManifest.xml 中定義Activity的地方一句話android:theme="@android:style/Theme.Dialog"或 android:theme="@android:style/Theme.Translucent"就變成半透明的
7.  如何退出Activity?如何安全退出已調用多個Activity的Application?
對於單一Activity的應用來說,退出很簡單,直接finish()即可。
當然,也可以用killProcess()和System.exit()這樣的方法。
但是,對於多Activity的應用來說,在打開多個Activity後,如果想在最後打開的Activity直接退出,上邊的方法都是沒有用的,因爲上邊的方法都是結束一個Activity而已。
那麼,有沒有辦法直接退出整個應用呢?
現提供幾個方法,供參考:
7.1  拋異常強制退出:

該方法通過拋異常,使程序ForceClose。
驗證可以,但是,需要解決的問題是,如何使程序結束掉,而不彈出Force Close的窗口。
7.2  記錄打開的Activity:
每打開一個Activity,就記錄下來。在需要退出時,關閉每一個Activity即可。
7.3  發送特定廣播:
在需要結束應用時,發送一個特定的廣播,每個Activity收到廣播後,關閉即可。
7.4  遞歸退出
在打開新的Activity時使用startActivityForResult,然後自己加標誌,在onActivityResult中處理,遞歸關閉。
8.請介紹下Android的數據存儲方式。
8.1  SharedPreferences方式
存儲路徑:(data/data/packagename/shares_prefs),輕量級存儲,以鍵值對的形式存儲在xml中,一般用來保存應用中的設置屬性
8.2  文件存儲方式
SD卡存儲多媒體文件,文件緩存
8.3  SQLite數據庫方式
存儲路徑:(data/data/packagename/databases),一種嵌入式數據庫,支持sql語言,存儲大量結構性數據
8.4  內容提供器(Content provider)方式
進程(應用程序)間數據共享,數據源可以是sqlite,也可以是xml,相關類:ContentResolver(內容解析器),ContentObserver(數據觀察者)
8.5  網絡存儲方式
天氣數據的xml,json格式等等,通過HttpUrlConnection,HttpClient,或者SOAP協議獲取數據
9.如何啓用Service,如何停用Service。
Android中的service類似於windows中的service,service一般沒有用戶操作界面,它運行於系統中不容易被用戶發覺,可以使用它開發如監控之類的程序。
9.1 步驟
第一步:繼承Service類
public class SMSService extends Service { }
第二步:在AndroidManifest.xml文件中的<application>節點裏對服務進行配置:
<service android:name=".DemoService" />
9.2 Context.startService()和Context.bindService
服務不能自己運行,需要通過調用Context.startService()或Context.bindService()方法啓動服務。這兩個方法都可
以啓動Service,但是它們的使用場合有所不同。
1.使用startService()方法啓用服務,調用者與服務之間沒有關連,即使調用者退出了,服務仍然運行。
使用bindService()方法啓用服務,調用者與服務綁定在了一起,調用者一旦退出,服務也就終止。
2.採用Context.startService()方法啓動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,
接着調用onStart()方法。如果調用startService()方法前服務已經被創建,多次調用startService()方法並
不會導致多次創建服務,但會導致多次調用onStart()方法。
採用startService()方法啓動的服務,只能調用Context.stopService()方法結束服務,服務結束時會調用
onDestroy()方法。 
3.採用Context.bindService()方法啓動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,
接着調用onBind()方法。這個時候調用者和服務綁定在一起,調用者退出了,系統就會先調用服務的onUnbind()方法,
。接着調用onDestroy()方法。如果調用bindService()方法前服務已經被綁定,多次調用bindService()方法並不會
導致多次創建服務及綁定(也就是說onCreate()和onBind()方法並不會被多次調用)。如果調用者希望與正在綁定的服務
解除綁定,可以調用unbindService()方法,調用該方法也會導致系統調用服務的onUnbind()-->onDestroy()方法。
9.3 Service的生命週期
Service的生命週期:onCreate,onStartCommand,onDestroy,onBindonUnbind
通常有兩種方式啓動一個Service,它們對Service生命週期的影響是不一樣的。
1)通過context.startService(),onCreate-->onStartCommand-->onDestroy
Service會經歷onCreateonStartCommand,然後處於運行狀態,stopService的時候調用onDestroy方法。
如果是調用者自己直接退出而沒有調用stopService的話,Service會一直在後臺運行。
如果Service已經啓動了,當我們再次啓動Service時,不會在執行onCreate()方法,而是直接執行onStartCommand()方法。
2)通過context.bindService(),onCreate--> onBind--->onUnbind-->onDestroy
Service會運行onCreate,然後是調用onBind,這個時候調用者和Service綁定在一起。調用者退出了,Srevice就會調用onUnbind->onDestroyed方法。
所謂綁定在一起就共存亡了。調用者也可以通過調用unbindService方法來停止服務,這時候Srevice就會調用onUnbind->onDestroyed方法。

備註:
1. 採用startService()啓動服務
     Intent intent =new Intent(DemoActivity.this, DemoService.class);
    startService(intent);
2.Context.bindService()啓動
    Intent intent =new Intent(DemoActivity.this, DemoService.class);
   bindService(intent, conn, Context.BIND_AUTO_CREATE);
   //unbindService(conn);//解除綁定

:onStartCommand()有四種返回值:
·START_STICKY:如果service進程被kill掉,保留service的狀態爲開始狀態,但不保留遞送的intent對象。隨後系統會嘗試重新創建service,由於服務狀態爲開始狀態,所以創建服務後一定會調用onStartCommand(Intent,int,int)方法。如果在此期間沒有任何啓動命令被傳遞到service,那麼參數Intent將爲null
·START_NOT_STICKY非粘性的。使用這個返回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統將會把它置爲started狀態,系統不會自動重啓該服務,直到startService(Intent intent)方法再次被調用;
·START_REDELIVER_INTENT:重傳Intent。使用這個返回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統會自動重啓該服務,並將Intent的值傳入。
·START_STICKY_COMPATIBILITYSTART_STICKY的兼容版本,但不保證服務被kill後一定能重啓。
10.Service是否運行在主線程,ServiceActivity是否運行在同一個線程?
ServiceActivityBroadcastReceiver同樣都運行在UI主線程,如果有耗時操作都會引發ANR問題。

11.IntentService的用法
Service的子類,主要用來解決在Service中處理耗時操作.
IntentService
使用隊列的方式將請求的Intent加入隊列,然後開啓一個worker thread(線程)來處理隊列中的Intent,對於異步的startService請求,IntentService會處理完成一個之後再處理第二個,每一個請求都會在一個單獨的worker thread中處理,不會阻塞應用程序的主線程

12.廣播的發送方式有哪些
sendBroadcast(),sendOrderedBroadcast()
sendStickyBroadcast()三種

·sendBroadcast()這個方法的廣播是能夠發送給所有廣播接收者,按照註冊的先後順序,如果你這個時候設置了廣播接收者的優先級,優先級如果恰好與註冊順序相同,則不會有任何問題,如果順序不一樣,會出leaked IntentReceiver這樣的異常,並且在前面的廣播接收者不能調用abortBroadcast()方法將其終止,如果調用會出BroadcastReceiver trying to return result during a non-ordered broadcast的異常,當然,先接收到廣播的receiver可以修改廣播數據。

·sendOrderedBroadcast()方法顧名思義就是priority的屬性能起作用,並且在隊列前面的receiver可以隨時終止廣播的發送。還有這個api能指定finalreceiver,這個receiver是最後一個接收廣播時間的receiver,並且一定會接收到廣播事件,是不能被前面的receiver攔截的。實際做實驗的情況是這樣的,假設我有3receiver依序排列,並且sendOrderedBroadcast()方法指定了一個finalReceiver,那麼intent傳遞給這4Receiver的順序爲Receiver1-->finalReceiver-->Receiver2-->finalReceiver-->Receiver3-->finalReceiver。這個特性可以用來統計系統中能監聽某種廣播的Receiver的數目。

·sendStickyBroadcast()字面意思是發送粘性的廣播,使用這個api需要權限android.Manifest.permission.BROADCAST_STICKY,粘性廣播的特點是Intent會一直保留到廣播事件結束,而這種廣播也沒有所謂的10秒限制,10秒限制是指普通的廣播如果onReceive方法執行時間太長,超過10秒的時候系統會將這個廣播置爲可以幹掉的candidate,一旦系統資源不夠的時候,就會幹掉這個廣播而讓它不執行。


: (下面是廣播接收者的生命週期以及一些細節部分:
1.
廣播接收者的生命週期是非常短暫的,在接收到廣播的時候創建,onReceive()方法結束之後銷燬
2.
廣播接收者中不要做一些耗時的工作,否則會彈出Application No Response錯誤對話框
3.
最好也不要在廣播接收者中創建子線程做耗時的工作,因爲廣播接收者被銷燬後進程就成爲了空進程,很容易被系統殺掉
4.
耗時的較長的工作最好放在服務中完成)
13.註冊廣播有幾種方式,這些方式有何優缺點?
Android廣播機制(兩種註冊方法) 
在android下,要想接受廣播信息,那麼這個廣播接收器就得我們自己來實現了,我們可以繼承BroadcastReceiver,就可以有一個廣播接受器了。有個接受器還不夠,我們還得重寫BroadcastReceiver裏面的onReceiver方法,當來廣播的時候我們要幹什麼,這就要我們自 己來實現,不過我們可以搞一個信息防火牆。具體的代碼:
public class SmsBroadCastReceiverextends BroadcastReceiver
{
 
@Override
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
Object[] object = (Object[])bundle.get("pdus");
SmsMessage sms[]=new SmsMessage[object.length];
for(int i=0;i<object.length;i++)
{
sms[0] =SmsMessage.createFromPdu((byte[])object);
Toast.makeText(context, "來自"+sms.getDisplayOriginatingAddress()+"的消息是:"+sms.getDisplayMessageBody(),Toast.LENGTH_SHORT).show();
}
//終止廣播,在這裏我們可以稍微處理,根據用戶輸入的號碼可以實現短信防火牆。
abortBroadcast();
}
}
當實現了廣播接收器,還要設置廣播接收器接收廣播信息的類型,這裏是信息:android.provider.Telephony.SMS_RECEIVED
我們就可以把廣播接收器註冊到系統裏面,可以讓系統知道我們有個廣播接收器。這裏有兩種,一種是代碼動態註冊:
//生成廣播處理  
smsBroadCastReceiver = newSmsBroadCastReceiver();   
//實例化過濾器並設置要過濾的廣播  
IntentFilter intentFilter = newIntentFilter("android.provider.Telephony.SMS_RECEIVED"); 
//註冊廣播   
BroadCastReceiverActivity.this.registerReceiver(smsBroadCastReceiver,intentFilter);  
一種是在AndroidManifest.xml中配置廣播
<?xml version="1.0"encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="spl.broadCastReceiver"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon"android:label="@string/app_name">
<activity android:name=".BroadCastReceiverActivity"
android:label="@string/app_name">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--廣播註冊-->
<receiver android:name=".SmsBroadCastReceiver">
<intent-filterandroid:priority="20">
<actionandroid:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
</application>
<uses-sdk android:minSdkVersion="7" />
<!-- 權限申請 -->
<uses-permissionandroid:name="android.permission.RECEIVE_SMS"></uses-permission>
</manifest>
兩種註冊類型的區別是:
    1)第一種不是常駐型廣播,也就是說廣播跟隨程序的生命週期。
    2)第二種是常駐型,也就是說當應用程序關閉後,如果有信息廣播來,程序也會被系統調用自動運行。

14.請解釋下在單線程模型中Message、Handler、MessageQueue、Looper之間的關係。
Handler簡介:
一個Handler允許你發送和處理Message和Runable對象,這些對象和一個線程的MessageQueue相關聯。每一個線程實例和一個單獨的線程以及該線程的MessageQueue相關聯。當你創建一個新的Handler時,它就和創建它的線程綁定在一起了。這裏,線程我們也可以理解爲線程的MessageQueue。從這一點上來看,Handler把Message和Runable對象傳遞給MessageQueue,而且在這些對象離開MessageQueue時,Handler負責執行他們。
Handler有兩個主要的用途:
(1)確定在將來的某個時間點執行一個或者一些Message和Runnable對象。
(2)在其他線程(不是Handler綁定線程)中排入一些要執行的動作。

Scheduling Message,即(1),可以通過以下方法完成:
post(Runnable):Runnable在handler綁定的線程上執行,也就是說不創建新線程。
postAtTime(Runnable,long):
postDelayed(Runnable,long):
sendEmptyMessage(int):
sendMessage(Message):
sendMessageAtTime(Message,long):
sendMessageDelayed(Message,long):

post這個動作讓你把Runnable對象排入MessageQueue,MessageQueue受到這些消息的時候執行他們,當然以一定的排序。sendMessage這個動作允許你把Message對象排成隊列,這些Message對象包含一些信息,Handler的hanlerMessage(Message)會處理這些Message.當然,handlerMessage(Message)必須由Handler的子類來重寫。這是編程人員需要作的事。
當posting或者sending到一個Hanler時,你可以有三種行爲:當MessageQueue準備好就處理,定義一個延遲時間,定義一個精確的時間去處理。後兩者允許你實現timeout,tick,和基於時間的行爲。
當你的應用創建一個新的進程時,主線程(也就是UI線程)自帶一個MessageQueue,這個MessageQueue管理頂層的應用對象(像activities,broadcast receivers等)和主線程創建的窗體。你可以創建自己的線程,並通過一個Handler和主線程進行通信。這和之前一樣,通過post和sendmessage來完成,差別在於在哪一個線程中執行這麼方法。在恰當的時候,給定的Runnable和Message將在Handler的MessageQueue中被Scheduled。

Message簡介:
Message類就是定義了一個信息,這個信息中包含一個描述符和任意的數據對象,這個信息被用來傳遞給Handler.Message對象提供額外的兩個int域和一個Object域,這可以讓你在大多數情況下不用作分配的動作。
儘管Message的構造函數是public的,但是獲取Message實例的最好方法是調用Message.obtain(),或者Handler.obtainMessage()方法,這些方法會從回收對象池中獲取一個。

MessageQueue簡介:
這是一個包含message列表的底層類。Looper負責分發這些message。Messages並不是直接加到一個MessageQueue中,而是通過MessageQueue.IdleHandler關聯到Looper。
你可以通過Looper.myQueue()從當前線程中獲取MessageQueue。

Looper簡介:
Looper類被用來執行一個線程中的message循環。默認情況,沒有一個消息循環關聯到線程。在線程中調用prepare()創建一個Looper,然後用loop()來處理messages,直到循環終止。
大多數和message loop的交互是通過Handler。

下面是一個典型的帶有Looper的線程 
class LooperThread extends Thread {
public Handler mHandler;
 
public void run() {
Looper.prepare();
 
mHandler = new Handler() {
public voidhandleMessage(Message msg) {
// process incomingmessages here
}
};
 
Looper.loop();
}
}
15.什麼是ANR如何避免它?(Android線程間的通信方式?)
答:ANR:ApplicationNotResponding(應用程序無響應).當出現下列情況時,Android就會顯示ANR對話框了:對輸入事件(如按鍵、觸摸屏事件)的響應超過5秒意向接受器(intentReceiver)超過10秒鐘仍未執行完畢Android應用程序完全運行在一個獨立的線程中(例如main)。這就意味着,任何在主線程中運行的,需要消耗大量時間的操作都會引發ANR。
解決方案有兩種:
1.AsyncTask異步任務中,doInBackground()和onPostExecute(Result)兩個方法非常重要
doInBackground()這個方法運行在後臺線程中,主要負責執行那些很耗時的操作,如移動護理系統中的網絡連接、解析XML等操作。該方法必須重載。
onPostExecute(Result)這個方法也運行於UI線程,在doInBackground(Params…)方法執行後調用,該方法用於處理後臺任務執行後返回的結果。
2.子thread+handler
16.AsyncTask的主要方法有哪些?如何啓動和停止AsyncTask?如何在AsyncTask中更新UI

答: AsyncTask的主要方法有doInBackGround()運行在後臺子線程,執行耗時操作
onPostExcute()運行在UI主線程,用於執行刷新UI的代碼
啓動通過execute()方法
停止通過cancel(boolean flag)方法取消執行,傳入參數ture表示如果調用方法時異步任務正在執行則打斷執行並取消,如果傳false表示執行完畢再取消
刷新UI的代碼一般卸載onPostExcute()方法中
17.掌握Android項目目錄結構
1.src目錄:src(即Source Code),src目錄用來存放應用程序中所有的源代碼,代碼的源文件一般存放在該目錄下的相應的包下。
2.gen目錄:gen目錄,該目錄下一般只有一個文件,即R文件。該文件夾下面有個R.java文件,R.java是在建立項目時自動生成的,定義該項目所有資源的索引。
3.Android4.1目錄:該文件夾下包含android.jar文件,這是一個Java歸檔文件,其中包含構建應用程序所需的所有的Android SDK庫(如Views、Controls)和APIs。
通過android.jar將自己的應用程序綁定到Android SDK和Android Emulator,這允許你使用所有Android的庫和包,且使你的應用程序在適當的環境中調試。
4.assets目錄:該目錄存放應用程序中使用的外部資源文件,如聲音視頻等,在Android程序中可以通過輸入/輸出流對該目錄中的文件進行讀寫。
5.res目錄:該目錄用來存放程序這用到的圖片、界面佈局文件及XML格式的描述文件。該目錄下有多個目錄。新建一個Android項目,在res目錄下一般
會有drawable,layout,valuse三個目錄。drawable用來存放圖片資源,目錄下一般會有三個目錄分別存放高中低三種不同分辨率的圖片,layout目錄用來存放應用程序的界面佈局文件,values目錄下存放字符串資源,顏色資源,數組資源等XML文件。
6.AndroidManifest.xml
18. 你如何評價Android系統?優缺點。
答:Android平臺手機 5大優勢: 
一、開放性 
在優勢方面,Android平臺首先就是其開發性,開發的平臺允許任何移動終端廠商加入到Android聯盟中來。顯著的開放性可以使其擁有更多的開發 者,隨着用戶和應用的日益豐富,一個嶄新的平臺也將很快走向成熟。開放性對於Android的發展而言,有利於積累人氣,這裏的人氣包括消費者和廠商,而 對於消費者來講,隨大的受益正是豐富的軟件資源。開放的平臺也會帶來更大競爭,如此一來,消費者將可以用更低的價位購得心儀的手機。
二、掙脫運營商的束縛 
在過去很長的一段時間,特別是在歐美地區,手機應用往往受到運營商制約,使用什麼功能接入什麼網絡,幾乎都受到運營商的控制。從去年iPhone 上市 ,用戶可以更加方便地連接網絡,運營商的制約減少。隨着EDGE、HSDPA這些2G至3G移動網絡的逐步過渡和提升,手機隨意接入網絡已不是運營商口中 的笑談,當你可以通過手機IM軟件方便地進行即時聊天時,再回想不久前天價的彩信和圖鈴下載業務,是不是像噩夢一樣?互聯網巨頭Google推動的 Android終端天生就有網絡特色,將讓用戶離互聯網更近。
三、豐富的硬件選擇 
這一點還是與Android平臺的開放性相關,由於Android的開放性,衆多的廠商會推出千奇百怪,功能特色各具的多種產品。功能上的差異和特色,卻 不會影響到數據同步、甚至軟件的兼容,好比你從諾基亞 Symbian風格手機 一下改用蘋果 iPhone ,同時還可將Symbian中優秀的軟件帶到iPhone上使用、聯繫人等資料更是可以方便地轉移,是不是非常方便呢?
四、不受任何限制的開發商 
Android平臺提供給第三方開發商一個十分寬泛、自由的環境,不會受到各種條條框框的阻擾,可想而知,會有多少新穎別緻的軟件會誕生。但也有其兩面性,血腥、暴力、情色方面的程序和遊戲如可控制正是留給Android難題之一。
五、無縫結合的Google應用 
如今叱詫互聯網的Google已經走過10年度歷史,從搜索巨人到全面的互聯網滲透,Google服務如地圖、郵件、搜索等已經成爲連接用戶和互聯網的重要紐帶,而Android平臺手機將無縫結合這些優秀的Google服務。
Android的5大不足:
一、安全和隱私 
由於手機與互聯網的緊密聯繫,個人隱私很難得到保守。除了上網過程中經意或不經意留下的個人足跡,Google這個巨人也時時站在你的身後,洞穿一切,因此,互聯網的深入將會帶來新一輪的隱私危機。
二、首先開賣Android手機的不是最大運營商 
衆所周知,T-Mobile在23日,於美國紐約發佈 了Android首款手機G1。但是在北美市場,最大的兩家運營商乃AT&T和Verizon,而目前所知取得Android手機銷售權的僅有 T-Mobile和Sprint,其中T-Mobile的3G網絡相對於其他三家也要遜色不少,因此,用戶可以買賬購買G1,能否體驗到最佳的3G網絡服 務則要另當別論了!
三、運營商仍然能夠影響到Android手機 
在國內市場,不少用戶對購得移動定製機不滿,感覺所購的手機被人塗畫了廣告一般。這樣的情況在國外市場同樣出現。Android手機的另一發售運營商Sprint就將在其機型中內置其手機商店程序。
四、同類機型用戶減少 
在不少手機論壇都會有針對某一型號的子論壇,對一款手機的使用心得交流,並分享軟件資源。而對於Android平臺手機,由於廠商豐富,產品類型多樣,這 樣使用同一款機型的用戶越來越少,缺少統一機型的程序強化。舉個稍顯不當的例子,現在山寨機氾濫,品種各異,就很少有專門針對某個型號山寨機的討論和羣 組,除了哪些功能異常搶眼、頗受追捧的機型以外。
五、過分依賴開發商缺少標準配置 
在使用PC端的Windows Xp系統的時候,都會內置微軟Windows Media Player這樣一個瀏覽器程序,用戶可以選擇更多樣的播放器,如Realplay或暴風影音等。但入手開始使用默認的程序同樣可以應付多樣的需要。在 Android平臺中,由於其開放性,軟件更多依賴第三方廠商,比如Android系統的SDK中就沒有內置音樂 播放器,全部依賴第三方開發,缺少了產品的統一性。
19.類似Android或IOS,他們都有一個共同的特點,那就是進程都是系統去關閉;而android的進程的5個等級是什麼。

 Foreground

 正處於Activity Resume()狀態

 正處於與bound服務交互的狀態

 正處於服務在前臺運行的狀態(startForeground()被調用)

Service生命週期函數正在被執行(oncreate),onStart(),onDestroy()

BroadCastReceiver正在執行onReceiver();

殺死Foreground Process需要用戶響應,因爲這個安全優先級是最高的 

Visible Process

Activity不在前端顯示,但也沒有完全隱藏,能夠看得見,比如彈出的dialog。 

Service Process

正在運行的,不在上述兩種狀態的Service

Background Process

不可見狀態的Activity進程(onstop()被調用)

Empty Process

沒有運行任何Components的進程,保留這個進程主要是爲了緩存的需要

20.Android中asset文件夾和raw文件夾區別?

答:res/raw和assets的相同點:
兩者目錄下的文件在打包後會原封不動的保存在apk包中,不會被編譯成二進制。
res/raw和assets的不同點:
1)res/raw中的文件會被映射到R.java文件中,訪問的時候直接使用資源ID即R.raw.filename;assets文件夾下的文件不會被映射到R.java中,訪問的時候需要AssetManager類。
2)res/raw不可以有目錄結構,而assets則可以有目錄結構,也就是assets目錄下可以再建立文件夾
3)讀取文件資源舉例:
讀取res/raw下的文件資源,通過以下方式獲取輸入流來進行寫操作
InputStreamis=getResources().openRawResource(R.raw.filename);
讀取assets下的文件資源,通過以下方式獲取輸入流來進行寫操作

  1. AssetManager am=null;
  2. am=getAssets();
  3. InputStreamis=am.open("filename");

21.掌握模擬器的使用以及常用adb命令

1. adb devices
查看當前連接設備
2. adb kill-server
終止adb進程
3. adb start-server
啓動adb進程
4. adb shell
進入shell模式(Linux模式),當連接有多個設備時,需執行命令
adb -s設備名shell
注:進入shell模式後序執行Linux命令
5. adb install apk路徑
安裝apk至設備,當連接有多個設備時,需執行命令
adb -s設備名install apk路徑
當設備之前裝有次apk時,替換安裝序執行命令
adb install -r apk路徑
6. adb uninstall要卸載的應用包名
卸載已安裝的應用
7. adb push要拷貝的文件路徑設備上存放次文件的路徑
將文件拷貝至設備sdcard,如adb push F:\Android授課資料\項目實訓\1205A\apk\com.moluo.android_100111.apk /sdcard
8. adb pull設備上文件路徑電腦存放文件路徑
將文件從設備拷貝到電腦,如adb pull /sdcard/com.moluo.android_100111.apk E:/
9. adb logcat
命令行的方式查看日誌
若希望將日誌保存至某文件,adb logcat -> E:/test.txt
10. android list avd
查看當前創建的所有模擬器列表
11. emulator @模擬器名字
啓動某個模擬器
12.命令行操作數據庫
adb shell
cd data/data
cd package
cd databases/cd shared_prefs/ cd files
sqlite3 test.db
>.tables
即可執行響應sql語句
22.掌握Activity的生命週期及各方法調用時機
答:共有七個週期函數:
void onCreate(BundlesavedInstanceState)第一次創建時調用
void onStart()被用戶可見時調用
void onRestart()當Activity處於stop狀態又被重新啓動時調用
void onResume()當獲得焦點即可與用戶交互時調用
void onPause()當失去焦點時調用
void onStop()當不可見時調用
void onDestroy()當銷燬時調用
Activity A---> Activity B, B將A完全覆蓋時生命週期調用流程:
onPause(A) --> onCreate(B) --> onStart(B) --> onResume(B) --> onStop(A)
此時按"Back"按鍵,證明週期調用流程
onPause(B) --> onRestart(A) --> onStart(A) -->onResume(A) --> onStop(B) --> onDestroy(B)
23.Activity四種啓動模式
在AndroidManifest.xml清單文件中的標籤中通過android:launchMode設置Activity啓動模式
standard:默認值,表示在startActivity時即創建其實例
singleTop:單一棧頂模式,首先檢查棧頂是否有該Activity實例,有則返回,無則創建其實例
singleTask:單一任務模式,檢查整個堆棧有無該Activity實例,有則返回,無則創建其實例
singleInstance:單一實例模式,一個Activity實例獨享一個任務堆棧,並且只能有一個堆棧中有該Activity的實例
24.談談UI中,Padding和Margin有什麼區別,gravity與layout_gravity的區別
答:Padding用來指定組件內的內容距離組件邊界的距離;
Margin用來指定控件與控件之間的距離
Gravity用來指定組件內的內容相對於組件本身的位置
Layout_gravity用來指定組件相對於其父組件的位置
25.listview優化策略?
答:1)自定義Adapter的getView(),對convetView進行判空,是當convertView不爲空的時候直接重新使用convertView
從而減少了很多不必要的View的創建
2)定義一個ViewHolder,將convetView的tag設置爲ViewHolder,不爲空時重新使用即可
3)當ListView加載數據量較大時可以採用分頁加載和圖片異步加載
4)實現分頁加載
實現OnScrollListener接口重寫onScrollStateChanged和onScroll方法,使用onscroll方法實現”滑動“後處理檢查是否還有新的記錄,如果有,添加記錄到adapter,adapter調用notifyDataSetChanged更新數據;如果沒有記錄了,則不再加載數據。使用onScrollStateChanged可以檢測是否滾到最後一行且停止滾動然後執行加載.
5)異步加載圖片
1.先從內存緩存中獲取圖片顯示(內存緩衝)
2.獲取不到的話從SD卡里獲取(SD卡緩衝,,從SD卡獲取圖片是放在子線程裏執行的,否則快速滑屏的話會不夠流暢)
3.都獲取不到的話從網絡下載圖片並保存到SD卡同時加入內存並顯示(視情況看是否要顯示)
26.view有哪幾種更新方式
答:在主線程(UI線程)可以直接調用View.invalidate() ;
在子線程需要更新UI可以直接調用View.postInvalidate(),也可以通過Handler發送消息給主線程,然後在handleMessage方法中通過View.invalidate()更新UI;
還可以在子線程中需要更新UI的時候調用runOnUIThread(Runnable )方法,然後在此方法中更新UI,同時可以使用AsyncTask異步任務,在doInBackground執行耗時操作,然後在onPostExcute方法中執行刷新UI動作
27.Intent的原理,作用,可以傳遞哪些類型的參數?
答:intent是連接Activity,Service,BroadcastReceiver,ContentProvider四大組件的信使,,可以傳遞八種基本數據類型以及string,Bundle類型,以及實現了Serializable或者Parcelable的類型。
Intent可以劃分成顯式意圖和隱式意圖。
顯式意圖:調用Intent.setComponent()或Intent.setClass()方法明確指定了組件名的Intent爲顯式意圖,顯式意圖明確指定了Intent應該傳遞給哪個組件。
隱式意圖:沒有明確指定組件名的Intent爲隱式意圖。Android系統會根據隱式意圖中設置的動作(action)、類別(category)、數據(URI和數據類型)找到最合適的組件來處理這個意圖。
28.Android的四大組件是什麼?它們的作用是什麼?
答:Android有四大組件:Activity、Service、BroadcastReceiver、ContentProvider。
Activity:應用程序中,一個Activity通常就是一個單獨的屏幕,它上面可以顯示一些控件也可以監聽並處理用戶的事件做出響應。Activity之間通過Intent進行通信。
Service服務:一個Service是一段長生命週期的,沒有用戶界面的程序,可以用來開發如監控類程序。
BroadcastReceive廣播接收器:你的應用可以使用它對外部事件進行過濾只對感興趣的外部事件(如當電話呼入時,或者數據網絡可用時)進行接收並做出響應。廣播接收器沒有用戶界面。然而,它們可以啓動一個activity或serice來響應它們收到的信息。
ContentProvider內容提供者:主要用於多個應用間數據共享。這些數據可以存儲在文件系統中或SQLite數據庫。
29.DVM與JVM區別

· 區別一:dvm執行的是.dex格式文件,jvm執行的是.class文件。android程序編譯完之後生產.class文件,然後,dex工具會把.class文件處理成.dex文件,然後把資源文件和.dex文件等打包成.apk文件。apk就是android package的意思。jvm執行的是.class文件。

· 區別二:dvm是基於寄存器的虛擬機而jvm執行是基於虛擬棧的虛擬機。寄存器存取速度比棧快的多,dvm可以根據硬件實現最大的優化,比較適合移動設備。

· 區別三:.class文件存在很多的冗餘信息,dex工具會去除冗餘信息,並把所有的.class文件整合到.dex文件中。減少了I/O操作,提高了類的查找速度。



















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章