您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
89_如何安全的退出应用程序
发布时间:2021-03-29 16:07:47编辑:雪饮阅读()
在前面曾经谈到过安卓activity的任务栈。那么以正常默认的任务栈来说,如果一个程序中打开的activity栈过多时候,需要按标准退出应用程序的流程,则需要不断的去按返回键直到退出到应用打开之前的界面为止。这样在某些情况下用户体验并不友好。那么今天就是实现如何一次性退出到应用打开之前的界面。
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="activity1" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="打开activity"
android:onClick="openActivity"
/>
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="打开activity2"
android:onClick="openActivity"
/>
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="打开菜单"
android:onClick="openMenu"
/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
权限 逻辑
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity2">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="activity2" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="打开activity"
android:onClick="openActivity"
/>
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="打开activity2"
android:onClick="openActivity"
/>
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="打开菜单"
android:onClick="openMenu"
/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.lead">
<!--API15之后activity逻辑层使用killBackgroundProcesses进行进程杀死时候所需要允许的权限-->
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<!--API15之前activity逻辑层使用restartPackage进行进程杀死时候所需要允许的权限-->
<uses-permission android:name="android.permission.RESTART_PACKAGES"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Lead"
android:name="App"
>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity2"></activity>
</application>
</manifest>
上面提到了这个全局的负责记录的这个App,这里就先将这个App说明下。那么其实现就是一个ArrayList。则建立于MainActivity.java同目录如App.java:
package com.example.lead;
import android.app.Activity;
import android.app.Application;
import java.util.ArrayList;
public class App extends Application {
ArrayList<Activity> activities;
//创建出来整个应用程序的全局的实例
//在整个应用程序的进程第一次被创建的时候执行
@Override
public void onCreate() {
activities=new ArrayList<Activity>();
super.onCreate();
}
}接下来就是具体每个activity了,对于单纯App.java是不能完成activity的记录的,需要每个activity在onCreate的时候将自身添加到activity集合中,另外finish()方法用于结束一个Activity的生命周期,而onDestory()方法则是Activity的一个生命周期方法,其作用是在一个Activity对象被销毁之前,Android系统会调用该方法,用于释放此Activity之前所占用的资源。所以为了实现上面一次性退出整个应用的逻辑,则每个activity都需要在onDestroy时候调用App.java中的activity集合来将自己从集合中移除掉。这样在真正调用一次性退出整个应用时候才能通过遍历整个集合进行finish时候干掉对应的activity栈条目。
另外就是对于上面提到的布局文件中菜单按键模拟调用的事件、菜单的创建(覆写实现onCreateOptionsMenu)、菜单中菜单项目被点击后的事件交互反馈(覆写实现onOptionsItemSelected),那么最后就是两个activity都要做上面这些事情,所以各个activity如:
MainActivity.java:
package com.example.lead;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import java.io.IOException;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
App app=(App) getApplication();
app.activities.add(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void openActivity(View view) {
Intent intent = new Intent();
if(view.getId()==R.id.button){
intent.setClassName("com.example.lead", "com.example.lead.MainActivity");
startActivity(intent);
}
if(view.getId()==R.id.button2){
intent.setClassName("com.example.lead", "com.example.lead.MainActivity2");
startActivity(intent);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater=new MenuInflater(this);
inflater.inflate(R.menu.menu,menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id=item.getItemId();
if(id==R.id.close_all_1){
//通过这种方式去杀死应用程序,应用程序不会被完全杀死,并且他不会把当前这个应用程序的activity的task栈清空
android.os.Process.killProcess(android.os.Process.myPid());
}
if(id==R.id.close_all_2){
//不会把自己的应用程序杀死
System.exit(0);
}
if(id==R.id.close_all_3){
//只能杀死别人不能杀死自己
ActivityManager manager=(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
//按照原来的说法该方式只能杀死别的进程不能杀死自己,那么其语法如 manager.restartPackage("com.android.email");
// 其实这个语法是有问题的,在API 15就开始废弃了restartPackage(也就是说在API15之前应该是可以杀死进程的,并且只能杀死别人的进程而不是自己的进程),并且在如今我这里的运行环境是API28,对应的sdk中email包名应该是com.google.android.gm而不是原来的com.android.email
//虽然这个com.google.android.gm包名我没有测试过,但是从adb命令中与activity相关的命令中可以看出一些线索的
/*
*
*
* C:\Program Files (x86)\Android\android-sdk\platform-tools>adb -s emulator-5554 shell dumpsys activity activities
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
Stack #9: type=standard mode=fullscreen
isSleeping=false
mBounds=Rect(0, 0 - 0, 0)
Task id #89
mBounds=Rect(0, 0 - 0, 0)
mMinWidth=-1
mMinHeight=-1
mLastNonFullscreenBounds=null
* TaskRecord{b25271d #89 A=com.example.lead U=0 StackId=9 sz=1}
userId=0 effectiveUid=u0a86 mCallingUid=2000 mUserSetupComplete=true mCallingPackage=null
affinity=com.example.lead
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example.lead/.MainActivity}
realActivity=com.example.lead/.MainActivity
autoRemoveRecents=false isPersistable=true numFullscreen=1 activityType=1
rootWasReset=false mNeverRelinquishIdentity=true mReuseTask=false mLockTaskAuth=LOCK_TASK_AUTH_PINNABLE
Activities=[ActivityRecord{64312ae u0 com.example.lead/.MainActivity t89}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{e2aad92 6829:com.example.lead/u0a86}
stackId=9
hasBeenVisible=true mResizeMode=RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION mSupportsPictureInPicture=false isResizeable=true lastActiveTime=2787650 (inactive for 319s)
* Hist #0: ActivityRecord{64312ae u0 com.example.lead/.MainActivity t89}
packageName=com.example.lead processName=com.example.lead
launchedFromUid=2000 launchedFromPackage=null userId=0
app=ProcessRecord{e2aad92 6829:com.example.lead/u0a86}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example.lead/.MainActivity }
frontOfTask=true task=TaskRecord{b25271d #89 A=com.example.lead U=0 StackId=9 sz=1}
taskAffinity=com.example.lead
realActivity=com.example.lead/.MainActivity
baseDir=/data/app/com.example.lead-m4uVghhllOXni3-GmeGmzw==/base.apk
dataDir=/data/user/0/com.example.lead
stateNotNeeded=false componentSpecified=true mActivityType=standard
compat={160dpi always-compat} labelRes=0x7f0f001b icon=0x7f0d0001 theme=0x7f10019f
mLastReportedConfigurations:
mGlobalConfig={1.0 310mcc260mnc [en_US] ldltr sw320dp w320dp h456dp 160dpi nrml port finger qwerty/v/v -nav/h winConfig={ mBounds=Rect(0, 0 - 0, 0) mAppBounds=Rect(0, 0 - 320, 480) mWindowingMode=fullscreen mActivityType=undefined} s.6}
mOverrideConfig={1.0 310mcc260mnc [en_US] ldltr sw320dp w320dp h456dp 160dpi nrml port finger qwerty/v/v -nav/h winConfig={ mBounds=Rect(0, 0 - 320, 480) mAppBounds=Rect(0, 0 - 320, 480) mWindowingMode=fullscreen mActivityType=standard} s.6}
CurrentConfiguration={1.0 310mcc260mnc [en_US] ldltr sw320dp w320dp h456dp 160dpi nrml port finger qwerty/v/v -nav/h winConfig={ mBounds=Rect(0, 0 - 320, 480) mAppBounds=Rect(0, 0 - 320, 480) mWindowingMode=fullscreen mActivityType=standard} s.6}
taskDescription: label="null" icon=null iconResource=0 iconFilename=null primaryColor=ff6200ee
backgroundColor=ffffffff
statusBarColor=ff3700b3
navigationBarColor=ff000000
launchFailed=false launchCount=0 lastLaunchTime=-10m7s205ms
haveState=false icicle=null
state=RESUMED stopped=false delayedResume=false finishing=false
keysPaused=false inHistory=true visible=true sleeping=false idle=true mStartingWindowState=STARTING_WINDOW_SHOWN
fullscreen=true noDisplay=false immersive=false launchMode=0
frozenBeforeDestroy=false forceNewConfig=false
mActivityType=standard
waitingVisible=false nowVisible=true lastVisibleTime=-5m19s301ms
resizeMode=RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION
mLastReportedMultiWindowMode=false mLastReportedPictureInPictureMode=false
Running activities (most recent first):
TaskRecord{b25271d #89 A=com.example.lead U=0 StackId=9 sz=1}
Run #0: ActivityRecord{64312ae u0 com.example.lead/.MainActivity t89}
mResumedActivity: ActivityRecord{64312ae u0 com.example.lead/.MainActivity t89}
mLastPausedActivity: ActivityRecord{64312ae u0 com.example.lead/.MainActivity t89}
Stack #0: type=home mode=fullscreen
isSleeping=false
mBounds=Rect(0, 0 - 0, 0)
Task id #2
mBounds=Rect(0, 0 - 0, 0)
mMinWidth=-1
mMinHeight=-1
mLastNonFullscreenBounds=null
* TaskRecord{2918572 #2 I=com.google.android.apps.nexuslauncher/.NexusLauncherActivity U=0 StackId=0 sz=1}
userId=0 effectiveUid=u0a22 mCallingUid=u0a22 mUserSetupComplete=true mCallingPackage=com.google.android.apps.nexuslauncher
intent={act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.google.android.apps.nexuslauncher/.NexusLauncherActivity}
realActivity=com.google.android.apps.nexuslauncher/.NexusLauncherActivity
autoRemoveRecents=false isPersistable=true numFullscreen=1 activityType=2
rootWasReset=false mNeverRelinquishIdentity=true mReuseTask=false mLockTaskAuth=LOCK_TASK_AUTH_PINNABLE
Activities=[ActivityRecord{5d1d987 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t2}]
askedCompatMode=false inRecents=true isAvailable=true
mRootProcess=ProcessRecord{d5548d1 2700:com.google.android.apps.nexuslauncher/u0a22}
stackId=0
hasBeenVisible=true mResizeMode=RESIZE_MODE_RESIZEABLE mSupportsPictureInPicture=false isResizeable=true lastActiveTime=2787536 (inactive for 319s)
* Hist #0: ActivityRecord{5d1d987 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t2}
packageName=com.google.android.apps.nexuslauncher processName=com.google.android.apps.nexuslauncher
launchedFromUid=0 launchedFromPackage=null userId=0
app=ProcessRecord{d5548d1 2700:com.google.android.apps.nexuslauncher/u0a22}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.google.android.apps.nexuslauncher/.NexusLauncherActivity }
frontOfTask=true task=TaskRecord{2918572 #2 I=com.google.android.apps.nexuslauncher/.NexusLauncherActivity U=0 StackId=0 sz=1}
taskAffinity=null
realActivity=com.google.android.apps.nexuslauncher/.NexusLauncherActivity
baseDir=/system/priv-app/NexusLauncherPrebuilt/NexusLauncherPrebuilt.apk
dataDir=/data/user/0/com.google.android.apps.nexuslauncher
stateNotNeeded=true componentSpecified=false mActivityType=home
compat={160dpi always-compat} labelRes=0x7f110030 icon=0x7f080039 theme=0x7f120002
mLastReportedConfigurations:
mGlobalConfig={1.0 310mcc260mnc [en_US] ldltr sw320dp w320dp h456dp 160dpi nrml port finger qwerty/v/v -nav/h winConfig={ mBounds=Rect(0, 0 - 0, 0) mAppBounds=Rect(0, 0 - 320, 480) mWindowingMode=fullscreen mActivityType=undefined} s.6}
mOverrideConfig={1.0 310mcc260mnc [en_US] ldltr sw320dp w320dp h456dp 160dpi nrml port finger qwerty/v/v -nav/h winConfig={ mBounds=Rect(0, 0 - 320, 480) mAppBounds=Rect(0, 0 - 320, 480) mWindowingMode=fullscreen mActivityType=home} s.6}
CurrentConfiguration={1.0 310mcc260mnc [en_US] ldltr sw320dp w320dp h456dp 160dpi nrml port finger qwerty/v/v -nav/h winConfig={ mBounds=Rect(0, 0 - 320, 480) mAppBounds=Rect(0, 0 - 320, 480) mWindowingMode=fullscreen mActivityType=home} s.6}
OverrideConfiguration={0.0 ?mcc?mnc ?localeList ?layoutDir ?swdp ?wdp ?hdp ?density ?lsize ?long ?ldr ?wideColorGamut ?orien ?uimode ?night ?touch ?keyb/?/? ?nav/? winConfig={ mBounds=Rect(0, 0 - 0, 0) mAppBounds=null mWindowingMode=undefined mActivityType=home}}
taskDescription: label="null" icon=null iconResource=0 iconFilename=null primaryColor=fff5f5f5
backgroundColor=fffafafa
statusBarColor=0
navigationBarColor=0
launchFailed=false launchCount=0 lastLaunchTime=-51m31s985ms
haveState=true icicle=Bundle[mParcelledData.dataSize=3604]
state=STOPPED stopped=true delayedResume=false finishing=false
keysPaused=false inHistory=true visible=false sleeping=false idle=true mStartingWindowState=STARTING_WINDOW_NOT_SHOWN
fullscreen=true noDisplay=false immersive=false launchMode=2
frozenBeforeDestroy=false forceNewConfig=false
mActivityType=home
waitingVisible=false nowVisible=false lastVisibleTime=-5m20s441ms
connections=[]
resizeMode=RESIZE_MODE_RESIZEABLE
mLastReportedMultiWindowMode=false mLastReportedPictureInPictureMode=false
Running activities (most recent first):
TaskRecord{2918572 #2 I=com.google.android.apps.nexuslauncher/.NexusLauncherActivity U=0 StackId=0 sz=1}
Run #0: ActivityRecord{5d1d987 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t2}
mLastPausedActivity: ActivityRecord{5d1d987 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t2}
Stack #8: type=standard mode=fullscreen
isSleeping=false
mBounds=Rect(0, 0 - 0, 0)
Task id #88
mBounds=Rect(0, 0 - 0, 0)
mMinWidth=-1
mMinHeight=-1
mLastNonFullscreenBounds=null
* TaskRecord{a9e5dad #88 A=com.google.android.gm U=0 StackId=8 sz=2}
userId=0 effectiveUid=u0a84 mCallingUid=u0a84 mUserSetupComplete=true mCallingPackage=com.google.android.gm
affinity=com.google.android.gm
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.google.android.gm/.ui.MailActivityGmail}
origActivity=com.google.android.gm/.ConversationListActivityGmail
realActivity=com.google.android.gm/.ui.MailActivityGmail
autoRemoveRecents=false isPersistable=true numFullscreen=2 activityType=1
rootWasReset=true mNeverRelinquishIdentity=true mReuseTask=false mLockTaskAuth=LOCK_TASK_AUTH_PINNABLE
Activities=[ActivityRecord{eec24f3 u0 com.google.android.gm/.welcome.WelcomeTourActivity t88}, ActivityRecord{9d9c18e u0 com.google.android.gm/.welcome.SetupAddressesActivity t88}]
askedCompatMode=false inRecents=true isAvailable=true
stackId=8
hasBeenVisible=true mResizeMode=RESIZE_MODE_RESIZEABLE mSupportsPictureInPicture=false isResizeable=true lastActiveTime=2786396 (inactive for 320s)
* Hist #1: ActivityRecord{9d9c18e u0 com.google.android.gm/.welcome.SetupAddressesActivity t88}
packageName=com.google.android.gm processName=com.google.android.gm
launchedFromUid=10084 launchedFromPackage=com.google.android.gm userId=0
app=ProcessRecord{518c6d0 7247:com.google.android.gm/u0a84}
Intent { cmp=com.google.android.gm/.welcome.SetupAddressesActivity (has extras) }
frontOfTask=false task=TaskRecord{a9e5dad #88 A=com.google.android.gm U=0 StackId=8 sz=2}
taskAffinity=com.google.android.gm
realActivity=com.google.android.gm/.welcome.SetupAddressesActivity
baseDir=/system/app/PrebuiltGmail/PrebuiltGmail.apk
dataDir=/data/user/0/com.google.android.gm
stateNotNeeded=false componentSpecified=true mActivityType=standard
compat={160dpi always-compat} labelRes=0x7f1201ab icon=0x7f030002 theme=0x7f1301b2
mLastReportedConfigurations:
mGlobalConfig={1.0 310mcc260mnc [en_US] ldltr sw320dp w320dp h456dp 160dpi nrml port finger qwerty/v/v -nav/h winConfig={ mBounds=Rect(0, 0 - 0, 0) mAppBounds=Rect(0, 0 - 320, 480) mWindowingMode=fullscreen mActivityType=undefined} s.6}
mOverrideConfig={1.0 310mcc260mnc [en_US] ldltr sw320dp w320dp h456dp 160dpi nrml port finger qwerty/v/v -nav/h winConfig={ mBounds=Rect(0, 0 - 320, 480) mAppBounds=Rect(0, 0 - 320, 480) mWindowingMode=fullscreen mActivityType=standard} s.6}
CurrentConfiguration={1.0 310mcc260mnc [en_US] ldltr sw320dp w320dp h456dp 160dpi nrml port finger qwerty/v/v -nav/h winConfig={ mBounds=Rect(0, 0 - 320, 480) mAppBounds=Rect(0, 0 - 320, 480) mWindowingMode=fullscreen mActivityType=standard} s.6}
resultTo=ActivityRecord{eec24f3 u0 com.google.android.gm/.welcome.WelcomeTourActivity t88} resultWho=null resultCode=1
taskDescription: label="null" icon=null iconResource=0 iconFilename=null primaryColor=ff039be5
backgroundColor=fffafafa
statusBarColor=ff0288d1
navigationBarColor=ffffffff
launchFailed=false launchCount=0 lastLaunchTime=-7m11s828ms
haveState=true icicle=Bundle[mParcelledData.dataSize=1112]
state=STOPPED stopped=true delayedResume=false finishing=false
keysPaused=false inHistory=true visible=false sleeping=false idle=true mStartingWindowState=STARTING_WINDOW_REMOVED
fullscreen=true noDisplay=false immersive=false launchMode=1
frozenBeforeDestroy=false forceNewConfig=false
mActivityType=standard
waitingVisible=false nowVisible=false lastVisibleTime=-7m11s435ms
resizeMode=RESIZE_MODE_RESIZEABLE
mLastReportedMultiWindowMode=false mLastReportedPictureInPictureMode=false
* Hist #0: ActivityRecord{eec24f3 u0 com.google.android.gm/.welcome.WelcomeTourActivity t88}
packageName=com.google.android.gm processName=com.google.android.gm
launchedFromUid=10084 launchedFromPackage=com.google.android.gm userId=0
app=null
Intent { flg=0x4000000 pkg=com.google.android.gm cmp=com.google.android.gm/.welcome.WelcomeTourActivity (has extras) }
frontOfTask=true task=TaskRecord{a9e5dad #88 A=com.google.android.gm U=0 StackId=8 sz=2}
taskAffinity=com.google.android.gm
realActivity=com.google.android.gm/.welcome.WelcomeTourActivity
baseDir=/system/app/PrebuiltGmail/PrebuiltGmail.apk
dataDir=/data/user/0/com.google.android.gm
stateNotNeeded=false componentSpecified=true mActivityType=standard
compat={160dpi always-compat} labelRes=0x7f1201ab icon=0x7f030002 theme=0x7f1301b3
mLastReportedConfigurations:
mGlobalConfig={1.0 310mcc260mnc [en_US] ldltr sw320dp w320dp h456dp 160dpi nrml port finger qwerty/v/v -nav/h winConfig={ mBounds=Rect(0, 0 - 0, 0) mAppBounds=Rect(0, 0 - 320, 480) mWindowingMode=fullscreen mActivityType=undefined} s.6}
mOverrideConfig={1.0 310mcc260mnc [en_US] ldltr sw320dp w320dp h456dp 160dpi nrml port finger qwerty/v/v -nav/h winConfig={ mBounds=Rect(0, 0 - 320, 480) mAppBounds=Rect(0, 0 - 320, 480) mWindowingMode=fullscreen mActivityType=standard} s.6}
CurrentConfiguration={1.0 310mcc260mnc [en_US] ldltr sw320dp w320dp h456dp 160dpi nrml port finger qwerty/v/v -nav/h winConfig={ mBounds=Rect(0, 0 - 320, 480) mAppBounds=Rect(0, 0 - 320, 480) mWindowingMode=fullscreen mActivityType=standard} s.6}
taskDescription: label="null" icon=null iconResource=0 iconFilename=null primaryColor=ffdb4437
backgroundColor=fffafafa
statusBarColor=ffbdbdbd
navigationBarColor=ffffffff
launchFailed=false launchCount=0 lastLaunchTime=-7m44s116ms
haveState=true icicle=Bundle[mParcelledData.dataSize=1444]
state=DESTROYED stopped=true delayedResume=false finishing=false
keysPaused=false inHistory=true visible=false sleeping=false idle=true mStartingWindowState=STARTING_WINDOW_REMOVED
fullscreen=true noDisplay=false immersive=false launchMode=1
frozenBeforeDestroy=false forceNewConfig=false
mActivityType=standard
waitingVisible=false nowVisible=false lastVisibleTime=-7m32s25ms
resizeMode=RESIZE_MODE_RESIZEABLE
mLastReportedMultiWindowMode=false mLastReportedPictureInPictureMode=false
Running activities (most recent first):
TaskRecord{a9e5dad #88 A=com.google.android.gm U=0 StackId=8 sz=2}
Run #0: ActivityRecord{9d9c18e u0 com.google.android.gm/.welcome.SetupAddressesActivity t88}
mLastPausedActivity: ActivityRecord{9d9c18e u0 com.google.android.gm/.welcome.SetupAddressesActivity t88}
ResumedActivity: ActivityRecord{64312ae u0 com.example.lead/.MainActivity t89}
mFocusedStack=ActivityStack{9fa9363 stackId=9 type=standard mode=fullscreen visible=true translucent=false, 1 tasks} mLastFocusedStack=ActivityStack{9fa9363 stackId=9 type=standard mode=fullscreen visible=true translucent=false, 1 tasks}
mCurTaskIdForUser={0=89}
mUserStackInFront={}
displayId=0 stacks=3
mHomeStack=ActivityStack{e913979 stackId=0 type=home mode=fullscreen visible=false translucent=true, 1 tasks}
isHomeRecentsComponent=true KeyguardController:
mKeyguardShowing=false
mAodShowing=false
mKeyguardGoingAway=false
mOccluded=false
mDismissingKeyguardActivity=null
mDismissalRequested=false
mVisibilityTransactionDepth=0
LockTaskController
mLockTaskModeState=NONE
mLockTaskModeTasks=
mLockTaskPackages (userId:packages)=
u0:[]
* */
//那么从官方文档看到的对于restartPackage的替代方案是killBackgroundProcesses,参数还是保留和之前一样
//但是这里经过测试,发现也并不一定能杀死目标进程。关于这个问题详情可以参考https://blog.csdn.net/wpz25074529/article/details/103646304
manager.killBackgroundProcesses("com.google.android.gm");
}
if(id==R.id.close_all_3_1){
//只能杀死别人不能杀死自己
ActivityManager manager=(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
//和上面close_all_3一样,这里杀自己也是杀不了的。无论是原来API15废弃的方法或者这个替代方法
manager.killBackgroundProcesses(getPackageName());
}
if(id==R.id.close_all_4){
App app=(App) getApplication();
List<Activity> lists=app.activities;
for(Activity activity:lists){
activity.finish();
}
}
if(id==R.id.close_this){
finish();
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onDestroy() {
App app=(App) getApplication();
app.activities.remove(this);
super.onDestroy();
}
//模拟menu菜单按钮被点击
public void openMenu(View view) {
try
{
String keyCommand = "input keyevent " + KeyEvent.KEYCODE_MENU;
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec(keyCommand);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}MainActivity2.java:
package com.example.lead;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import java.io.IOException;
import java.util.List;
public class MainActivity2 extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
App app=(App) getApplication();
app.activities.add(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
}
public void openActivity(View view) {
Intent intent = new Intent();
if(view.getId()==R.id.button){
intent.setClassName("com.example.lead", "com.example.lead.MainActivity");
startActivity(intent);
}
if(view.getId()==R.id.button2){
intent.setClassName("com.example.lead", "com.example.lead.MainActivity2");
startActivity(intent);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater=new MenuInflater(this);
inflater.inflate(R.menu.menu,menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id=item.getItemId();
if(id==R.id.close_all_1){
//通过这种方式去杀死应用程序,应用程序不会被完全杀死,并且他不会把当前这个应用程序的activity的task栈清空
android.os.Process.killProcess(android.os.Process.myPid());
}
if(id==R.id.close_all_2){
//不会把自己的应用程序杀死
System.exit(0);
}
if(id==R.id.close_all_3){
//只能杀死别人不能杀死自己
ActivityManager manager=(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
manager.restartPackage("com.android.email");
}
if(id==R.id.close_all_3_1){
//只能杀死别人不能杀死自己
ActivityManager manager=(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
manager.restartPackage(getPackageName());
}
if(id==R.id.close_all_4){
App app=(App) getApplication();
List<Activity> lists=app.activities;
for(Activity activity:lists){
activity.finish();
}
}
if(id==R.id.close_this){
finish();
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onDestroy() {
App app=(App) getApplication();
app.activities.remove(this);
super.onDestroy();
}
public void openMenu(View view) {
try
{
String keyCommand = "input keyevent " + KeyEvent.KEYCODE_MENU;
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec(keyCommand);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}菜单布局
上面逻辑中有创建菜单,这个菜单也是依赖于类似布局文件一样的xml的。这里菜单中的菜单条目中可以用每个条目的icon图标、title标题、id等。
那么菜单布局及icon图标资源则如
测试
上面的一切都完成之后就可以部署到设备中进行测试了,这里测试没有什么问题,大概如
这里的”退出当前”,就是那个模拟返回键的方式进行退出的,每次只退出一个activity。
关键字词:android,activity,退出,应用程序,进程