注意,登出的時候須要關閉用戶資源。若是不關閉的話,就會致使後臺服務一直接收退出用戶的消息等狀況發生。android
對於APP來講,徹底退出是一項很是基本的功能,可是,這個功能要實現的比較好,也是比較困難的。git
最麻煩的地方就是:**賬號切換了,可是還存在子進程或者子線程在運行上一個用戶業務,致使完成的業務數據寫入當前切換成功的用戶數據庫中。**若是擁有推送進程的話,那麼還須要notify推送進程關閉,避免殺死Service進程又自重啓。數據庫
一般的作法是關閉全部服務,殺死全部的進程,而後重啓。以下是一段比較完善的代碼:app
/** * 重啓App */ static public void killApp(Context context, boolean restart) { //重啓 if (restart) { Intent intent = new Intent(context, MyActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } //中止後臺 service try { //讀取全部的SERVICE信息 PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SERVICES); if (packageInfo != null && packageInfo.services != null) { for (ServiceInfo serviceInfo : packageInfo.services) { try { Class cls = Class.forName(serviceInfo.name); context.stopService(new Intent(context, cls)); } catch (ClassNotFoundException e) { } } } } catch (Exception e) { Log.e(MyActivity.class.getName(), e.getMessage(), e); } //殺死全部進程 try { Set<String> processNameSet = new HashSet<String>(); //讀取 全部的Process { //讀取Activity { PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES); if (packageInfo != null && packageInfo.activities != null) { for (ActivityInfo activityInfo : packageInfo.activities) { processNameSet.add(activityInfo.processName); } } } //讀取Service { PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SERVICES); if (packageInfo != null && packageInfo.services != null) { for (ServiceInfo serviceInfo : packageInfo.services) { processNameSet.add(serviceInfo.processName); } } } //讀取 RECEIVERS { PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_RECEIVERS); if (packageInfo != null && packageInfo.receivers != null) { for (ActivityInfo activityInfo : packageInfo.receivers) { processNameSet.add(activityInfo.processName); } } } //讀取 PROVIDERS { PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PROVIDERS); if (packageInfo != null && packageInfo.providers != null) { for (ProviderInfo providerInfo : packageInfo.providers) { processNameSet.add(providerInfo.processName); } } } } //關閉全部進程 { int myPid = android.os.Process.myPid(); ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); Iterator iterator = mActivityManager.getRunningAppProcesses().iterator(); while (iterator.hasNext()) { ActivityManager.RunningAppProcessInfo appProcess = (ActivityManager.RunningAppProcessInfo) iterator.next(); if (processNameSet.contains(appProcess.processName)) { //先KILL其餘進程 if (appProcess.pid != myPid) { android.os.Process.killProcess(appProcess.pid); } } } //殺死本身 android.os.Process.killProcess(myPid); } } catch (Exception e) { Log.e(MyActivity.class.getName(),e.getMessage(),e); throw new RuntimeException(e); } }
核心思想是:ide
這樣子就能徹底退出app了,值得一提的是網上出現 restartPackage, killBackgroundProcesses 貌似在5.1上都不可行。固然,上面的代碼測試環境,也是5.1了。測試
固然了,體驗比較好的就是依次釋放用戶資源(線程池,數據庫,後臺Service等)。不過該方法實現起來比較困難。.net
在用戶的登入登出設計中,登入的時候須要注意用戶是否以前登入過,而登出設計須要考慮TOKEN失效以及主動退出的問題。而登出設計的時候,還須要考慮關於我的資源(線程池,數據庫,後臺任務等)關閉的問題。線程