對於應用的退出,我一直以來都有一個誤區,我曾經簡單地認為,finish()是結束一個Activity的,System.exit(0)是結束整個Application的,直到有一天.....
---------------------我是華麗的分割線--------------------這是一個驚悚的故事------------------------------------------------------------------------------------------
曾經,有一個android應用是這樣的:
主Activity的布局文件:
復制代碼
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:paddingBottom="@dimen/activity_vertical_margin"
6 android:paddingLeft="@dimen/activity_horizontal_margin"
7 android:paddingRight="@dimen/activity_horizontal_margin"
8 android:paddingTop="@dimen/activity_vertical_margin"
9 tools:context=".MainActivity" >
10
11 <TextView
12 android:id="@+id/txt"
13 android:layout_width="match_parent"
14 android:layout_height="wrap_content"
15 android:layout_alignParentTop="true"
16 android:text="this is the first activity" />
17
18 <Button
19 android:id="@+id/btn"
20 android:layout_width="wrap_content"
21 android:layout_height="wrap_content"
22 android:layout_below="@+id/txt"
23 android:layout_centerHorizontal="true"
24 android:onClick="btnClick"
25 android:text="跳轉" />
26
27 </RelativeLayout>
復制代碼
請不要關注那些不太規范的細節,這只是一個故事!
然後Activity(Launcher)是這個樣子的:
復制代碼
1 public class MainActivity extends Activity {
2
3 @Override
4 protected void onCreate(Bundle savedInstanceState) {
5 super.onCreate(savedInstanceState);
6 setContentView(R.layout.activity_main);
7 }
8
9 public void btnClick(View v){
10 Intent intent=new Intent(MainActivity.this,SecondActivity.class);
11 startActivity(intent);
12 this.finish();//注意這個地方,接下來就是見證奇跡的時刻!!!
13 }
14
15 }
復制代碼
我們可以看到,我們還需要一個跳轉的Activity,在這裡:
復制代碼
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
LinearLayout layout=new LinearLayout(this);
TextView txt=new TextView(this);
txt.setText("this is the second activity");
Button btn=new Button(this);
btn.setText("退出");
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
System.exit(0);
}
});
layout.addView(txt);
layout.addView(btn);
setContentView(layout);
}
}
復制代碼
好了,一個最簡單的跳轉、關閉功能的android應用完成了。下面是效果圖:
這似乎驗證了System.exit(0)的有效性,但是,讓我們回去看下Activity(Launcher)的代碼,對,就是加注釋那句,讓我們去掉他會怎樣呢?
接下來就是見證奇跡的時刻:
System.exit(0)失效了!!!!
------------------------------------------故事講完了----------------------實在是驚悚-------------------------------------------------------------------------------------
為什麼會出現這種效果呢,這是因為
finish():結束當前Activity,不會立即釋放內存。遵循android內存管理機制。遵循activity的生命周期。
System.exit():結束當前組件如Activity,並立即釋放當前Activity所占資源。不遵循activity的生命周期。
其實這裡我是有疑問的,android是一個進程一個虛擬機,同一應用的activity默認是在同一個進程的,System.exit(0)(參數0代表正常退出)的作用是終止當前運行的虛擬機,為什麼不能結束整個應用呢?如有了解的大神還望不吝指導。
說到這裡,我們就需要考慮在沒有將後台activity finish掉的情況下,怎樣在前台activity退出整個應用?(在這裡,我們不考慮釋放內存、Service等其他組件的關閉以及可能需要在activity生命周期中處理的一系列操作)
現在流行的靠譜方法有兩種:一種是使用單例模式創建一個自定義棧來管理activity,實現exit()方法遍歷所有activity並finish()掉,但是我不喜歡並且沒用過這種方法,所以有需要的可以自己在網上搜索,例子還是蠻多的。我在這裡要介紹的是第二種方法,創建activity基類BaseActivity完成退出。
具體的實現是這樣的:
先創建一個基類BaseActivity
復制代碼
1 public class BaseActivity extends Activity {
2 public Activity activity;
3 public ExitAllBroadCast exitAllBroadCast;
4
5 @Override
6 protected void onCreate(Bundle savedInstanceState) {
7 super.onCreate(savedInstanceState);
8 activity = BaseActivity.this;
9 exitAllBroadCast = new ExitAllBroadCast();
10
11 }
12
13 @Override
14 protected void onStart() {
15 IntentFilter filter = new IntentFilter();// 創建IntentFilter對象
16 filter.addAction("com.all.exit.broadcast");
17 registerReceiver(exitAllBroadCast, filter);// 注冊Broadcast Receiver
18 super.onStart();
19 }
20 class ExitAllBroadCast extends BroadcastReceiver{
21
22 @Override
23 public void onReceive(Context context, Intent intent) {
24
25 activity.finish();
26 }
27
28 }
29 @Override
30 protected void onDestroy() {
31
32 super.onDestroy();
33 unregisterReceiver(exitAllBroadCast);
34 }
35 }
復制代碼
在基類中,我們注冊了一個廣播接收器,當接收到“com.all.exit.broadcast”廣播時,就執行finish()。
現在,我們讓所有的Activity都來繼承這個BaseActivity,當我們想要退出的時候,發送廣播就好了
1 Intent myIntent = new Intent();// 創建Intent對象
2 myIntent.setAction("com.all.exit.broadcast");
3 sendBroadcast(myIntent);// 發送廣播