全面解析Android應(yīng)用開(kāi)發(fā)中Activity類的用法
Activity類處于android.app包中,繼承體系如下:
1.java.lang.Object
2.android.content.Context
3.android.app.ApplicationContext
4.android.app.Activity
activity是單獨(dú)的,用于處理用戶操作。幾乎所有的activity都要和用戶打交道,所以activity類創(chuàng)建了一個(gè)窗口,開(kāi)發(fā)人員可以通過(guò)setContentView(View)接口把UI放到activity創(chuàng)建的窗口上,當(dāng)activity指向全屏窗口時(shí),也可以用其他方式實(shí)現(xiàn):作為漂浮窗口(通過(guò)windowIsFloating的主題集合),或者嵌入到其他的activity(使用ActivityGroup)。大部分的Activity子類都需要實(shí)現(xiàn)以下兩個(gè)接口:
onCreate(Bundle)接口是初始化activity的地方. 在這兒通??梢哉{(diào)用setContentView(int)設(shè)置在資源文件中定義的UI, 使用findViewById(int) 可以獲得UI中定義的窗口.
onPause()接口是使用者準(zhǔn)備離開(kāi)activity的地方,在這兒,任何的修改都應(yīng)該被提交(通常用于ContentProvider保存數(shù)據(jù)).
為了能夠使用Context.startActivity(),所有的activity類都必須在AndroidManifest.xml文件中定義有相關(guān)的“activity”項(xiàng)。
Activity類是Android 應(yīng)用生命周期的重要部分。下面我們具體來(lái)總結(jié)一下Activity的各個(gè)要點(diǎn):
一、Activity的生命周期
二、Activity之間傳遞數(shù)據(jù)
1. 通過(guò)Intent傳遞數(shù)據(jù)
通過(guò)Intent.putExtra方法可以將簡(jiǎn)單數(shù)據(jù)類型或可序列化對(duì)象保存在Intent對(duì)象中,然后在另一個(gè)Activity中使用getInt、getString等方法獲得這些數(shù)據(jù)。示例代碼如下:
Intent intent =new Intent(CurrentActivity.this,OtherActivity.class); // 創(chuàng)建一個(gè)帶“收件人地址”的 email Bundle bundle =new Bundle();// 創(chuàng)建 email 內(nèi)容 bundle.putBoolean("boolean_key", true);// 編寫(xiě)內(nèi)容 bundle.putString("string_key", "string_value"); intent.putExtra("key", bundle);// 封裝 email startActivity(intent);// 啟動(dòng)新的 Activity
下面是獲取數(shù)據(jù):
Intent intent =getIntent();// 收取 email Bundle bundle =intent.getBundleExtra("key");// 打開(kāi) email bundle.getBoolean("boolean_key");// 讀取內(nèi)容 bundle.getString("string_key");
不過(guò)使用Bundle傳遞數(shù)據(jù)稍顯麻煩,如果你只需要傳遞一種類型的值可以這樣:
Intent intent =new Intent(EX06.this,OtherActivity.class); intent.putExtra("boolean_key", true); intent.putExtra("string_key", "string_value"); startActivity(intent);
獲取數(shù)據(jù):
Intent intent=getIntent(); intent.getBooleanExtra("boolean_key",false); intent.getStringExtra("string_key");
2. 通過(guò)靜態(tài)變量傳遞數(shù)據(jù)
適用于不可序列化的且簡(jiǎn)單的對(duì)象,不過(guò)不推薦使用靜態(tài)代碼塊
public class MainActivity extends Activity { private Button btn; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = (Button)findViewById(R.id.btOpenOtherActivity); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //定義一個(gè)意圖 Intent intent = new Intent(MainActivity.this,OtherActivity.class); //改變OtherActivity的三個(gè)靜態(tài)變量的值 OtherActivity.name = "wulianghuan"; OtherActivity.age = "22"; OtherActivity.address = "上海閔行"; startActivity(intent); } }); } } public class OtherActivity extends Activity { public static String name; public static String age; public static String address; private TextView text_name; private TextView text_age; private TextView text_address; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.other); text_name = (TextView) findViewById(R.id.name); text_age = (TextView) findViewById(R.id.age); text_address = (TextView) findViewById(R.id.address); //設(shè)置文本框的數(shù)據(jù) text_name.setText("姓名:"+name); text_age.setText("年齡:"+age); text_address.setText("地址:"+address); } }
3.通過(guò)全局對(duì)象傳遞數(shù)據(jù)
如果想使某些數(shù)據(jù)長(zhǎng)時(shí)間駐留內(nèi)存,以便程序隨時(shí)調(diào)用,建議采用全局對(duì)象。Application全局類不需要定義靜態(tài)變量只要定義普通成員變量即可,但全局類中必須有一個(gè)無(wú)參構(gòu)造方法,編寫(xiě)完Application類后,還需要在<application>標(biāo)簽中制定全局類名,否則系統(tǒng)不會(huì)自動(dòng)創(chuàng)建全局對(duì)象。
public class MainApplication extends Application { private String username; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } } public class MainActivity extends Activity { private MainApplication application; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); application = (MainApplication) getApplication(); application.setUsername("sunzn"); } public void open(View view) { Intent intent = new Intent(this, OtherActivity.class); startActivity(intent); } } public class OtherActivity extends Activity { private TextView tv_data; private MainApplication application; private String username; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_other); application = (MainApplication) getApplication(); username = application.getUsername(); tv_data = (TextView) findViewById(R.id.tv_data); tv_data.setText("從上一個(gè) Activity 中獲取到的數(shù)據(jù)為:" + username); } }
三、從Activity返回?cái)?shù)據(jù)
要從Activity返回?cái)?shù)據(jù),需要使用startActivityForResult方法來(lái)顯示Activity。
從Activity1跳轉(zhuǎn)到Activity2:
Intent intent = new Intent(); intent = intent.setClass(ActivityIntent.this, AnotherActivity.class); Bundle bundle = new Bundle(); bundle.putString("string", et_string.getText().toString()); intent.putExtras(bundle); startActivityForResult(intent,0); //只有這里不同
從Activity2返回?cái)?shù)據(jù)到Aactivity1:
Intent intent = new Intent(); intent = intent.setClass(AnotherActivity.this, ActivityIntent.class); Bundle bundle = new Bundle(); bundle.putInt("result", "Activity2的處理結(jié)果"); intent.putExtras(bundle); AnotherActivity.this.setResult(RESULT_OK, intent); //RESULT_OK是返回狀態(tài)碼 AnotherActivity.this.finish();
在Activity1中重寫(xiě)onActivityResault方法,接受數(shù)據(jù):
protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch(resultCode) { //根據(jù)狀態(tài)碼,處理返回結(jié)果 case RESULT_OK: Bundle bundle =data.getExtras(); //獲取intent里面的bundle對(duì)象 String result = bundle.getInt("result"); break; default: break; } }
四、Activity的四種創(chuàng)建模式
我們?cè)陂_(kāi)發(fā)項(xiàng)目的過(guò)程中,會(huì)涉及到該應(yīng)用中多個(gè)Activity組件之間的跳轉(zhuǎn),或者夾帶其它應(yīng)用的可復(fù)用的Activity。例如我們可能希望跳轉(zhuǎn)到原來(lái)某個(gè)Activity實(shí)例,而不是產(chǎn)生大量重復(fù)的 Activity。這樣就需要我們?yōu)?Activity 配置特定的加載模式,而不是使用默認(rèn)的加載模式。設(shè)置啟動(dòng)模式的位置在 Manifest.xml 文件中 Activity的android:launchMode 屬性
1.standard 模式
這是默認(rèn)模式,無(wú)需設(shè)置,每次激活A(yù)ctivity時(shí)都會(huì)創(chuàng)建Activity實(shí)例,并放入任務(wù)棧中。相當(dāng)于入棧,按back鍵返回到前一個(gè)Activity相當(dāng)于退棧。
2.singleTop 模式
如果在任務(wù)的棧頂正好存在該Activity的實(shí)例,就重用該實(shí)例( 會(huì)調(diào)用實(shí)例的 onNewIntent()),否則就會(huì)創(chuàng)建新的實(shí)例并放入棧頂,即使棧中已經(jīng)存在該Activity的實(shí)例,只要不在棧頂,都會(huì)創(chuàng)建新的實(shí)例。可用來(lái)解決棧頂多個(gè)重復(fù)相同的Activity的問(wèn)題
3.singleTask 模式
如果在棧中已經(jīng)有該Activity的實(shí)例,就重用該實(shí)例(會(huì)調(diào)用實(shí)例的 onNewIntent() )。重用時(shí),會(huì)讓該實(shí)例回到棧頂,因此在它上面的實(shí)例將會(huì)被移出棧。如果棧中不存在該實(shí)例,將會(huì)創(chuàng)建新的實(shí)例放入棧中。singleTask 模式可以用來(lái)退出整個(gè)應(yīng)用。將主Activity設(shè)為SingTask模式,然后在要退出的Activity中轉(zhuǎn)到主Activity,然后重寫(xiě)主Activity的onNewIntent函數(shù),并在函數(shù)中加上一句finish。
4.singleInstance 模式
在一個(gè)新棧中創(chuàng)建該Activity的實(shí)例,并讓多個(gè)應(yīng)用共享該棧中的該Activity實(shí)例。一旦該模式的Activity實(shí)例已經(jīng)存在于某個(gè)棧中,任何應(yīng)用再激活該Activity時(shí)都會(huì)重用該棧中的實(shí)例( 會(huì)調(diào)用實(shí)例的 onNewIntent() )。其效果相當(dāng)于多個(gè)應(yīng)用共享一個(gè)應(yīng)用,不管誰(shuí)激活該 Activity 都會(huì)進(jìn)入同一個(gè)應(yīng)用中。
五、Activity現(xiàn)場(chǎng)保存狀態(tài)
一般來(lái)說(shuō),調(diào)用onPause()和onStop()方法后的activity實(shí)例仍然存在于內(nèi)存中,activity的所有信息和狀態(tài)數(shù)據(jù)不會(huì)消失, 當(dāng)activity重新回到前臺(tái)之后, 所有的改變都會(huì)得到保留。但是當(dāng)系統(tǒng)內(nèi)存不足時(shí), 調(diào)用onPause()和onStop()方法后的activity可能會(huì)被系統(tǒng)摧毀, 此時(shí)內(nèi)存中就不會(huì)存有該activity的實(shí)例對(duì)象了. 如果之后這個(gè)activity重新回到前臺(tái), 之前所作的改變就會(huì)消失.可以在activity被殺掉之前調(diào)用保存每個(gè)實(shí)例的狀態(tài),開(kāi)發(fā)者可以覆寫(xiě)onSaveInstanceState()方法. onSaveInstanceState()方法接受一個(gè)Bundle類型的參數(shù), 開(kāi)發(fā)者可以將狀態(tài)數(shù)據(jù)存儲(chǔ)到這個(gè)Bundle對(duì)象中,以保證該狀態(tài)在onCreate(Bundle)或者onRestoreInstanceState(Bundle)(傳入的Bundle參數(shù)是由onSaveInstanceState封裝好的)中恢復(fù)。這個(gè)方法在一個(gè)activity被殺死前調(diào)用,當(dāng)該activity在將來(lái)某個(gè)時(shí)刻回來(lái)時(shí)可以恢復(fù)其先前狀態(tài)。如果調(diào)用onSaveInstanceState()方法,調(diào)用將發(fā)生在onPause()或onStop()方法之前,而且它也不是生命周期的方法。
若向數(shù)據(jù)庫(kù)中插入記錄等,保存持久化數(shù)據(jù)的操作應(yīng)該放在onPause()中. onSaveInstanceState()方法只適合保存瞬態(tài)數(shù)據(jù), 比如UI控件的狀態(tài), 成員變量的值等.
public class MainActivity extends Activity { private String temp; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 從savedInstanceState中恢復(fù)數(shù)據(jù), 如果沒(méi)有數(shù)據(jù)需要恢復(fù)savedInstanceState為null if (savedInstanceState != null) { temp = savedInstanceState.getString("temp"); System.out.println("onCreate: temp = " + temp); } } public void onRestoreInstanceState(Bundle saveInstanceState) { super.onRestoreInstanceState( saveInstanceState); String temp = saveInstanceState.getString("temp"); System.out.println("onResume: temp = " + temp); } // 將數(shù)據(jù)保存到outState對(duì)象中, 該對(duì)象會(huì)在重建activity時(shí)傳遞給onCreate方法和onRestoreInstanceState方法 @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString("temp", temp); }
六、一些關(guān)于Activity的技巧
1.設(shè)置Activity的方向
android:screenOrientation="portrait">// 豎屏 , 值為 landscape 時(shí)為橫屏
2.設(shè)置Activity全屏
在onCreate方法中添加如下代碼:
// 設(shè)置全屏模式 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // 去除標(biāo)題欄 requestWindowFeature(Window.FEATURE_NO_TITLE);
改變窗口大小、位置、透明度
在onCreate方法中添加如下代碼:
Window w=getWindow(); w.setBackgroundDrawableResource(resourceID);//設(shè)置窗口背景 WindowManager.LayoutParams layoutParams = w.getAttributes(); layoutParams.height = 200; layoutParams.width= 200; layoutParams.gravity = Gravity.TOP; layoutParams.x=50;//距離Gravity屬性的距離 layoutParams.y=50; layoutParams.alpha = 0.5;//0:完全透明,1:不透明 w.setAttributes(layoutParams);
3.關(guān)閉所有窗口
Intent intent = new Intent(); intent.setClass(Android123.this, CWJ.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); //注意本行的FLAG設(shè)置 startActivity(intent)
另一種方法:在調(diào)用退出方法中寫(xiě)上MyApplication.getInstance().exit();
public class MyApplication extends Application { private List<Activity> activityList = new LinkedList<Activity>(); private static MyApplication instance; private MyApplication() { } // 單例模式中獲取唯一的MyApplication實(shí)例 public static MyApplication getInstance() { if (null == instance) { instance = new MyApplication(); } return instance; } // 添加Activity到容器中 public void addActivity(Activity activity) { activityList.add(activity); } // 遍歷所有Activity并finish /* * 在每一個(gè)Activity中的onCreate方法里添加該Activity到MyApplication對(duì)象實(shí)例容器中 * * MyApplication.getInstance().addActivity(this); * * 在需要結(jié)束所有Activity的時(shí)候調(diào)用exit方法 * * MyApplication.getInstance().exit(); */ public void exit() { for (Activity activity : activityList) { activity.finish(); } System.exit(0); }
- Android獲得當(dāng)前正在顯示的activity類名的方法
- android的activity跳轉(zhuǎn)到另一個(gè)activity
- Android基礎(chǔ)之Fragment與Activity交互詳解
- android獲取當(dāng)前運(yùn)行Activity名字的方法
- android Activity相對(duì)布局的使用方法
- android 獲取上一個(gè)activity返回值的方法
- Android 多個(gè)Activity之間的傳值
- Android中通過(guò)view方式獲取當(dāng)前Activity的屏幕截圖實(shí)現(xiàn)方法
- 19個(gè)Android常用工具類匯總
- Android開(kāi)發(fā)之Activity管理工具類完整示例
相關(guān)文章
解決Android快速滑動(dòng)時(shí)圖片一閃一閃問(wèn)題
這篇文章主要給大家介紹了個(gè)人在解決Android快速滑動(dòng)時(shí)圖片一閃一閃問(wèn)題的一些思路和方法,非常實(shí)用,有需要的小伙伴可以參考下。2015-07-07Android實(shí)現(xiàn)帶圓環(huán)的圓形頭像
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)帶圓環(huán)的圓形頭像,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08詳解有關(guān)Android截圖與錄屏功能的學(xué)習(xí)
這篇文章主要介紹了詳解有關(guān)Android截圖與錄屏功能的學(xué)習(xí),詳細(xì)介紹如何使用MediaProjection,MediaCodec以及MediaMuxer來(lái)實(shí)現(xiàn)簡(jiǎn)單的截屏和錄屏功能。2017-04-04Android實(shí)現(xiàn)微信支付的統(tǒng)一下單
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)微信支付的統(tǒng)一下單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06詳解Android6.0運(yùn)行時(shí)權(quán)限管理
自從Android6.0發(fā)布以來(lái),在權(quán)限上做出了很大的變動(dòng),不再是之前的只要在manifest設(shè)置就可以任意獲取權(quán)限,而是更加的注重用戶的隱私和體驗(yàn)。本文詳細(xì)介紹了Android6.0運(yùn)行時(shí)權(quán)限管理。需要的朋友一起來(lái)看下吧2016-12-12Android音頻開(kāi)發(fā)之SurfaceView的使用詳解
這篇文章主要為大家介紹了Android中SurfaceView的使用方法,本文通過(guò)簡(jiǎn)要的案例,為大家進(jìn)行了詳細(xì)的講解,需要的朋友可以參考一下2022-04-04Android App中使用ViewPager實(shí)現(xiàn)滑動(dòng)分頁(yè)的要點(diǎn)解析
這篇文章主要介紹了Android App中使用ViewPager實(shí)現(xiàn)滑動(dòng)分頁(yè)的要點(diǎn)解析,還附帶了一個(gè)禁止ViewPager左右滑動(dòng)的方法,需要的朋友可以參考下2016-06-06