轉載請注明本文出自xiaole0313的博客(http://blog.csdn.net/xiaole0313),謝謝支持!
前言
最近才開的博客,希望大家多多關注,andorid開發也做了3年有余了,也面試多家企業,借此機會分享1下,我們中遇到過的問題和解決方案吧,希望能夠對正在找工作的andoird程序員有1定的幫助。學完《andorid從零開始教程》+面試題目全理解,年薪20w以上絕對沒問題。
特別獻上整理過的50道面試題目
1.listView的優化方式
重用convertView |
viewHolder |
static class viewHolder |
在列表里面有圖片的情況下,監聽滑動不加載圖片 |
多個不同布局,可以創建不同的viewHolder和convertView進行重用 |
從sqlite拉取數據源顯示 |
從xml使用pull解析拉取數據源顯示 |
從網絡上拉取數據源顯示 |
進程間通訊主要包括管道, 系統IPC(Inter-Process Communication,進程間通訊)(包括消息隊列,信號,同享存儲),
套接字(SOCKET). 目的: l 數據傳輸:1個進程需要將它的數據發送給另外一個進程,發送的數據量在1個字節到幾兆字節之間。 l 同享數據:多個進程想要操作同享數據,1個進程對同享數據的修改,別的進程應當立刻看到。 l 通知事件:1個進程需要向另外一個或1組進程發送消息,通知它(它們)產生了某種事件(如進程終止時要通知父進程)。 l 資源同享:多個進程之間同享一樣的資源。為了作到這1點,需要內核提供鎖和同步機制。 l 進程控制:有些進程希望完全控制另外一個進程的履行(如Debug進程),此時控制進程希望能夠攔截另外一個進程的所有墮入和異常,并能夠及時知道它的狀態改變。 進程通過與內核及其它進程之間的相互通訊來調和它們的行動。Linux支持多種進程間通訊(IPC)機制,信號和管道是其中的兩種。除此以外,Linux還支持System V 的IPC機制(用首次出現的Unix版本命名)。 |
Android中的Parcel機制 實現了Bundle傳遞對象 使用Bundle傳遞對象,首先要將其序列化,但是,在Android中要使用這類傳遞對象的方式需要用到Android Parcel機制,即,Android實現的輕量級的高效的對象序列化和反序列化機制。 JAVA中的Serialize機制,譯成串行化、序列化……,其作用是能將數據對象存入字節流當中,在需要時重新生成對象。主要利用是利用外部存儲裝備保存對象狀態,和通過網絡傳輸對象等。 Android中的新的序列化機制 在Android系統中,定位為針對內存受限的裝備,因此對性能要求更高,另外系統中采取了新的IPC(進程間通訊)機制,必定要求使用性能更出色的對象傳輸方式。在這樣的環境下, Parcel被設計出來,其定位就是輕量級的高效的對象序列化和反序列化機制。 Android中序列化有以下幾個特點: 1. 全部讀寫全是在內存中進行,所以效力比JAVA序列化中使用外部存儲器會高很多; 2. 讀寫時是4字節對齊的 3. 如果預分配的空間不夠時,會1次多分配50%; 4. 對普通數據,使用的是mData內存地址,對IBinder類型的數據和FileDescriptor使用的是mObjects內存地址。后者是通過flatten_binder()和unflatten_binder()實現的,目的是反序列化時讀出的對象就是原對象而不用重新new1個新對象。 代碼: activity代碼: Intent mIntent =newIntent(this,ParcelableDemo.class); Bundle mBundle =newBundle(); mBundle.putParcelable(PAR_KEY, mPolice); mIntent.putExtras(mBundle); 實體類:
|
(1) Eclipse中新建android工程 工程名 JNItest Package名com.ura.test Activity名 JNItest 利用程序名 JNItest (2) 編輯main.xml <?xml version="1.0" encoding="utf⑻"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/JNITest" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/JNITest" /> </LinearLayout> (3)編輯java文件 package com.ura.test; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class JNITest extends Activity { /** Called when the activity is first created. */ static { System.loadLibrary("JNITest"); } public native String GetTest(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String str =GetTest(); TextView JNITest = (TextView)findViewById(R.id.JNITest); JNITest.setText(str); } } (4)生成head文件 編譯上面工程宣稱class文件,然后用javah工具生成c/c++ 頭文件 javah -classpath bin -d jni com.ura.test.JNItest 生成的頭文件以下 /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_ura_test_JNITest */ #ifndef _Included_com_ura_test_JNITest #define _Included_com_ura_test_JNITest #ifdef __cplusplus extern "C" { #endif /* * Class: com_ura_test_JNITest * Method: GetTest * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_ura_test_JNITest_GetTest (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif (5)編寫c/c++文件以下 include "com_ura_test_JNITest.h" #define LOG_TAG "JNITest" #undef LOG #include <utils/Log.h> JNIEXPORT jstring JNICALL Java_com_ura_test_JNITest_GetTest (JNIEnv * env, jobject obj) { return (*env)->NewStringUTF(env, (char *)"JNITest Native String"); LOGD("Hello LIB!\n"); } (6)編寫android.mk文件 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ com_ura_test_JNITest.c LOCAL_C_INCLUDES := \ $(JNI_H_INCLUDE) LOCAL_SHARED_LIBRARIES := libutils LOCAL_PRELINK_MODULE := false LOCAL_MODULE := libJNITest include $(BUILD_SHARED_LIBRARY) (7)編譯生成動態庫 新建文件夾 ~/mydroid/external/libJNITest 把上面編寫好的頭文件,c/c++源文件,make文件拷貝進上面目錄中 * 需要注意的是把PRELINK_MOUDULE設置成false 否則需要重新做成img文件再燒入。 在 ubuntu中履行 cd cd mydroid/build/ envsetup.sh cd ~/mydroid cd external/libJNITest/ mm 編譯成功的后會在下面目錄中生成libJNITest.so文件 ~mydroid/out/target/product/generic/system/lib/ (8)在摹擬器中履行程序 首先要把動態庫拷進/system/lib中。 啟動摹擬器 adb shell adb remount adb push libJNITest.so /system/lib 確認拷貝成功 cd /system/lib ls 然后不要關閉摹擬器(關掉再開動態庫就沒了,由于摹擬器rom是只讀) 履行java程序JNITest 會看到屏幕上打印出 JNITest Native String |
4大組件之1,1般的,1個用戶交互界面對應1個activity setContentView() ,// 要顯示的布局 button.setOnclickLinstener{ } , activity 是Context的子類,同時實現了window.callback和keyevent.callback, 可以處理與窗體用戶交互的事件. 里面不能進行耗時操作 我開發經常使用的的有ListActivity , PreferenceActivity ,TabAcitivty等… 如果界面有共同的特點或功能的時候,還會自己定義1個BaseActivity. |
Activity生命周期 1 完全生命周期 onCreate() --> onStart() --> onResume() 可以在手機上看見activity ---> onPause() --> onStop() 看不見了 ---> onDestory() 燒毀了 2 前臺生命周期 onstart() ---> onStop()之間進行切換 onCreate() --> onStart() --> onResume() 現在有1個activity完全覆蓋 onPause() ----> onStop() 如果上面的activity關閉 onRestart() ---> onStart() --> onResume() 3 可視生命周期 onResume() ---> onPause()之間進行切換 onCreate() --> onStart() --> onResume() 現在有1個activity沒有完全覆蓋 onPause() 如果上面的activity關閉 onResume() |
這個生命周期跟清單文件里的配置有關系 1、不設置Activity的android:configChanges時,切屏會重新調用各個生命周期 默許首先燒毀當前activity,然后重新加載 2、設置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調用各個生命周期,只會履行onConfigurationChanged方法 游戲開發中, 屏幕的朝向都是寫死的. |
可以自定義1個activity的樣式,詳細見手機衛士的程序詳細信息 android:theme="@style/FloatActivity" E:\day9\mobilesafe\res\values\style |
|
除在棧頂的activity,其他的activity都有可能在內存不足的時候被系統回收,1個activity越處于棧底,被回收的可能性越大. protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putLong("id", 1234567890); } public void onCreate(Bundle savedInstanceState) { //判斷savedInstanceState是否是空. //如果不為空就取出來 super.onCreate(savedInstanceState); } |
退出activity 直接調用 finish () 方法 . //用戶點擊back鍵 就是退出1個activity 退出activity 會履行 onDestroy()方法 . 1、拋異常強迫退出: 該方法通過拋異常,使程序Force Close。 驗證可以,但是,需要解決的問題是,如何使程序結束掉,而不彈出Force Close的窗口。 //安全結束進程 android.os.Process.killProcess(android.os.Process.myPid()); 2、記錄打開的Activity: 每打開1個Activity,就記錄下來。在需要退出時,關閉每個Activity便可。 List<Activity> lists ; 在application 全集的環境里面 lists = new ArrayList<Activity>(); lists.add(activity); for(Activity activity: lists) { activity.finish(); } 3、發送特定廣播: 在需要結束利用時,發送1個特定的廣播,每一個Activity收到廣播后,關閉便可。 //給某個activity 注冊接受接受廣播的意圖 registerReceiver(receiver, filter) //如果過接遭到的是 關閉activity的廣播 就調用finish()方法 把當前的activity finish()掉 4、遞歸退出 在打開新的Activity時使用startActivityForResult,然后自己加標志,在onActivityResult中處理,遞歸關閉。 上面是網上的1些做法. 其實 可以通過 intent的flag 來實現.. intent.setFlag(FLAG_ACTIVITY_CLEAR_TOP)激活1個新的activity,然后在新的activity的oncreate方法里面 finish掉. |
基本數據類型可以通過. Intent 傳遞數據 在A activity中 Intent intent = new Intent(); intent.putExtra(name, value) Bundle bundle = new Bundle(); bundle.putBoolean(key,value); intent.putExtras(bundle); extras.putDouble(key, value) // 通過intent putExtra 方法 基本數據類型 都傳遞 Intent i = getIntent(); i.getExtras(); intent.getStringExtra("key","value"); intent.getBooleanExtra("key","value") Bundle bundle = new Bundle(); bumdle.putShort(key, value); intent.putExtras(bumdle); intent.putExtras(bundle) -------------- Application 全局里面寄存 對象 ,自己去實現自己的application的這個類, 基礎系統的application , 每一個activity都可以取到 ----------------- 讓對象實現 implements Serializable 接口把對象寄存到文件上. 讓類實現Serializable 接口,然后可以通過ObjectOutputStream //對象輸出流 File file = new File("c:\1.obj"); FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos); Student stu = new Student(); oos.writeObject(stu); //從文件中把對象讀出來 ObjectInputStream ois = new ObjectInputStream(arg0); Student stu1 = (Student) ois.readObject(); 文件/網絡 intent.setData(Uri) Uri.fromFile(); //大圖片的傳遞 |
把上面的幾點用自己的心得寫出來 |