Android面試簡錄——組件3

四大應用程序組件


Android中的窗口:Activity

  • 如何配置Activity才能讓程序啟動時將該Activity作為啟動窗口揖曾?
    在AndroidManifest.xml文件中指定MAIN動作赡盘。
    <action android:name="android.intent.action.MAIN" />
  • 請闡述Activity有哪幾個生命周期方法以及在Activity現(xiàn)實和銷毀的過程中生命周期方法執(zhí)行的順序扯旷。
    protected void onCreate(Bundle savedInstanceState)
    protected void onStart()
    protected void onRestart()
    protected void onResume()
    protected void onPause()
    protected void onStop()
    protected void onDestroy()
    Activity顯示:onCreate -> onStart ->onResume.
    Activity銷毀:onPause -> onStop -> onDestroy.
    onStop時Activity重新獲得焦點:onRestart -> onStart -> onResume.
  • 調(diào)用Activity都有哪幾種方法奕塑?
    1.顯式調(diào)用:直接指定Activity
    2.隱式調(diào)用:通過Activity Action來調(diào)用Activity
  • 在Activity之間如何傳遞數(shù)據(jù)丰歌?
    1.Intent對象:
    Intent.putExtra ~ 設置要傳遞的數(shù)據(jù)
    Intent.getXxxExtra ~ 獲取傳遞的數(shù)據(jù)
    2.靜態(tài)變量:public static
    3.剪切板:
    數(shù)據(jù)保存:
    Intent intent = new Intent(this, MyActivity.class);
    ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
    clipboard.setText("數(shù)據(jù)");
    startActivity(intent);
    獲取數(shù)據(jù):
    ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
    String text = clipboard.getText().toString();
    4.全局對象:繼承自android.app.Application類
    package mobile.android.transmit.data;
    import android.app.application;
    public class MyApp extends Application {
    public String country;
    public Data data = new Data();
    }
    需要在AndroidManifest.xml中定義該類议蟆。
    獲然槲隆:
    MyApp myApp = (MyApp) getApplicationContext();

【拓展】通過剪切板傳遞復雜數(shù)據(jù)
問題提出:高版本中支持剪切板保存Intent支持的類型锡宋,但是低版本中不支持儡湾。
解決辦法:使用字符串傳遞任何二進制數(shù)據(jù)(包括可序列化對象、圖像的等)执俩。
1.將可序列化對象轉(zhuǎn)換成Base64編碼徐钠,然后保存到剪切板中:
Intent intent = new Intent(this, MyActivity3.class);
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
Data clipboardData = new Data();
clipboardData.id = 6666;
clipboardData.name = "通過Clipboard傳遞的數(shù)據(jù)";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String base64Str = "";
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(clipboardData);
base64Str = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
oos.close();
} catch (Exception e) {
}
clipboard.setText(base64Str);
startActivity(intent);
2.從剪切板中獲取Base64編碼格式的字符串,并進行解碼役首,最后還原成Data對象尝丐。
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
String base64Str = clipboard.getText().toString();
byte[] buffer = Base64.decode(base64Str, Base64.DEFAULT);
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
try {
ObjectInputStream ois = new ObjectInputStream(bais);
Data data = (Data) ois.redObject();
textView.setText(base64Str + "\n\ndata.id:" + data.id + "\ndata.name" + data.name);
} catch (Exception e) {
}

  • 請寫出直接撥號、將電話號碼傳入撥號程序衡奥、調(diào)用撥號程序爹袁、調(diào)用系統(tǒng)瀏覽器瀏覽網(wǎng)頁、調(diào)用系統(tǒng)程序查看聯(lián)系人矮固、顯示系統(tǒng)設置界面和現(xiàn)實Wi-Fi設置界面的Java程序失息。
    撥號代碼:
    Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:12345678"));
    startActivity(callIntent);
    將電話號碼傳入撥號程序:
    Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:87654321"));
    startActivity(dialIntent);
    調(diào)用撥號程序:
    Intent touchDialerIntent = new Intent("com.android.phone.action.TOUCH_DIALER");
    startActivity(touchDialerIntent);
    調(diào)用系統(tǒng)瀏覽器網(wǎng)頁:
    Intent webIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://nokiaguy.blogjava.net"));
    startActivity(webIntent);
    調(diào)用系統(tǒng)程序查看聯(lián)系人:
    Intent contactListIntent = new Intent("com.android.contacts.action.LIST_CONTACTS");
    startActivity(contactListIntent);
    顯示系統(tǒng)設置頁面:
    Intent settingIntent = new Intent("android.settings.SETTINGS");
    startActivity(settingIntent);
    顯示W(wǎng)i-Fi設置界面:
    Intent wifiSettingsIntent = new Intent("android.settings.WIFI_SETTINGS");
    startActivity(wifiSettingsIntent);
  • 如何將Activity變成半透明的對話框?
    對話框:Theme.Dialog
    半透明:android:windowBackground
    1.定義一個新的主題:
    <style name="MyTheme" parent="@android:style/Theme.Dialog">
    <item name="android:windowBackground">@drawable/msg_background</item>
    </style>
    2.指定主題
    <activity android:name=".Main" android:label="@string/appname" android:theme="@style/MyTheme">
  • 如何設置Activity顯示和關閉時的動畫效果档址?
    overridePendingTransition方法
    1.在res/anim中建立對應的動畫資源文件
    2.在代碼中添加動畫效果:
    Intent intent = new Intent(this, AnimationActivity.class);
    startActivity(intent);
    overridePendingTransition(R.anim.fade_in, R.anim.fade_out);

廣播接收器:Broadcast Receiver

  • 如何接收廣播盹兢?
    接收單個廣播:
    1.編寫廣播接收類。從BroadcastReceiver或其子類繼承守伸。
    2.在BroadcastReceiver.onReceive(Context context, Intent intent)方法中編寫處理廣播的代碼绎秒。
    *在AndroidManifest.xml文件中注冊。
    接收多個廣播:
    使用intent.getAction判斷當前接收到的是哪個廣播尼摹。
    if ("action1".equals(intent.getAction())) {
    ...
    }
    if ("action2".equals(intent.getAction())) {
    ...
    }
  • 如何獲取短信內(nèi)容替裆?
    1.編寫廣播接收器
    onReceive方法如下:
    public void onReceive(Context context, Intent intent) {
    Bundle bundle = new intent.getExtras();
    if (bundle != null) {
    Object[] objArray = (Object[]) bundle.get("pdus");
    SmsMessage[] messages = new SmsMessage[objArray.length];
    for (int i = 0; i < objArray.length; i ++) {
    messages[i] = SmsMessage.createFromPdu((byte[]) objArray[i]);
    String s = "手機號:" + messages[i].getOriginationAddress() + "\n";
    s += "短信內(nèi)容:" = messages[i].getDisplayMessageBody();
    Toast.makeText(context, s, Toast.LENGTH_LONG).show();
    }
    }
    }
    2.在AndroidManifest.xml文件中定義該廣播接收器時添加短信廣播Action校辩。
    <action android:name="android.provider.Telephony.SMS_RECEIVED" />
  • 如何攔截來電,并在檢測到某些特定號碼時自動掛斷電話辆童?
    編寫一個廣播接收類來攔截來電。
    通過反射技術訪問Android SDK的內(nèi)部功能來掛斷電話惠赫。
    攔截來電的onReceive方法:
    public void onReceive(final Context context, Intent intent) {
    TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
    switch (tm.getCallState()) {
    case TelephonyManager.CALL_STATE_RINGING:
    String incomingNumber = intent.getStringExtra("incoming_number");
    if ("12345678".equals(incomingNumber)) {
    Class<TelephonyManager> telephonyManagerClass = TelephonyManager.class;
    Method telephonyMethod = telephonyManagerClass.getDeclaredMethod("getITelephony", (Class[]) null);
    telephonyMethod.setAccessible(true);
    Object obj = telephonyMethod.invoke(tm, (Object[], null));
    Method endCallMethod = obj.getCLass().getMethod("endCall", null);
    endCallMethod.setAccessible(true);
    endCallMethod.invoke(obj, null);
    }
    break;
    case TelephonyManager.CALL_STATE_OFFHOOK:
    Log.d("call_state", "offhook");
    break;
    case TelephonyManager.CALL_STATE_IDLE:
    closeToast();
    }
    }
    在AndroidManifest.xml文件中設置定義廣播接收器:
    <action android:name="android.intent.action.PHONE_STATE"/>
  • 如何攔截手機屏幕休眠和喚醒動作把鉴?
    [注意] 該功能的廣播接收器只能通過Java代碼注冊,不能在AndroidManifest.xml文件中注冊儿咱。
    通過如下兩個Broadcast Action可以攔截屏幕休眠和喚醒動作:
    休眠狀態(tài):Intent.ACTION_SCREEN_ON
    喚醒狀態(tài):Intent.ACTION_SCREEN_OFF
    注冊廣播接收器(ScreenOnOffReceiver)的代碼如下:
    ScreenOnOffReceiver screenOnOffReceiver = new ScreenOnOffReceiver();
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(Intent.ACTION_SCREEN_ON);
    intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
    registerReceiver(screenOnOffReceiver, intentFilter);
  • 如何讓一個Acitivity在開機后自動顯示庭砍?
    使用廣播接收器(StarupReceiver)攔截手機啟動廣播,然后在onReceive方法中打開Activity混埠。
    public void onReceive(Context context, Intent intent) {
    Intent mainIntent = new Intent(context, Main.class);
    mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(mainIntent);
    }
    注冊:
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
    * 如何發(fā)送廣播怠缸?
    sendBroadcast:
    public void sendBroadcast(Intent intent);

服務:Service

  • 請描述一下Service的生命周期。
    3個生命周期钳宪。
    public void onCreate(); //創(chuàng)建服務
    public void onStart(Intent intent, int startId); //開始服務
    public void onDestroy(); //銷毀服務
    首次創(chuàng)建:onCreate() -> onStart().
    再次調(diào)用startService/使用startService開始一個已經(jīng)停止的服務:onStart().
    調(diào)用stopService:onDestroy().
  • 請描述一下開發(fā)AIDL服務的步驟揭北。
    AIDL:允許一個應用程序訪問另一個應用程序的對象。
    建立AIDL服務的步驟:
    1.建立aidl文件(Android工程的Java源文件目錄)
    2.如果aidl文件內(nèi)容正確 -> 自動生成Java接口文件(*.java)
    3.建立一個服務類
    4.實現(xiàn)aidl文件生成的java接口
    5.在AndroidManifest.xml文件中配置AIDL服務吏颖。[注意]<action>標簽中android:name的屬性值就是客戶端要引用該服務的ID搔体,也就是Intent類構造方法的參數(shù)值。
  • AIDL服務支持哪些類型的數(shù)據(jù)半醉?
    1.Java的簡單類型(int疚俱,char,boolean等)
    2.String和CharSequence
    3.List和Map
    4.AIDL自動生成的接口類型
    5.實現(xiàn)android.os.Parcelable接口的類

內(nèi)容提供者:Content Provider

  • 如何讀取聯(lián)系人信息缩多?
    ListView listView = (ListView) findViewById(R.id.listView);
    Cursor cursor = getContentResolver().query(
    ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
    SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(
    this, android.R.layout.simple_list_item_1, cursor,
    new String[] {ContactsContract.Contacts.DISPLAY_NAME},
    new int[] {android.R.id.text1});
    listView.setAdapter(simpleCursorAdapter);

  • 如何查詢收發(fā)的短信信息呆奕,以及只查收件箱和發(fā)件箱?
    ListView lvShortMessages = (ListView) findViewById(R.id.lvShortMessages);
    Cursor cursor = getContentResolver().query(
    Uri.parse("content://sms"), null, "address like ?",
    new String[] {"1%"}, null);
    SMSAdapter smsAdapter = new SMSAdapter(this, cursor);
    lvShortMessages.setAdapter(smsAdapter);
    只查收件箱:"content://sms" -> "content://sms/inbox"
    只查發(fā)件箱:"content://sms" -> "content://sms/outbox"

  • 請描述Content Provider URI有哪幾部分組件衬吆?
    四部分:
    1.content:// ~ 相當于HTTP URI的http://
    2.authority ~ 相當于HTTP URI的域名
    3.路徑(path)
    4.參數(shù)(param)
    舉例:content://mobile.android.mydata/product/20
    分析:authority:mobile.android.mydata
    path:product
    param:20

  • 開發(fā)一個Content Provider的步驟梁钾。
    1.編寫一個類,繼承自ContentProvider
    2.實現(xiàn)ContentProvider中所有的抽象方法
    3.定義Content Provider的URI
    4.在static塊中使用UriMatcher對象映射Uri和返回碼
    static {
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    uriMatcher.addURI(AUTHORITY, "cities", 1);
    uriMatcher.addURI(AUTHORITY, "code/#", 2);
    uriMatcher.addURI(AUTHORITY, "cities_in_province/*", 3);
    }
    5.根須實際的需要實現(xiàn)相應的方法
    6.實現(xiàn)query,insert,delete,update方法時要使用UriMatcher.match方法將URI映射成第4步與URI對應的代碼(addURI方法的最后一個參數(shù)值)
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    Cursor cursor = null;
    switch (uriMatcher.match(uri)) {
    case 1:
    ...
    break;
    case 2:
    ...
    break;
    default:
    throw new IllegalArgumentException("<" + uri + ">格式不正確");
    }
    return cursor;
    }
    7.在AndroidManifest.xml文件中使用<provider>標簽注冊Content Provider咆槽。
    <provider android:name="RegionContentProvider"
    android:authorities="mobile.android.mydata" />

  • 如何為Content Provider添加訪問權限陈轿?
    在AndroidManifest.xml文件中的<provider>設置相應的權限,并定義這個權限秦忿。
    只讀:readPermission
    只寫:wirtePermission
    讀寫:permission
    1.設置權限:
    <provider
    android:name="RegionContentProvider"
    android:authorities="mobile.android.ch11.permission.regioncontentprovider"

        android:readPermission="mobile.android.ch11.permission.regioncontentprovider.READ_REGION" />
    2.定義權限:
    <permission
        android:name="mobile.android.ch11.permission.regioncontentprovider.READ_REGION"
        android:protectionLevel="normal"
        android:label="@string/label"
        android:description="@string/description"
        />
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末麦射,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子灯谣,更是在濱河造成了極大的恐慌潜秋,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胎许,死亡現(xiàn)場離奇詭異峻呛,居然都是意外死亡罗售,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門钩述,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寨躁,“玉大人,你說我怎么就攤上這事牙勘≈翱遥” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵方面,是天一觀的道長放钦。 經(jīng)常有香客問我,道長恭金,這世上最難降的妖魔是什么操禀? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮横腿,結(jié)果婚禮上颓屑,老公的妹妹穿的比我還像新娘。我一直安慰自己蔑水,他們只是感情好邢锯,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著搀别,像睡著了一般丹擎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上歇父,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天蒂培,我揣著相機與錄音,去河邊找鬼榜苫。 笑死护戳,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的垂睬。 我是一名探鬼主播媳荒,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼驹饺!你這毒婦竟也來了钳枕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤赏壹,失蹤者是張志新(化名)和其女友劉穎鱼炒,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝌借,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡昔瞧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年指蚁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片自晰。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡凝化,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出缀磕,到底是詐尸還是另有隱情缘圈,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布袜蚕,位于F島的核電站,受9級特大地震影響绢涡,放射性物質(zhì)發(fā)生泄漏牲剃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一雄可、第九天 我趴在偏房一處隱蔽的房頂上張望凿傅。 院中可真熱鬧,春花似錦数苫、人聲如沸聪舒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽箱残。三九已至,卻和暖如春止吁,著一層夾襖步出監(jiān)牢的瞬間被辑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工敬惦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盼理,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓俄删,卻偏偏與公主長得像宏怔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子畴椰,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

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