0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Activity初學(xué)乍練

Android開發(fā)例程 ? 來源:Android開發(fā)例程 ? 作者:Android開發(fā)例程 ? 2023-04-01 22:28 ? 次閱讀

本節(jié)開始講解Android的四大組件之一的Activity(活動(dòng)),先來看下官方對(duì)于Activity的介紹:PS:官網(wǎng)文檔:Activity

Activity是一個(gè)應(yīng)用程序的組件,他在屏幕上提供了一個(gè)區(qū)域,允許用戶在上面做一些交互性的操作,比如打電話,照相,發(fā)送郵件,或者顯示一個(gè)地圖!Activity可以理解成一個(gè)繪制用戶界面的窗口,而這個(gè)窗口可以填滿整個(gè)屏幕,也可能比屏幕小或者浮動(dòng)在其他窗口的上方!

從上面這段話,我們可以得到以下信息

1. Activity用于顯示用戶界面,用戶通過Activity交互完成相關(guān)操作2. 一個(gè)App允許有多個(gè)Activity

好了,大概的引言就介紹到這里,想深入了解可以繼續(xù)看API,開始本節(jié)內(nèi)容~

1.Activity的概念與Activity的生命周期圖

注意事項(xiàng):

1. onPause()和onStop()被調(diào)用的前提是: 打開了一個(gè)新的Activity!而前者是舊Activity還可見的狀態(tài);后者是舊Activity已經(jīng)不可見!
2. 另外,親測:AlertDialog和PopWindow是不會(huì)觸發(fā)上述兩個(gè)回調(diào)方法的~

2.Activity/ActionBarActivity/AppCompatActivity的區(qū)別

在開始講解創(chuàng)建Activity之前要說下這三個(gè)的一個(gè)區(qū)別:Activity就不用說啦,后面這兩個(gè)都是為了低版本兼容而提出的提出來的,他們都在v7包下,ActionBarActivity已被廢棄,從名字就知道,ActionBar~,而在5.0后,被Google棄用了,現(xiàn)在用ToolBar...而我們現(xiàn)在在Android Studio創(chuàng)建一個(gè)Activity默認(rèn)繼承的會(huì)是:AppCompatActivity!當(dāng)然你也可以只寫Activity,不過AppCompatActivity給我們提供了一些新的東西而已!兩個(gè)選一個(gè),Just you like~

3.Activity的創(chuàng)建流程

好了,上面也說過,可以繼承Activity和AppCompatActivity,只不過后者提供了一些新的東西而已!另外,切記,Android中的四大組件,只要你定義了,無論你用沒用,都要在AndroidManifest.xml對(duì)這個(gè)組件進(jìn)行聲明,不然運(yùn)行時(shí)程序會(huì)直接退出,報(bào)ClassNotFindException...

4.onCreate()一個(gè)參數(shù)和兩個(gè)參數(shù)的區(qū)別

相信用as的朋友在重寫Act的onCreate()方法時(shí)會(huì)發(fā)現(xiàn),這玩意有兩個(gè)參數(shù):

可是正常的才只有一個(gè)參數(shù)啊:

恩呢,這就是5.0給我們提供的新的方法,要用它,先要在配置文件中為我們的Activity設(shè)置一個(gè)屬性:

android:persistableMode="persistAcrossReboots"

然后我們的Activity就擁有了持久化的能力了,一般我們會(huì)搭配另外兩個(gè)方法來使用

public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState)
public void onRestoreInstanceState(Bundle savedInstanceState, PersistableBundle persistentState)

相信有些朋友對(duì)這兩個(gè)方法名不陌生吧,前一個(gè)方法會(huì)在下述情形中被調(diào)用:

點(diǎn)擊home鍵回到主頁或長按后選擇運(yùn)行其他程序

按下電源鍵關(guān)閉屏幕

啟動(dòng)新的Activity

橫豎屏切換時(shí),肯定會(huì)執(zhí)行,因?yàn)闄M豎屏切換的時(shí)候會(huì)先銷毀Act,然后再重新創(chuàng)建 重要原則:當(dāng)系統(tǒng)"未經(jīng)你許可"時(shí)銷毀了你的activity,則onSaveInstanceState會(huì)被系統(tǒng)調(diào)用, 這是系統(tǒng)的責(zé)任,因?yàn)樗仨氁峁┮粋€(gè)機(jī)會(huì)讓你保存你的數(shù)據(jù)(你可以保存也可以不保存)。

而后一個(gè)方法,和onCreate同樣可以從取出前者保存的數(shù)據(jù):一般是在onStart()和onResume()之間執(zhí)行!之所以有兩個(gè)可以獲取到保存數(shù)據(jù)的方法,是為了避免Act跳轉(zhuǎn)而沒有關(guān)閉,然后不走onCreate()方法,而你又想取出保存數(shù)據(jù)~

說回來:說回這個(gè)Activity擁有了持久化的能力,增加的這個(gè)PersistableBundle參數(shù)令這些方法擁有了系統(tǒng)關(guān)機(jī)后重啟的數(shù)據(jù)恢復(fù)能力?。《也挥绊懳覀兤渌男蛄谢僮?,臥槽,具體怎么實(shí)現(xiàn)的,暫時(shí)還不了解,可能是另外弄了個(gè)文件保存吧~!后面知道原理的話會(huì)告知下大家!另外,API版本需要>=21,就是要5.0以上的版本才有效~

4.啟動(dòng)一個(gè)Activity的幾種方式

在Android中我們可以通過下面兩種方式來啟動(dòng)一個(gè)新的Activity,注意這里是怎么啟動(dòng),而非啟動(dòng)模式!!分為顯示啟動(dòng)和隱式啟動(dòng)!

1. 顯式啟動(dòng):通過包名來啟動(dòng),寫法如下:

①最常見的:

startActivity(new Intent(當(dāng)前Act.this,要啟動(dòng)的Act.class));

②通過Intent的ComponentName:

ComponentName cn = new ComponentName("當(dāng)前Act的全限定類名","啟動(dòng)Act的全限定類名") ;
Intent intent = new Intent() ;
intent.setComponent(cn) ;
startActivity(intent) ;

初始化Intent時(shí)指定包名:

Intent intent = new Intent("android.intent.action.MAIN");
intent.setClassName("當(dāng)前Act的全限定類名","啟動(dòng)Act的全限定類名");
startActivity(intent);

2.隱式啟動(dòng):通過Intent-filter的Action,Category或data來實(shí)現(xiàn)這個(gè)是通過Intent的 intent-filter**來實(shí)現(xiàn)的,這個(gè)Intent那章會(huì)詳細(xì)講解!這里知道個(gè)大概就可以了!

3. 另外還有一個(gè)直接通過包名啟動(dòng)apk的:

Intent intent = getPackageManager().getLaunchIntentForPackage
("apk第一個(gè)啟動(dòng)的Activity的全限定類名") ;
if(intent != null) startActivity(intent) ;

5.橫豎屏切換與狀態(tài)保存的問題

前面也也說到了App橫豎屏切換的時(shí)候會(huì)銷毀當(dāng)前的Activity然后重新創(chuàng)建一個(gè),你可以自行在生命周期 的每個(gè)方法里都添加打印Log的語句,來進(jìn)行判斷,又或者設(shè)一個(gè)按鈕一個(gè)TextView點(diǎn)擊按鈕后,修改TextView 文本,然后橫豎屏切換,會(huì)神奇的發(fā)現(xiàn)TextView文本變回之前的內(nèi)容了! 橫豎屏切換時(shí)Act走下述生命周期:
onPause-> onStop-> onDestory-> onCreate->onStart->onResume
關(guān)于橫豎屏切換可能遇到下述問題:

1.先說下如何禁止屏幕橫豎屏自動(dòng)切換吧,很簡單,在AndroidManifest.xml中為Act添加一個(gè)屬性:android:screenOrientation,有下述可選值:

unspecified:默認(rèn)值 由系統(tǒng)來判斷顯示方向.判定的策略是和設(shè)備相關(guān)的,所以不同的設(shè)備會(huì)有不同的顯示方向。

landscape:橫屏顯示(寬比高要長)

portrait:豎屏顯示(高比寬要長)

user:用戶當(dāng)前首選的方向

behind:和該Activity下面的那個(gè)Activity的方向一致(在Activity堆棧中的)

sensor:有物理的感應(yīng)器來決定。如果用戶旋轉(zhuǎn)設(shè)備這屏幕會(huì)橫豎屏切換。

nosensor:忽略物理感應(yīng)器,這樣就不會(huì)隨著用戶旋轉(zhuǎn)設(shè)備而更改了("unspecified"設(shè)置除外)。

2.橫豎屏?xí)r想加載不同的布局

1)準(zhǔn)備兩套不同的布局,Android會(huì)自己根據(jù)橫豎屏加載不同布局:創(chuàng)建兩個(gè)布局文件夾:layout-land橫屏,layout-port豎屏然后把這兩套布局文件丟這兩文件夾里,文件名一樣,Android就會(huì)自行判斷,然后加載相應(yīng)布局了!

2 )自己在代碼中進(jìn)行判斷,自己想加載什么就加載什么:

我們一般是在onCreate()方法中加載布局文件的,我們可以在這里對(duì)橫豎屏的狀態(tài)做下判斷,關(guān)鍵代碼如下:

if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){  
     setContentView(R.layout.橫屏);
}  

else if (this.getResources().getConfiguration().orientation ==Configuration.ORIENTATION_PORTRAIT) {  
    setContentView(R.layout.豎屏);
}

3. 如何讓模擬器橫豎屏切換

如果你的模擬器是GM的話。直接按模擬器上的切換按鈕即可,原生模擬器可按ctrl + f11/f12切換!

4. 狀態(tài)保存問題:

這個(gè)上面也說過了,通過一個(gè)Bundle savedInstanceState參數(shù)即可完成!三個(gè)核心方法:

onCreate(Bundle savedInstanceState);
onSaveInstanceState(Bundle outState);
onRestoreInstanceState(Bundle savedInstanceState);

你只重寫onSaveInstanceState()方法,往這個(gè)bundle中寫入數(shù)據(jù),比如:

outState.putInt("num",1);

這樣,然后你在onCreate或者onRestoreInstanceState中就可以拿出里面存儲(chǔ)的數(shù)據(jù),不過拿之前要判斷下是否為null哦!

savedInstanceState.getInt("num");

6.系統(tǒng)給我們提供的常見的Activity

好的,最后給大家附上一些系統(tǒng)給我們提供的一些常見的Activtiy吧!

//1.撥打電話
// 給移動(dòng)客服10086撥打電話
Uri uri = Uri.parse("tel:10086");
Intent intent = new Intent(Intent.ACTION_DIAL, uri);
startActivity(intent);

//2.發(fā)送短信
// 給10086發(fā)送內(nèi)容為“Hello”的短信
Uri uri = Uri.parse("smsto:10086");
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
intent.putExtra("sms_body", "Hello");
startActivity(intent);

//3.發(fā)送彩信(相當(dāng)于發(fā)送帶附件的短信)
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra("sms_body", "Hello");
Uri uri = Uri.parse("content://media/external/images/media/23");
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setType("image/png");
startActivity(intent);

//4.打開瀏覽器:
// 打開Google主頁
Uri uri = Uri.parse("http://www.baidu.com");
Intent intent  = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

//5.發(fā)送電子郵件:(閹割了Google服務(wù)的沒戲!!!!)
// 給someone@domain.com發(fā)郵件
Uri uri = Uri.parse("mailto:someone@domain.com");
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
startActivity(intent);
// 給someone@domain.com發(fā)郵件發(fā)送內(nèi)容為“Hello”的郵件
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, "someone@domain.com");
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_TEXT, "Hello");
intent.setType("text/plain");
startActivity(intent);
// 給多人發(fā)郵件
Intent intent=new Intent(Intent.ACTION_SEND);
String[] tos = {"1@abc.com", "2@abc.com"}; // 收件人
String[] ccs = {"3@abc.com", "4@abc.com"}; // 抄送
String[] bccs = {"5@abc.com", "6@abc.com"}; // 密送
intent.putExtra(Intent.EXTRA_EMAIL, tos);
intent.putExtra(Intent.EXTRA_CC, ccs);
intent.putExtra(Intent.EXTRA_BCC, bccs);
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_TEXT, "Hello");
intent.setType("message/rfc822");
startActivity(intent);

//6.顯示地圖:
// 打開Google地圖中國北京位置(北緯39.9,東經(jīng)116.3)
Uri uri = Uri.parse("geo:39.9,116.3");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

//7.路徑規(guī)劃
// 路徑規(guī)劃:從北京某地(北緯39.9,東經(jīng)116.3)到上海某地(北緯31.2,東經(jīng)121.4)
Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=39.9 116.3&daddr=31.2 121.4");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

//8.多媒體播放:
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse("file:///sdcard/foo.mp3");
intent.setDataAndType(uri, "audio/mp3");
startActivity(intent);

//獲取SD卡下所有音頻文件,然后播放第一首=-= 
Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

//9.打開攝像頭拍照:
// 打開拍照程序
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
startActivityForResult(intent, 0);
// 取出照片數(shù)據(jù)
Bundle extras = intent.getExtras(); 
Bitmap bitmap = (Bitmap) extras.get("data");

//另一種:
//調(diào)用系統(tǒng)相機(jī)應(yīng)用程序,并存儲(chǔ)拍下來的照片
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
time = Calendar.getInstance().getTimeInMillis();
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment
.getExternalStorageDirectory().getAbsolutePath()+"/tucue", time + ".jpg")));
startActivityForResult(intent, ACTIVITY_GET_CAMERA_IMAGE);

//10.獲取并剪切圖片
// 獲取并剪切圖片
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
intent.putExtra("crop", "true"); // 開啟剪切
intent.putExtra("aspectX", 1); // 剪切的寬高比為1:2
intent.putExtra("aspectY", 2);
intent.putExtra("outputX", 20); // 保存圖片的寬和高
intent.putExtra("outputY", 40); 
intent.putExtra("output", Uri.fromFile(new File("/mnt/sdcard/temp"))); // 保存路徑
intent.putExtra("outputFormat", "JPEG");// 返回格式
startActivityForResult(intent, 0);
// 剪切特定圖片
Intent intent = new Intent("com.android.camera.action.CROP"); 
intent.setClassName("com.android.camera", "com.android.camera.CropImage"); 
intent.setData(Uri.fromFile(new File("/mnt/sdcard/temp"))); 
intent.putExtra("outputX", 1); // 剪切的寬高比為1:2
intent.putExtra("outputY", 2);
intent.putExtra("aspectX", 20); // 保存圖片的寬和高
intent.putExtra("aspectY", 40);
intent.putExtra("scale", true);
intent.putExtra("noFaceDetection", true); 
intent.putExtra("output", Uri.parse("file:///mnt/sdcard/temp")); 
startActivityForResult(intent, 0);

//11.打開Google Market 
// 打開Google Market直接進(jìn)入該程序的詳細(xì)頁面
Uri uri = Uri.parse("market://details?id=" + "com.demo.app");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

//12.進(jìn)入手機(jī)設(shè)置界面:
// 進(jìn)入無線網(wǎng)絡(luò)設(shè)置界面(其它可以舉一反三)  
Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);  
startActivityForResult(intent, 0);

//13.安裝apk:
Uri installUri = Uri.fromParts("package", "xxx", null);   
returnIt = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri);

//14.卸載apk:
Uri uri = Uri.fromParts("package", strPackageName, null);      
Intent it = new Intent(Intent.ACTION_DELETE, uri);      
startActivity(it); 

//15.發(fā)送附件:
Intent it = new Intent(Intent.ACTION_SEND);      
it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");      
it.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/eoe.mp3");      
sendIntent.setType("audio/mp3");      
startActivity(Intent.createChooser(it, "Choose Email Client"));

//16.進(jìn)入聯(lián)系人頁面:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(People.CONTENT_URI);
startActivity(intent);

//17.查看指定聯(lián)系人:
Uri personUri = ContentUris.withAppendedId(People.CONTENT_URI, info.id);//info.id聯(lián)系人ID
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(personUri);
startActivity(intent);

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Android
    +關(guān)注

    關(guān)注

    12

    文章

    3903

    瀏覽量

    126625
  • 組件
    +關(guān)注

    關(guān)注

    1

    文章

    495

    瀏覽量

    17733
  • Android平臺(tái)
    +關(guān)注

    關(guān)注

    0

    文章

    10

    瀏覽量

    8109
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    ADXL345 activity無法進(jìn)入中斷怎么解決?

    最近在使用ADXL345,想使用ADXL345的activity中斷功能,讓單片機(jī)一直讀取中斷信號(hào)INT2,但一直無法進(jìn)入activity中斷,請(qǐng)高手指點(diǎn)!!!。 程序如下; void
    發(fā)表于 12-28 06:55

    ADXL345無論怎么晃動(dòng)始終檢測不到Activity信號(hào)是為什么?

    (DATA_FORMAT,0x20); //μíμ???óDD§ ADXL345_WR_Reg(INT_MAP,(u8)~Activity); // ??Activity?D??ó3é?μ? INT1
    發(fā)表于 01-01 08:20

    求霍爾電流電壓傳感器接入電路中到連接單片機(jī)的電路圖

    希望各位大大幫幫忙,我初學(xué),什么都不懂,希望有哪位好心的幫幫忙弄個(gè)電路圖,電流和電壓傳感器采集信號(hào)到單片機(jī)這一段的,急用,謝謝了:handshake
    發(fā)表于 05-26 16:42

    labview編程求助,各位大俠請(qǐng)留步看一看

    這個(gè)用PCI-6251采集卡采集數(shù)據(jù),然后顯示時(shí)域、頻域和經(jīng)過PGC算法的波形圖并可以儲(chǔ)存數(shù)據(jù)的程序,現(xiàn)在需要在維持原功能不變的情況下變一路采集為兩路同時(shí)采集并工作。小弟初學(xué),改不明白了。求各位
    發(fā)表于 12-17 09:40

    LabVIEW\activity

    正在學(xué)習(xí)教程,但是、教程里面介紹的文件夾LabVIEW\activity,我怎么找不到呢?需要Generate Waveform VI。我現(xiàn)在用的是2010
    發(fā)表于 05-21 22:35

    在線分享PCB和3D作品,贏京東購物卡

    /company/RS/Begin.html 作品提交說明:請(qǐng)?jiān)贒esignSpark小組討論發(fā)布最終設(shè)計(jì)成果發(fā)帖格式:【初學(xué)】+標(biāo)題 例如:【初學(xué)
    發(fā)表于 06-13 00:31

    labview入門教程,每日一

    入門教程,每日一第一期 簡單溫度波形圖程序設(shè)計(jì)我也是初學(xué)者,可以一起學(xué)習(xí)討論
    發(fā)表于 09-05 14:26

    labview入門教程,每日一3

    入門教程,每日一第三期 用三種方法實(shí)現(xiàn)公式Y(jié)=AX[sup]2[/sup]+BX+C的計(jì)算我也是初學(xué)者,可以一起學(xué)習(xí)討論
    發(fā)表于 09-05 23:15

    ADXL345無法產(chǎn)生Activity中斷

    (DATA_FORMAT,0x20); //μíμ???óDD§ ADXL345_WR_Reg(INT_MAP,(u8)~Activity); // ??Activity
    發(fā)表于 09-13 11:33

    web前端編程與嵌入式編程有哪些不同之處呢

    初學(xué)的嵌入式web開發(fā)者對(duì)于兩種編程方式的一點(diǎn)體會(huì)
    發(fā)表于 12-22 07:14

    直接法UKF在組合導(dǎo)航中的應(yīng)用_玉新

    直接法UKF在組合導(dǎo)航中的應(yīng)用_玉新
    發(fā)表于 03-20 09:09 ?3次下載

    Android Activity啟動(dòng)模式的詳解

    singleInstance:和singleTask差不多,唯一不同的是singleInstance Activity實(shí)例的Task只能存放一個(gè)該模式的Activity實(shí)例,例如Qactivity
    的頭像 發(fā)表于 04-18 15:47 ?3907次閱讀

    android的Activity應(yīng)用

    android的Activity應(yīng)用(電力電子電源技術(shù)及應(yīng)用課后答案)-android的Activity應(yīng)用,有需要的可以參考!
    發(fā)表于 08-31 13:22 ?1次下載
    android的<b class='flag-5'>Activity</b>應(yīng)用

    android-Activity

    android-Activity(深圳普德新星電源技術(shù)有限公司怎樣)-android-Activity,有需要的可以參考!
    發(fā)表于 08-31 15:51 ?1次下載
    android-<b class='flag-5'>Activity</b>

    Android開發(fā)—使用ActivityGroup來切換Activity和Layout

    Android開發(fā)—使用ActivityGroup來切換Activity和Layout(ups電源技術(shù)參數(shù))-該文檔為Android開發(fā)—使用ActivityGroup來切換Activity和Layout講解文檔,是一份還算不錯(cuò)的參考文檔,感興趣的可以下載看看,,,,,,
    發(fā)表于 09-27 15:36 ?3次下載
    Android開發(fā)—使用ActivityGroup來切換<b class='flag-5'>Activity</b>和Layout