Android下结束进度的章程

by admin on 2019年9月24日

 使用ntsd程序 (借使设置过VS,在VS的装置目录下,比方“C:\Program Files
(x86)\Debugging Tools for Windows
(x86)\ntsd.exe”,也得以在此间下载)

  近来在做二个近乎与职务管理器的东西,里面有个功用,能够透过那个管理器结束掉别的的历程。

 

 

adb server is out of date.  killing…
ADB server didn’t ACK
* failed to start daemon *
error: unknown host service

 

动用adb时,若出地点的错,使用adb
kill-server是绝非用的,因为这时是任何进程的监听了端口,并不是adb。笔者用cmd+命令管理器消除:

输入netstat -ano | findstr “5037”  

找到下列进程

  TCP    127.0.0.1:5037         0.0.0.0:0              LISTENING       4236  

  TCP    127.0.0.1:5037         127.0.0.1:49422        ESTABLISHED     4236  

  TCP    127.0.0.1:49422        127.0.0.1:5037         ESTABLISHED     3840  

此刻把4236以此进程停止就行了。

TASKLIST | findstr “4236”

本人的是被贰个叫tadb.exe的强制了,貌似是qqmusic的历程,甘休它,over

图片 1

在linux系统管理中,大家临时须求收尾掉有个别客户的持有进度。初学者一般会先查询出顾客的有所pid,然后一条条kill甘休掉,或许写一个本子。实际上甘休的不二等秘书技有这几个,博主那边总括了下边4种艺术,以kill客商zhangnq为例。

Process类的CloseMainWindow, Kill, Close

Process.CloseMainWindow是GUI程序的最友好截至方式,从名字上就能够看出来它是通过完工主窗体,约等于顾客点击窗体的关闭按键大概按Alt
+
F4。它的实质就是向主窗体发送WM_CLOSE音讯(Process.MainWindowsHandle能够回去主窗体的句柄)。那么些能够在.NET
Framework源代码中看出来:

publicbool
CloseMainWindow()

{

IntPtr mainWindowHandle =this.MainWindowHandle;

//句柄是或不是为0

if
(mainWindowHandle ==IntPtr.Zero)

{

returnfalse;

}

//GetWindowLong是还是不是中标试行

if
((NativeMethods.GetWindowLong(newHandleRef(this,
mainWindowHandle), -16)
&0x8000000)
!=0)

{

returnfalse;

}

//0x10 是 WM_CLOSE消息

//向主窗体发送WM_CLOSE,注意是PostMessage而不是SendMessage

NativeMethods.PostMessage(newHandleRef(this,
mainWindowHandle), 0x10, IntPtr.Zero,
IntPtr.Zero);

returntrue;

}

 

CloseMainWindow方法应用PostMessage(不是SendMessage,所以新闻会加在音讯队列的末梢)方法向主窗体发送三个WM_CLOSE音讯,那样等主窗体管理完全部音信后,等境遇WM_CLOSE便伊始进行退出动作。

举例说记事本接到了WM_CLOSE新闻不过有未保存的文书记事本会弹出对话框提醒客户保存恐怕不保留依旧撤废退出操作。Windows
Forms和WPF的窗体都会有近似操作,通过窗体的Closing事件来在WM_CLOSE音讯接收后做出是不是退出的垄断。

 

从此现在大家会讲到Windows
Forms和WPF都有和好的投机型常规退出办法,不过实际有贰个通用的GUI程序退出方式,就是使用这些CloseMainWindow方法:

//Windows Forms和WPF都得以用

//Windows
Forms的Form.Closing事件会在此后发生

//WPF的Windows.Closing事件也会

Process.GetCurrentProcess().CloseMainWindow();

 

 

 

接下去正是Process.Kill方法,从名字也得以看出来,直接杀掉,不给喘息喘息时机呵呵。Kill方法会直接截止全数进度,不进行例行能源清理(什么finally块等……)。Kill本质调用本地API:TerminateProcess函数。

 

 

终极一个是Process.Close方法。抱歉它根本不是用来终止进度的!这些方法名字有个别误导,其实历来则否则。它唯有是而是IDisposable的Dispose方法的求实施行,用来拓宽Process类的托管财富清理的!

是因为Process类承袭自Component类,后面一个继续IDisposable而与此同期又有析构函数,而经过三个承接类可改写的Dispose方法(参数是bool
disposing)来剖断这几个Dispose是客户调用依然GC调用。而以此Process.Close()方法就是客户调用Dispose时张开托管财富的清理办法:

上面Process.Dispose方法代码:

protectedoverridevoid
Dispose(bool disposing)

{

if
(!this.disposed)

{

if
(disposing)

{

//客商调用,清理托管能源

this.Close();

}

this.disposed
=true;

//调用Component的Dispose

base.Dispose(disposing);

}

}

 

其一Close方法类似相当多别的.NET中的类,譬喻Stream……由此Close明确不会实现进度,仅仅是Process类作为IDisposable接口的直接继承者的自家清理办法。

 

 

 

ntsd -c q -p PID
ntsd -c q -pn PName

  在Android平台下,甘休进程的法子依旧比较多的。首先指明,此处的“结束进度”,包罗了截至本身进度和得了别的进度五个方面。通过查阅SDK文书档案和互连网的局地材质,自个儿找到一些了结进程的章程。在此间做一些归结和小结,小说的一部分信息有十分大希望源于网三月有个别小说和帖子,由于过了相比较长日子,所以若开掘本文与其他文章雷同,请见谅。

  1. pkill方式

    # pkill -u zhangnq

  2. killall方式

    # killall -u zhangnq

  3. ps情势 ps列出zhangnq的pid,然后所有人家kill掉,相比麻烦。

    # ps -ef | grep zhangnq | awk ‘{ print $2 }’ | xargs kill -9

  4. pgrep情势 pgrep -u参数查出客户的有着pid,然后依次kill

    # pgrep -u zhangnq | xargs kill -9

Environment类的Exit和FailFast

Environment.Exit相当于在Main函数中的return指令。可是它不会施行代码块的finally块(假设有的话),但财富清理依然要进行的。

 

它是最常见的退出当前进度的艺术之一。在Main函数中大家得以直接return语句便退出了前后相继。假使不在Main函数内,那么Environment.Exit方法就能够派上用场:

classa

{

~a()

{

Console.WriteLine(“析构函数”);

}

}

classProgram

{

staticvoid
Main()

{

try

{

a oa
=newa();

test();

}

finally

{

//这段代码永世不会进行

Console.WriteLine(“finally”);

}

}

 

staticvoid
test()

{

Environment.Exit(0);

}

}

 

代码将会输出:

析构函数

如上所述GC调用了oa的析构函数,但只顾finally块未有运维。

 

 

Environment.Fail法斯特方法更速度,它仍然没有供给向操作系统再次回到过程退出代码(ExitCode),直接停止最近历程并在应用程序事件薄中写入新闻,用于程序出现致命错误须求及时停下。

classa

{

~a()

{

Console.WriteLine(“析构函数”);

}

}

classProgram

{

staticvoid
Main()

{

try

{

a oa
=newa();

Environment.Fail法斯特(“致命错误发生!”);

}

finally

{

//这段代码永久不会执行

Console.WriteLine(“finally”);

}

}

}

 

在.NET
4.0下,Environment.Fail法斯特代码会抛出FatalExecutionEngineError,而在4.0之前会抛出ExecutionEngineException。但都不会有别的输出(GC未有清理对象,同期finally块也未曾运转)

 

 

 

 

三种办法

一、截止多个活动Activity

WPF的Shutdown和Windows Forms的Exit

GUI程序往往皆有温馨的消息队列和事件管理格局,由此得了二个GUI程序要远复杂与甘休八个调整台程序。上述的形式中,Process.Kill和Environment.Exit和Fail法斯特假设用在三个GUI程序中,都会一直强制甘休全部程序,而不会激发GUI窗体的片段针对性应用程序停止的事件(例如Closing事件)。而地方也讲过:Process.CloseMainWindow通过向主窗体发送三个WM_CLOSE音信能够很好的终结一个GUI程序,不过屡屡更自然的不二等秘书籍是选拔GUI框架本人提供的了断程序的方式。

 

WPF中是System.Windows.Application.Shutdown方法,它实质上正是在当前线程的音信队列Dispatcher对象中投入贰个常规优先级(DispatcherPriority.Normal)的回调退出函数,等新闻队列最后管理到该项时前后相继开始退出操作。平日那样使用:

//可能App也足以,WPF程序暗中同意会有贰个App类承继Application类

Application.Current.Shutdown();

 

 

Windows
Forms中是:System.Windows.Forms.Application.Exit方法。它是透过Application.OpenFormsInternal属性先把曾经开荒的窗体通过正规方式都关门(运维Form.Closing事件),最终再结束全数应用程序进度。

 

并且经过WPF的Window.Closing或Windows
Forms的Form.Closing事件都得以撤销这种样式的淡出操作。

 

 

 

一种是利用进程的ID号,将PID换到对应进度ID号就可以

  要一往无前的竣事叁个活动Activity,(先重申一下,是得了二个移动,并非进程)深入人心,明确是finish方法啦,这么些就无须置疑了,並且这么些办法最后会调用Activity的生命周期函数onDestroy方法,截至方今的Activity,从义务栈中弹出当前的Activity,激活下四个Activity。当然别的的finish种类方法,我们不在这里做详细商量,风野趣的校友能够团结查阅一下SDK
的文书档案。

非托管的ExitProcess和TerminateProcess

这是Windows
API中甘休进度的非托管方法。ExitProcess停止进度更和煦些,而TerminateProcess会立时强制甘休进度。两个的关系有一些像Environment.Exit和FailFast,但自身不明显本质上是还是不是一致。何况TerminateProcess能够钦赐进度重回值,但Fail法斯特不能。多少个非托管API的施行都不回运维finally块。

使用起来一点也不细略(关键是P/Invoke,参谋:http://www.pinvoke.net,很有用的)

using
System.Runtime.InteropServices;

classProgram

{

[DllImport(“kernel32.dll”)]

staticexternvoid
ExitProcess(uint uExitCode);

 

[DllImport(“kernel32.dll”, SetLastError =true)]

[return:
MarshalAs(UnmanagedType.Bool)]

staticexternbool
TerminateProcess(IntPtr hProcess, uint
uExitCode);

 

staticvoid
Main()

{

ExitProcess(1);

//或者

TerminateProcess(Process.GetCurrentProcess().Handle,
1);

}

}

 

 

 

 

一种是选拔进程的称呼,将PName换来对应的exe名字就能够,比方notepad.exe

二、强制截止近日的经过

手动发送WM_CLOSE,WM_DESTROY,WM_QUIT消息

在一个GUI程序运维情形下,大家透过获得窗体的句柄,然后便得以向该句柄发送音信,WndProc(Window
Procedure)函数会管理相应的平地风波。在那之中WM_CLOSE也正是客商点击关闭按键,使用PostMessage将WM_CLOSE发送至主窗体等价于.NET中Process类的CloseMainWindow方法,当接过到WM_CLOSE音讯时,应用程序是能够挑选是还是不是真正甘休程序的,如若后续甘休程序而不注销。接着WM_DESTROY消息会发送,那个新闻表示着窗体起首确实关闭,此时得以开展局地财富的清理。最后当前线程接收到WM_QUIT新闻,线程的新闻循环会被终止。

 

为此向窗体发送那3个音讯,唯有WM_CLOSE会引发Closing事件,属高满堂常窗体退出逻辑,别的两当中国国投息会一贯强行关闭窗体。

注意WM_QUIT新闻只好用PostMessage将其送至音讯队列后面部分,使用SendMessage霎时发送在WPF应用程序上运维后前后相继尚未其他影响。

 

下边是一个WPF程序发送下列消息,(并不曾贴XAML,你一定通晓哪些加3个按键然后把Click事件和窗体的Closing事件绑在代码上吗)

using
System;

using
System.Collections.Generic;

using
System.Linq;

using
System.Text;

using
System.Windows;

using
System.Windows.Controls;

using
System.Windows.Data;

using
System.Windows.Documents;

using
System.Windows.Input;

using
System.Windows.Media;

using
System.Windows.Media.Imaging;

using
System.Windows.Navigation;

using
System.Windows.Shapes;

//外加命名空间

using
System.Diagnostics;

using
System.Runtime.InteropServices;

 

namespace Mgen.TEX

{

publicpartialclassMainWindow
: Window

{

public MainWindow()

{

InitializeComponent();

}

 

//Windows消息值

constuint
WM_CLOSE =0x10;

constuint
WM_DESTROY =0x02;

constuint
WM_QUIT =0x12;

 

//SendMessage和PostMessage的P/Invoke

[DllImport(“user32.dll”, CharSet =CharSet.Auto)]

staticexternIntPtr
SendMessage(IntPtr hWnd, uint Msg,
IntPtr wParam, IntPtr
lParam);

 

[return:
MarshalAs(UnmanagedType.Bool)]

[DllImport(“user32.dll”, SetLastError =true)]

staticexternbool
PostMessage(IntPtr hWnd, uint Msg,
IntPtr wParam, IntPtr
lParam);

 

//窗体的Closing事件,剖断Closing是不是被周转

privatevoid
Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)

{

MessageBox.Show(“Closing事件!”);

}

 

//发送三种信息

privatevoid
WM_CLOSE_Click(object sender, RoutedEventArgs e)

{

//也能够用PostMessage

SendMessage(Process.GetCurrentProcess().MainWindowHandle, WM_CLOSE, IntPtr.Zero,
IntPtr.Zero);

}

 

privatevoid
WM_DESTROY_Click(object
sender, RoutedEventArgs e)

{

//也足以用PostMessage

SendMessage(Process.GetCurrentProcess().MainWindowHandle, WM_DESTROY, IntPtr.Zero,
IntPtr.Zero);

}

 

privatevoid
WM_QUIT_Click(object sender, RoutedEventArgs e)

{

//只好选取PostMessage去将WM_QUIT送至信息队列后面部分

PostMessage(Process.GetCurrentProcess().MainWindowHandle, WM_QUIT, IntPtr.Zero,
IntPtr.Zero);

}

 

}

}

为了便于,写了个批管理,将该批管理和ntsd放在一块儿,使用时实行批管理,采用相应的办法,并输入参数就能够。

  强行终止前段时间进度有四个措施。(呵呵,这里便是终结进程了)

@ECHO OFF
TITLE 结束使用普通方法无法结束的进程
COLOR 0A
MODE con: COLS=62 LINES=22

:MENU
set tm1=%time:~0,2%
set tm2=%time:~3,2%
set tm3=%time:~6,2%
ECHO.  %date% %tm1%点%tm2%分%tm3%秒 
ECHO.   ========================================
ECHO.   请选择要进行的操作,然后按回车
ECHO.   ────────────────────
ECHO.  1    根据进程号PID结束进程
ECHO.  2    根据进程名称结束进程

ECHO.  0    退出
ECHO.
ECHO.请输入选择项目的序号:

set /p choose=
if "%choose%" equ "" goto MENU
if %choose%==1 goto killusingpid
if %choose%==2 goto killusingname
if %choose%==0 goto END

ECHO. 输入错误,请输入正确的项目序号:
goto MENU

:killusingpid
set choose=
ECHO.请输入进程号PID,然后按回车
set /p proid=
set /a i=0
:kpid
ntsd -c q -p %proid%
if %i% GEQ 10 ( ( echo 结束进程%proid%失败 ) & goto MENU )
set /a i=%i%+1
echo 结束进程%proid%第%i%次
tasklist | findstr /i %proid% && ( goto kpid )
echo 结束进程ID为%proid%的程序成功或进程ID:%proid%不存在
GOTO MENU

:killusingname
set choose=
ECHO.请输入进程的名称(比如notepad.exe),然后按回车
set /p proname=
set /a i=0
:kpname
ntsd -c q -pn %proname%
if %i% GEQ 10 ( ( echo 结束程序%proname%失败 ) & goto Menu )
set /a i=%i%+1
echo 结束程序%proname%第%i%次
tasklist | findstr /i %proname% && goto kpname
echo 结束程序%proname%成功或程序:%proname%未启动

GOTO MENU

:END
exit

  1、killProcess(int pid)            
 例子:android.os.Process.killProcess(android.os.Process.myPid());

 

  对于那个主意,要求详细解释一下。在SDK的文书档案中,解释如下:

 

Kill the process with the given PID. Note
that, though this API allows us to request to kill any process based on
its PID, the kernel will still impose standard restrictions on which
PIDs you are actually able to kill. Typically this means only the
process running the caller’s packages/application and any additional
processes created by that app; packages sharing a common UID will also
be able to kill each other’s processes.

 

拉脱维亚语不好,无法标准翻译,所以指望大家自身清楚,免得对大家造成误会。我个人对那句话的诠释正是,那几个主意应用是有标准的:

 

a、将被杀掉的长河 和 当前进程处于同三个包依然应用程序中;

参考:

b、将被杀掉的历程
是由近来应用程序所开创的附加进程;

c、将被杀掉的经过 和 当前进程分享了普通客户的UID。(这里的普通客户,是相对于Root权限的客商来说的)

 

  2、System.exit(int code)            
例子:System.exit(0);

  该措施只可以用于截止近期经过本身,个人感觉在前后相继碰到特别,不能日常实施时,能够通过那么些方法强制退出。

  要求小心的是,那三个格局,会形成进度非寻常退出,正是说,进度退出时不会去实践onPause、onStop和onDestroy方法,那么进度很有非常的大希望错过了保留数据的火候。因而,那五个点子最棒使用在出现格外的时候!

三、甘休另三个经过

  要经过叁个进度去停止另贰个经过。在事先的SDK版本中,平昔使用方法restartPackage(packageName)方法,但是在Android的开支文书档案中介绍说,这些函数会招致某个难点( the
previous behavior here is no longer available to applications because it
allows them to break other applications by removing their alarms,
stopping their services, etc.
),所以建议大家利用一个新的艺术: 

  void killBackgroundProcesses)(String packageName)

  由于那一个措施没有重回值,所以我们也不晓得大家的靶子经过是还是不是确实退出了。但是,笔者当下只发掘了这么些能够了结另二个进程的主意。

四、退出到主屏幕(记得是对当前过程的拍卖)

  那一个法子,也是脱离当前经过的二个主意。假如大家在经过中成立了众多的Activity,但是又不想关闭时去退出不在职分栈顶的Activity,那么就足以一贯动用那几个艺术了。那几个艺术是透过查阅互连网资料看到的。在此先感谢追梦人
了(他的博客地址:,招待大家去探视她的博客)。

作用:当按下再次来到键时,就再次回到到主显示器,并蕴涵参数FLAG_ACTIVITY_CLEAR_TOP,会清理掉当前的位移。

 1     @Override
 2     public boolean onKeyDown(int keyCode, KeyEvent event) {
 3         if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { // 按下的如果是BACK,同时没有重复  
 4                 Intent home = new Intent(Intent.ACTION_MAIN);  
 5                home.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  
 6                home.addCategory(Intent.CATEGORY_HOME);  
 7                startActivity(home);  
 8         }
 9         return super.onKeyDown(keyCode, event);  
10     }

  此格局真的截至了现阶段历程,可是透过Android平台的App
Manager工具去查看的话,使用2.3.3的模拟器,会开掘刚刚被终结的过程会以Cached
background
Process的形式存在,而且模拟器给出了然释,说是为了下三次更迅捷的开发银行那么些进程。

===============================优雅的分界线===============================

【注解】本文系本身原创,转载请评释小说出处:  
博客园

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图