注意,登出的时候须要关闭用户资源。若是不关闭的话,就会致使后台服务一直接收退出用户的消息等状况发生。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失效以及主动退出的问题。而登出设计的时候,还须要考虑关于我的资源(线程池,数据库,后台任务等)关闭的问题。线程