在Android開發中,我們運行了應用程序后,都需要退出應用的,那么該如何退出應用,又都有哪些實現方式呢?今天就為大家整理分享一些退出應用程序的方法,一起來看看吧!
更新內容
Ver:v1
Ver:v2
1. finish方法
finish();
該方法只是結束當前Activity,系統將最上面的Activity移出了棧,并沒有清理占用的資源。如果棧內有很多Activity 的話,使用該方法顯得有點捉襟見肘了,沒辦法一次移出全部Activity,并且沒有立即釋放內存,活動的資源也沒有被清理。
2. 進程式
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);//正常退出System.exit(1);//非正常退出
KillProcess() 和 System.exit(),許多人都使用過,當你棧里只有一個Activity的時候,這個措施是行之有效的。但當關閉多個Activity的時候,棧里有多個Activity時,這兩個方法就不起作用了。 因為通過殺進程方式退出,會被系統認為異常退出,會保存應用的一些狀態信息比如Activity運行棧,然后會恢復這個應用。當恢復一個Android應用程序時,會先從棧里面移除異常的Activity,相當于Back鍵操作。
3. 根據Activity的生命周期
Android的窗口類提供了歷史棧,可以通過stack的原理來巧妙的實現。在A窗口打開B窗口的時候,在Intent中直接加入標識Intent.FLAG_ACTIVITY_CLEAR_TOP
,這樣開啟B時,會清除該進程空間的所有Activity。 1)在A窗口中調用該方法跳轉到B窗口:
Intent intent = new Intent();intent.setClass(AActivity.this,BActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);startActivity(intent);
2)在B窗口退出時直接使用 finish 方法即可全部退出
finish();
4. 任務管理器
系統將終止一切和這個程序包關聯的,所有共享同一 uid 的 process全部殺掉,還會停止相關的服務,并且會發送一個廣播。
<uses-permission android:name="android.permission.RESTART_PACKAGES"/>
ActivityManager am = (ActivityManager)getSystemService (Context.ACTIVITY_SERVICE);am.restartPackage(getPackageName());
但是在 Android 2.2(API 8)之后,restartPackage
方法已經過時,不可以將應用程序結束,需要使用ActivityManager
類的killBackgroundProcesses
方法。
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
ActivityManager am = (ActivityManager)getSystemService (Context.ACTIVITY_SERVICE);am.killBackgroundProcesses(getPackageName());System.exit(0);
注意事項:該方法雖然可以立即殺死與指定包相關聯的所有后臺進程,但是這些進程如果在將來某一時刻需要使用,便會重新啟動。而且該方法只是結束后臺進程的方法,不能結束當前應用移除所有的 Activity。如果需要退出應用,需要添加
System.exit(0)
方法一起使用,并且只限棧內只有一個Activity,如果有多個Activity時,正如上面 方法 2 所說,就不起作用了。
5. 任務棧式
利用一個單例模式的Activity棧來管理所有Activity 1)自定義 Application類,儲存每一個Activity,并實現關閉所有Activity的操作
public class MyApplication extends Application { private List<Activity> activityList = new LinkedList<Activity>(); private static MyApplication instance;/***單例模式 1:*/ private MyApplication() { } public static MyApplication getInstance() { if(null == instance) { instance = new MyApplication(); } return instance; } @Override public void onCreate() { super.onCreate(); } /***單例模式 2:*/// public static MyApplication getInstance() {// return instance;// }// @Override// public void onCreate() {// super.onCreate();// instance = this; // } //添加Activity到容器中 public void addActivity(Activity activity) { activityList.add(activity); } //遍歷所有Activity并finish public void exit() { for(Activity activity:activityList) { activity.finish(); } activityList.clear(); }}
2)在父類BaseActivity中添加繼承子類Activity到棧中
public class BaseActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 添加Activity到堆棧 MyApplication.getInstance().addActivity(this); } ...}
3)在需要結束所有Activity的時候調用 exit 方法
MyApplication.getInstance().exit();
6. 容器式
類似 5(任務棧式),自定義一個Actiivty棧,通過單例模式的Activity棧來管理所有Activity 1)建立一個全局容器,把所有的Activity存儲起來
public class BaseActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 添加Activity到堆棧 AtyContainer.getInstance().addActivity(this); } ...}
2)創建Activity管理類
public class AtyContainer { public AtyContainer() { } private static AtyContainer instance = new AtyContainer(); private static List<Activity> activityStack = new ArrayList<Activity>(); public static AtyContainer getInstance() { return instance; } /** * 添加Activity到堆棧 */ public void addActivity(Activity activity) { if (activityStack == null) { activityStack = new ArrayList<Activity>(); } activityStack.add(activity); } /** * 移除指定的Activity */ public void removeActivity(Activity activity) { if (activity != null) { activityStack.remove(activity); activity = null; } } /** * 結束所有Activity */ public void finishAllActivity() { for (int i = 0, size = activityStack.size(); i < size; i++) { if (null != activityStack.get(i)) { activityStack.get(i).finish(); } } activityStack.clear(); }}
3)在退出時循環遍歷finish所有Activity
AtyContainer.getInstance().finishAllActivity();
方法 5(任務棧式)和 6(容器式),是目前許多人常用的,但是需要注意的是:activityStack持有Activity的強引用,當某個Activity異常退出時,activityStack沒有及時釋放掉引用,可能會導致內存問題。
7. 清空堆棧
1)設置MainActivity的加載模式為singleTask
android:launchMode="singleTask"
2)重寫MainActivity中的onNewIntent方法
@Overrideprotected void onNewIntent(Intent intent) { super.onNewIntent(intent); if (intent != null) { boolean isExit = intent.getBooleanExtra("exit", false); if (isExit) { finish(); } }}
3)需要退出時在Intent中添加退出的Tag
/**退出程序*/protected void exit() { // 這里使用clear + new task的方式清空整個任務棧,只保留新打開的Main頁面 // 然后Main頁面接收到退出的標志位exit=true,finish自己,這樣就關閉了全部頁面 Intent intent = new Intent(this, MainActivity.class); intent.putExtra("exit", true); startActivity(intent);}
8. 銷毀任務棧
直接調用系統 API獲取當前的任務棧,把里面的Activity全部銷毀掉。不過該方法簡單粗暴,需要 API 21(Android 5.0)以上才可以使用。
@TargetApi(Build.VERSION_CODES.LOLLIPOP) private void exitAPP() { ActivityManager activityManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.AppTask> appTaskList = activityManager.getAppTasks(); for (ActivityManager.AppTask appTask : appTaskList) { appTask.finishAndRemoveTask(); } }
9. 廣播式
通過在全局中注冊一個廣播,當退出時發送一個廣播退出 1)在BaseActivity中注冊廣播
public class BaseActivity extends Activity { private static final String EXITACTION = "action.exit"; private ExitReceiver exitReceiver = new ExitReceiver(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); IntentFilter filter = new IntentFilter(); filter.addAction(EXITACTION); registerReceiver(exitReceiver, filter); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(exitReceiver); } class ExitReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { finish(); } }}
2)發送廣播退出
public class MainActivity extends BaseActivity { private long exitTime = 0; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }// 物理返回鍵,雙擊退出 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) { if ((System.currentTimeMillis() - exitTime) > 2000) { Toast.makeText(MainActivity.this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); exitTime = System.currentTimeMillis(); } else { //發送廣播退出程序 Intent intent = new Intent("com.xxx.BaseActivity"); intent.putExtra(EXITACTION, 1); sendBroadcast(intent); } return true; } return super.onKeyDown(keyCode, event); }}
10. 懶人式
1)將MainActivity設置為singleTask
android:launchMode="singleTask"
2)將退出出口放置在MainActivity
private boolean mIsExit;/**雙擊返回鍵退出*/@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (mIsExit) { this.finish(); } else { Toast.makeText(MainActivity.this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); mIsExit = true; new Handler().postDelayed(new Runnable() { @Override public void run() { mIsExit = false; } }, 2000); } return true; } return super.onKeyDown(keyCode, event);}...
11. 退回系統桌面
Android應用開發中,有一種場景,就是我們不希望用戶直接按Back鍵退出Activity,而是希望應用隱藏到后臺的假退出,類似于按Home鍵的效果。(例如QQ、微信等)
方法一:
moveTaskToBack(true);//將Activity退到后臺,注意不是finish()退出。
方法二:
/**退出程序**/protected void exit() { Intent startMain = new Intent(Intent.ACTION_MAIN); startMain.addCategory(Intent.CATEGORY_HOME); startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(startMain); System.exit(0);}
方法三:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:andro package="com.xxx.xxx" android:versionCode="1" android:versionName="1.0.1"> <application> <activity android:name="com.xxx.xxx.MainActivity" android:label="@string/app_name" android:launchMode="singleTask" android:clearTaskOnLaunch="true" android:stateNotNeeded="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> ... </application></manifest>
12. 監聽式
從Android 4.0(API 14)開始,Application中多了一個可以設置全局監聽Activity生命周期的方法:registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback),其中傳入的參數 ActivityLifecycleCallbacks能得到全局所有Activity生命周期的回調,所以我們可以從Application中全局監聽所有Activity并對其進行管理
public class MyApplication extends Application { protected static Context context; /** * 維護Activity 的list */ private static List<Activity> mActivitys = Collections.synchronizedList(new LinkedList<Activity>()); @Override public void onCreate() { super.onCreate(); context = this.getApplicationContext(); registerActivityListener(); } public static Context getContext() { return context; } /** * @param activity 作用說明 :添加一個activity到管理里 */ public void pushActivity(Activity activity) { mActivitys.add(activity); } /** * @param activity 作用說明 :刪除一個activity在管理里 */ public void popActivity(Activity activity) { mActivitys.remove(activity); } /** * get current Activity 獲取當前Activity(棧中最后一個壓入的) */ public static Activity currentActivity() { if (mActivitys == null||mActivitys.isempty()) { return null; } Activity activity = mActivitys.get(mActivitys.size()-1); return activity; } /** * 結束當前Activity(棧中最后一個壓入的) */ public static void finishCurrentActivity() { if (mActivitys == null||mActivitys.isEmpty()) { return; } Activity activity = mActivitys.get(mActivitys.size()-1); finishActivity(activity); } /** * 結束指定的Activity */ public static void finishActivity(Activity activity) { if (mActivitys == null||mActivitys.isEmpty()) { return; } if (activity != null) { mActivitys.remove(activity); activity.finish(); activity = null; } } /** * 結束指定類名的Activity */ public static void finishActivity(Class<?> cls) { if (mActivitys == null||mActivitys.isEmpty()) { return; } for (Activity activity : mActivitys) { if (activity.getClass().equals(cls)) { finishActivity(activity); } } } /** * 按照指定類名找到activity * * @param cls * @return */ public static Activity findActivity(Class<?> cls) { Activity targetActivity = null; if (mActivitys != null) { for (Activity activity : mActivitys) { if (activity.getClass().equals(cls)) { targetActivity = activity; break; } } } return targetActivity; } /** * @return 作用說明 :獲取當前最頂部activity的實例 */ public Activity getTopActivity() { Activity mBaseActivity = null; synchronized (mActivitys) { final int size = mActivitys.size() - 1; if (size < 0) { return null; } mBaseActivity = mActivitys.get(size); } return mBaseActivity; } /** * @return 作用說明 :獲取當前最頂部的acitivity 名字 */ public String getTopActivityName() { Activity mBaseActivity = null; synchronized (mActivitys) { final int size = mActivitys.size() - 1; if (size < 0) { return null; } mBaseActivity = mActivitys.get(size); } return mBaseActivity.getClass().getName(); } /** * 結束所有Activity */ public static void finishAllActivity() { if (mActivitys == null) { return; } for (Activity activity : mActivitys) { activity.finish(); } mActivitys.clear(); } /** * 退出應用程序 */ public static void appExit() { try { finishAllActivity(); } catch (Exception e) { } } private void registerActivityListener() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { /** * 監聽到 Activity創建事件 將該 Activity 加入list */ pushActivity(activity); } @Override public void onActivityStarted(Activity activity) { } @Override public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { if (null==mActivitys||mActivitys.isEmpty()) { return; } if (mActivitys.contains(activity)) { /** * 監聽到 Activity銷毀事件 將該Activity 從list中移除 */ popActivity(activity); } } }); } }}
以上整理了目前Android退出應用程序常見的一些方法,每個方法各有利弊,大家可以去實踐下,看看其具體效果,然后根據自己的需要,選擇適合自己的方式。
160763.html
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
石家莊裝修建材市場有哪些?1.巨然李佳裝飾城(巨然李佳裝飾城位于石家莊市中華南街473號)2.西三莊建材市場(位于北二環與西三莊街交叉口)3.紅星美凱龍(建華街與和平路交叉口)4.好家園(東二環與和平路交叉口)5.岳明家園(淮安路高架橋以西)6.白色家居(體育街與東港路交叉口)7.陽光宜家建材廣場(和平東路430號)8.紅房子裝飾材料市場(槐中路與建設街交叉口)9.華業裝飾城(新華西路)10.岳明...
網站域名的流程及費用是多少?在中國有兩種建立網站的方法。一是購買香港以外的國內空間,另一種是購買香港空間和外國空間。兩者之間有區別。第一個是建立網站備案,第二個不是。因此,有些學生選擇第二個是為了方便。不過,對于中國來說,部分線路的延誤有點大,這是非常重要的,這也是一個需要考慮的因素。接下來,我想談談在國內空間建立網站的步驟。如果你購買國外空間,你可以跳過歸檔的步驟。第一步是購買空間和域名。目前國...
北京到杭州高鐵里程數?從北京到杭州全程約1200公里。目前北京到杭州沒有直達線路,推薦19條中轉線路,分別是:G177、G197、C2079、G33、G35、G181、G37、G185、G187、C2559、G189、G191、G193、Z284、G133至G7613、G137。222北京到杭州高鐵多少公里,北京到杭州高鐵最新消息?北京到杭州的航班列表類別順序始發站末端的耗費時間的方案1G177細...